Skip to content

Commit 301dd7a

Browse files
committed
fix fallout from std::libc separation
1 parent 8ddd5f5 commit 301dd7a

File tree

114 files changed

+364
-224
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+364
-224
lines changed

mk/crates.mk

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,14 @@
4949
# automatically generated for all stage/host/target combinations.
5050
################################################################################
5151

52-
TARGET_CRATES := std green rustuv native flate arena glob term semver \
52+
TARGET_CRATES := libc std green rustuv native flate arena glob term semver \
5353
uuid serialize sync getopts collections num test time rand \
5454
workcache url log
5555
HOST_CRATES := syntax rustc rustdoc fourcc hexfloat
5656
CRATES := $(TARGET_CRATES) $(HOST_CRATES)
5757
TOOLS := compiletest rustdoc rustc
5858

59-
DEPS_std := native:rustrt native:compiler-rt native:backtrace
59+
DEPS_std := libc native:rustrt native:compiler-rt native:backtrace
6060
DEPS_green := std rand native:context_switch
6161
DEPS_rustuv := std native:uv native:uv_support
6262
DEPS_native := std

src/doc/guide-ffi.md

Lines changed: 93 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ The following is a minimal example of calling a foreign function which will
1212
compile if snappy is installed:
1313

1414
~~~~ {.ignore}
15-
use std::libc::size_t;
15+
extern crate libc;
16+
use libc::size_t;
1617
1718
#[link(name = "snappy")]
1819
extern {
@@ -44,7 +45,8 @@ keeping the binding correct at runtime.
4445
The `extern` block can be extended to cover the entire snappy API:
4546

4647
~~~~ {.ignore}
47-
use std::libc::{c_int, size_t};
48+
extern crate libc;
49+
use libc::{c_int, size_t};
4850
4951
#[link(name = "snappy")]
5052
extern {
@@ -170,6 +172,88 @@ Foreign libraries often hand off ownership of resources to the calling code.
170172
When this occurs, we must use Rust's destructors to provide safety and guarantee
171173
the release of these resources (especially in the case of failure).
172174

175+
As an example, we give a reimplementation of owned boxes by wrapping `malloc`
176+
and `free`:
177+
178+
~~~~
179+
extern crate libc;
180+
181+
use std::cast;
182+
use libc::{c_void, size_t, malloc, free};
183+
use std::mem;
184+
use std::ptr;
185+
186+
// Define a wrapper around the handle returned by the foreign code.
187+
// Unique<T> has the same semantics as ~T
188+
pub struct Unique<T> {
189+
// It contains a single raw, mutable pointer to the object in question.
190+
priv ptr: *mut T
191+
}
192+
193+
// Implement methods for creating and using the values in the box.
194+
// NB: For simplicity and correctness, we require that T has kind Send
195+
// (owned boxes relax this restriction, and can contain managed (GC) boxes).
196+
// This is because, as implemented, the garbage collector would not know
197+
// about any shared boxes stored in the malloc'd region of memory.
198+
impl<T: Send> Unique<T> {
199+
pub fn new(value: T) -> Unique<T> {
200+
unsafe {
201+
let ptr = malloc(std::mem::size_of::<T>() as size_t) as *mut T;
202+
assert!(!ptr.is_null());
203+
// `*ptr` is uninitialized, and `*ptr = value` would attempt to destroy it
204+
// move_val_init moves a value into this memory without
205+
// attempting to drop the original value.
206+
mem::move_val_init(&mut *ptr, value);
207+
Unique{ptr: ptr}
208+
}
209+
}
210+
211+
// the 'r lifetime results in the same semantics as `&*x` with ~T
212+
pub fn borrow<'r>(&'r self) -> &'r T {
213+
unsafe { cast::copy_lifetime(self, &*self.ptr) }
214+
}
215+
216+
// the 'r lifetime results in the same semantics as `&mut *x` with ~T
217+
pub fn borrow_mut<'r>(&'r mut self) -> &'r mut T {
218+
unsafe { cast::copy_mut_lifetime(self, &mut *self.ptr) }
219+
}
220+
}
221+
222+
// The key ingredient for safety, we associate a destructor with
223+
// Unique<T>, making the struct manage the raw pointer: when the
224+
// struct goes out of scope, it will automatically free the raw pointer.
225+
// NB: This is an unsafe destructor, because rustc will not normally
226+
// allow destructors to be associated with parametrized types, due to
227+
// bad interaction with managed boxes. (With the Send restriction,
228+
// we don't have this problem.)
229+
#[unsafe_destructor]
230+
impl<T: Send> Drop for Unique<T> {
231+
fn drop(&mut self) {
232+
unsafe {
233+
let x = mem::uninit(); // dummy value to swap in
234+
// We need to move the object out of the box, so that
235+
// the destructor is called (at the end of this scope.)
236+
ptr::replace(self.ptr, x);
237+
free(self.ptr as *mut c_void)
238+
}
239+
}
240+
}
241+
242+
// A comparison between the built-in ~ and this reimplementation
243+
fn main() {
244+
{
245+
let mut x = ~5;
246+
*x = 10;
247+
} // `x` is freed here
248+
249+
{
250+
let mut y = Unique::new(5);
251+
*y.borrow_mut() = 10;
252+
} // `y` is freed here
253+
}
254+
~~~~
255+
256+
>>>>>>> 854a01b... fix fallout from std::libc separation
173257
# Callbacks from C code to Rust functions
174258

175259
Some external libraries require the usage of callbacks to report back their
@@ -402,7 +486,7 @@ global state. In order to access these variables, you declare them in `extern`
402486
blocks with the `static` keyword:
403487

404488
~~~{.ignore}
405-
use std::libc;
489+
extern crate libc;
406490
407491
#[link(name = "readline")]
408492
extern {
@@ -420,7 +504,7 @@ interface. To do this, statics can be declared with `mut` so rust can mutate
420504
them.
421505

422506
~~~{.ignore}
423-
use std::libc;
507+
extern crate libc;
424508
use std::ptr;
425509
426510
#[link(name = "readline")]
@@ -444,11 +528,15 @@ calling foreign functions. Some foreign functions, most notably the Windows API,
444528
conventions. Rust provides a way to tell the compiler which convention to use:
445529

446530
~~~~
531+
extern crate libc;
532+
447533
#[cfg(target_os = "win32", target_arch = "x86")]
448534
#[link(name = "kernel32")]
449535
extern "stdcall" {
450-
fn SetEnvironmentVariableA(n: *u8, v: *u8) -> std::libc::c_int;
536+
fn SetEnvironmentVariableA(n: *u8, v: *u8) -> libc::c_int;
451537
}
538+
539+
# fn main() { }
452540
~~~~
453541

454542
This applies to the entire `extern` block. The list of supported ABI constraints

src/doc/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ li {list-style-type: none; }
3636
* [The `glob` file path matching library](glob/index.html)
3737
* [The `green` M:N runtime library](green/index.html)
3838
* [The `hexfloat` library for hexadecimal floating-point literals](hexfloat/index.html)
39+
* [The `libc` bindings](libc/index.html)
3940
* [The `native` 1:1 threading runtime](native/index.html)
4041
* [The `num` arbitrary precision numerics library](num/index.html)
4142
* [The `rand` library for random numbers and distributions](rand/index.html)

src/doc/rust.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1471,11 +1471,13 @@ with the exception that they may not have a body
14711471
and are instead terminated by a semicolon.
14721472

14731473
~~~~
1474-
# use std::libc::{c_char, FILE};
1474+
extern crate libc;
1475+
use libc::{c_char, FILE};
14751476
14761477
extern {
14771478
fn fopen(filename: *c_char, mode: *c_char) -> *FILE;
14781479
}
1480+
# fn main() {}
14791481
~~~~
14801482

14811483
Functions within external blocks may be called by Rust code,

src/etc/zsh/_rust

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ _rustc_opts_switches=(
4040
)
4141
_rustc_opts_lint=(
4242
'attribute-usage[detects bad use of attributes]'
43-
'ctypes[proper use of std::libc types in foreign modules]'
43+
'ctypes[proper use of libc types in foreign modules]'
4444
'dead-assignment[detect assignments that will never be read]'
4545
'dead-code[detect piece of code that will never be used]'
4646
'default-type-param-usage[prevents explicitly setting a type parameter with a default]'

src/libflate/lib.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,14 @@ Simple compression
2626

2727
#[cfg(test)] #[phase(syntax, link)] extern crate log;
2828

29-
use std::libc::{c_void, size_t, c_int};
30-
use std::libc;
29+
extern crate libc;
30+
3131
use std::c_vec::CVec;
32+
use libc::{c_void, size_t, c_int};
3233

33-
pub mod rustrt {
34-
use std::libc::{c_int, c_void, size_t};
3534

35+
pub mod rustrt {
36+
use libc::{c_void, size_t, c_int};
3637
#[link(name = "miniz", kind = "static")]
3738
extern {
3839
pub fn tdefl_compress_mem_to_heap(psrc_buf: *c_void,

src/libgreen/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@
199199
#[cfg(test)] #[phase(syntax, link)] extern crate log;
200200
#[cfg(test)] extern crate rustuv;
201201
extern crate rand;
202+
extern crate libc;
202203

203204
use std::mem::replace;
204205
use std::os;

src/libgreen/macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ macro_rules! rtabort (
5252

5353
pub fn dumb_println(args: &fmt::Arguments) {
5454
use std::io;
55-
use std::libc;
55+
use libc;
5656

5757
struct Stderr;
5858
impl io::Writer for Stderr {

src/libgreen/sched.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,7 @@ fn new_sched_rng() -> XorShiftRng {
970970
}
971971
#[cfg(unix)]
972972
fn new_sched_rng() -> XorShiftRng {
973-
use std::libc;
973+
use libc;
974974
use std::mem;
975975
use rand::SeedableRng;
976976

src/libgreen/stack.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use std::rt::env::max_cached_stacks;
1212
use std::os::{errno, page_size, MemoryMap, MapReadable, MapWritable,
1313
MapNonStandardFlags, MapVirtual};
14-
use std::libc;
14+
use libc;
1515

1616
/// A task's stack. The name "Stack" is a vestige of segmented stacks.
1717
pub struct Stack {

src/liblibc/lib.rs

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,40 @@
1111
#[feature(globs)];
1212
#[crate_id = "libc#0.10-pre"];
1313
#[experimental];
14+
#[no_std]; // we don't need std, and we can't have std, since it doesn't exist
15+
// yet. std depends on us.
16+
#[crate_type = "rlib"];
17+
#[crate_type = "dylib"];
1418

1519
/*!
1620
* Bindings for the C standard library and other platform libraries
1721
*
18-
* This module contains bindings to the C standard library,
19-
* organized into modules by their defining standard.
20-
* Additionally, it contains some assorted platform-specific definitions.
21-
* For convenience, most functions and types are reexported from `libc`,
22-
* so `pub use std::*` will import the available
23-
* C bindings as appropriate for the target platform. The exact
24-
* set of functions available are platform specific.
22+
* **NOTE:** These are *architecture and libc* specific. On Linux, these
23+
* bindings are only correct for glibc.
2524
*
26-
* *Note* Because these definitions are platform-specific, some may not appear in
27-
* the generated documentation.
25+
* This module contains bindings to the C standard library, organized into
26+
* modules by their defining standard. Additionally, it contains some assorted
27+
* platform-specific definitions. For convenience, most functions and types
28+
* are reexported, so `use libc::*` will import the available C bindings as
29+
* appropriate for the target platform. The exact set of functions available
30+
* are platform specific.
2831
*
29-
* We consider the following specs reasonably normative with respect
30-
* to interoperating with the C standard library (libc/msvcrt):
32+
* *Note:* Because these definitions are platform-specific, some may not appear
33+
* in the generated documentation.
34+
*
35+
* We consider the following specs reasonably normative with respect to
36+
* interoperating with the C standard library (libc/msvcrt):
3137
*
3238
* * ISO 9899:1990 ('C95', 'ANSI C', 'Standard C'), NA1, 1995.
3339
* * ISO 9899:1999 ('C99' or 'C9x').
3440
* * ISO 9945:1988 / IEEE 1003.1-1988 ('POSIX.1').
3541
* * ISO 9945:2001 / IEEE 1003.1-2001 ('POSIX:2001', 'SUSv3').
3642
* * ISO 9945:2008 / IEEE 1003.1-2008 ('POSIX:2008', 'SUSv4').
3743
*
38-
* Note that any reference to the 1996 revision of POSIX, or any revs
39-
* between 1990 (when '88 was approved at ISO) and 2001 (when the next
40-
* actual revision-revision happened), are merely additions of other
41-
* chapters (1b and 1c) outside the core interfaces.
44+
* Note that any reference to the 1996 revision of POSIX, or any revs between
45+
* 1990 (when '88 was approved at ISO) and 2001 (when the next actual
46+
* revision-revision happened), are merely additions of other chapters (1b and
47+
* 1c) outside the core interfaces.
4248
*
4349
* Despite having several names each, these are *reasonably* coherent
4450
* point-in-time, list-of-definition sorts of specs. You can get each under a
@@ -55,22 +61,26 @@
5561
* sanity while editing, filling-in-details and eliminating duplication) into
5662
* definitions common-to-all (held in modules named c95, c99, posix88, posix01
5763
* and posix08) and definitions that appear only on *some* platforms (named
58-
* 'extra'). This would be things like significant OSX foundation kit, or
59-
* win32 library kernel32.dll, or various fancy glibc, linux or BSD
60-
* extensions.
64+
* 'extra'). This would be things like significant OSX foundation kit, or win32
65+
* library kernel32.dll, or various fancy glibc, linux or BSD extensions.
6166
*
6267
* In addition to the per-platform 'extra' modules, we define a module of
6368
* 'common BSD' libc routines that never quite made it into POSIX but show up
64-
* in multiple derived systems. This is the 4.4BSD r2 / 1995 release, the
65-
* final one from Berkeley after the lawsuits died down and the CSRG
66-
* dissolved.
69+
* in multiple derived systems. This is the 4.4BSD r2 / 1995 release, the final
70+
* one from Berkeley after the lawsuits died down and the CSRG dissolved.
6771
*/
6872

6973
#[allow(non_camel_case_types)];
7074
#[allow(non_uppercase_statics)];
7175
#[allow(missing_doc)];
7276
#[allow(uppercase_variables)];
7377

78+
#[cfg(test)] extern crate std;
79+
#[cfg(test)] extern crate extra;
80+
// for lang="start"
81+
#[cfg(test)] extern crate green;
82+
#[cfg(test)] extern crate rustuv;
83+
7484
// Initial glob-exports mean that all the contents of all the modules
7585
// wind up exported, if you're interested in writing platform-specific code.
7686

@@ -3862,12 +3872,11 @@ pub mod funcs {
38623872
pub mod glob {
38633873
use types::os::arch::c95::{c_char, c_int};
38643874
use types::os::common::posix01::{glob_t};
3865-
use Nullable;
38663875

38673876
extern {
38683877
pub fn glob(pattern: *c_char,
38693878
flags: c_int,
3870-
errfunc: Nullable<extern "C" fn(epath: *c_char, errno: int) -> int>,
3879+
errfunc: ::Nullable<extern "C" fn(epath: *c_char, errno: int) -> int>,
38713880
pglob: *mut glob_t);
38723881
pub fn globfree(pglob: *mut glob_t);
38733882
}

src/libnative/io/addrinfo.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use ai = std::io::net::addrinfo;
1212
use std::c_str::CString;
1313
use std::cast;
1414
use std::io::IoError;
15-
use std::libc;
16-
use std::libc::{c_char, c_int};
15+
use libc;
16+
use libc::{c_char, c_int};
1717
use std::ptr::{null, mut_null};
1818

1919
use super::net::sockaddr_to_addr;

src/libnative/io/file_unix.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ use std::sync::arc::UnsafeArc;
1414
use std::c_str::CString;
1515
use std::io::IoError;
1616
use std::io;
17-
use std::libc::{c_int, c_void};
18-
use std::libc;
17+
use libc::{c_int, c_void};
18+
use libc;
1919
use std::mem;
2020
use std::rt::rtio;
2121
use std::slice;
@@ -341,8 +341,8 @@ pub fn mkdir(p: &CString, mode: io::FilePermission) -> IoResult<()> {
341341
}
342342

343343
pub fn readdir(p: &CString) -> IoResult<~[Path]> {
344-
use std::libc::{dirent_t};
345-
use std::libc::{opendir, readdir_r, closedir};
344+
use libc::{dirent_t};
345+
use libc::{opendir, readdir_r, closedir};
346346

347347
fn prune(root: &CString, dirs: ~[Path]) -> ~[Path] {
348348
let root = unsafe { CString::new(root.with_ref(|p| p), false) };
@@ -520,7 +520,7 @@ pub fn utime(p: &CString, atime: u64, mtime: u64) -> IoResult<()> {
520520
mod tests {
521521
use super::{CFile, FileDesc};
522522
use std::io;
523-
use std::libc;
523+
use libc;
524524
use std::os;
525525
use std::rt::rtio::RtioFileStream;
526526

0 commit comments

Comments
 (0)