From 25bc37cef9ac13b0fc8b51bd4a285ac1f54cbc1f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 14 Nov 2011 22:29:40 -0800 Subject: [PATCH] refactor all unix types --- src/lib/ctypes.rs | 21 +++++--- src/lib/generic_os.rs | 2 +- src/lib/io.rs | 34 +++++++----- src/lib/linux_os.rs | 102 ++++++++++++++++++++---------------- src/lib/macos_os.rs | 112 +++++++++++++++++++++++----------------- src/lib/run_program.rs | 43 +++++++-------- src/test/stdtest/run.rs | 14 ++--- 7 files changed, 191 insertions(+), 137 deletions(-) diff --git a/src/lib/ctypes.rs b/src/lib/ctypes.rs index 0c862f677105..c48a2c8c073b 100644 --- a/src/lib/ctypes.rs +++ b/src/lib/ctypes.rs @@ -4,11 +4,18 @@ Module: ctypes Definitions useful for C interop */ -/* Type: size_t */ -type size_t = uint; -/* Type: ssize_t */ -type ssize_t = int; -/* Type: uint32_t */ -type uint32_t = u32; -/* Type: uintptr_t */ +type c_int = i32; +type long = int; +type unsigned = u32; +type ulong = uint; + +type intptr_t = uint; type uintptr_t = uint; +type uint32_t = u32; + +type size_t = uint; +type ssize_t = int; +type off_t = uint; + +type fd_t = i32; // not actually a C type, but should be. +type pid_t = i32; diff --git a/src/lib/generic_os.rs b/src/lib/generic_os.rs index 09b23694e2fc..9ce889761de5 100644 --- a/src/lib/generic_os.rs +++ b/src/lib/generic_os.rs @@ -48,7 +48,7 @@ fn setenv(n: str, v: str) { let _: () = str::as_buf(v, {|vbuf| - os::libc::setenv(nbuf, vbuf, 1); + os::libc::setenv(nbuf, vbuf, 1i32); }); }); } diff --git a/src/lib/io.rs b/src/lib/io.rs index e3ff7ee09955..5cb8e2231a55 100644 --- a/src/lib/io.rs +++ b/src/lib/io.rs @@ -1,3 +1,5 @@ +import ctypes::fd_t; +import ctypes::c_int; #[abi = "cdecl"] native mod rustrt { @@ -6,7 +8,6 @@ native mod rustrt { fn rust_get_stderr() -> os::libc::FILE; } - // Reading // FIXME This is all buffered. We might need an unbuffered variant as well @@ -49,8 +50,12 @@ type reader = fn tell() -> uint; }; -fn convert_whence(whence: seek_style) -> int { - ret alt whence { seek_set. { 0 } seek_cur. { 1 } seek_end. { 2 } }; +fn convert_whence(whence: seek_style) -> i32 { + ret alt whence { + seek_set. { 0i32 } + seek_cur. { 1i32 } + seek_end. { 2i32 } + }; } resource FILE_res(f: os::libc::FILE) { os::libc::fclose(f); } @@ -64,11 +69,11 @@ obj FILE_buf_reader(f: os::libc::FILE, res: option::t<@FILE_res>) { vec::unsafe::set_len::(buf, read); ret buf; } - fn read_byte() -> int { ret os::libc::fgetc(f); } - fn unread_byte(byte: int) { os::libc::ungetc(byte, f); } - fn eof() -> bool { ret os::libc::feof(f) != 0; } + fn read_byte() -> int { ret os::libc::fgetc(f) as int; } + fn unread_byte(byte: int) { os::libc::ungetc(byte as i32, f); } + fn eof() -> bool { ret os::libc::feof(f) != 0i32; } fn seek(offset: int, whence: seek_style) { - assert (os::libc::fseek(f, offset, convert_whence(whence)) == 0); + assert (os::libc::fseek(f, offset, convert_whence(whence)) == 0i32); } fn tell() -> uint { ret os::libc::ftell(f) as uint; } } @@ -247,14 +252,14 @@ obj FILE_writer(f: os::libc::FILE, res: option::t<@FILE_res>) { if nout < 1u { log_err "error dumping buffer"; } } fn seek(offset: int, whence: seek_style) { - assert (os::libc::fseek(f, offset, convert_whence(whence)) == 0); + assert (os::libc::fseek(f, offset, convert_whence(whence)) == 0i32); } fn tell() -> uint { ret os::libc::ftell(f) as uint; } } -resource fd_res(fd: int) { os::libc::close(fd); } +resource fd_res(fd: fd_t) { os::libc::close(fd); } -obj fd_buf_writer(fd: int, res: option::t<@fd_res>) { +obj fd_buf_writer(fd: fd_t, res: option::t<@fd_res>) { fn write(v: [u8]) unsafe { let len = vec::len::(v); let count = 0u; @@ -282,7 +287,7 @@ obj fd_buf_writer(fd: int, res: option::t<@fd_res>) { fn file_buf_writer(path: str, flags: [fileflag]) -> result::t { - let fflags: int = + let fflags: i32 = os::libc_constants::O_WRONLY | os::libc_constants::O_BINARY; for f: fileflag in flags { alt f { @@ -299,7 +304,7 @@ fn file_buf_writer(path: str, os::libc_constants::S_IRUSR | os::libc_constants::S_IWUSR) }); - ret if fd < 0 { + ret if fd < 0i32 { log_err sys::last_os_error(); result::err("error opening " + path) } else { @@ -385,9 +390,14 @@ fn buffered_file_buf_writer(path: str) -> result::t { // FIXME it would be great if this could be a const +<<<<<<< HEAD // Problem seems to be that new_writer is not pure fn stdout() -> writer { ret new_writer(fd_buf_writer(1, option::none)); } fn stderr() -> writer { ret new_writer(fd_buf_writer(2, option::none)); } +======= +fn stdout() -> writer { ret new_writer(fd_buf_writer(1i32, option::none)); } +fn stderr() -> writer { ret new_writer(fd_buf_writer(2i32, option::none)); } +>>>>>>> refactor all unix types fn print(s: str) { stdout().write_str(s); } fn println(s: str) { stdout().write_str(s + "\n"); } diff --git a/src/lib/linux_os.rs b/src/lib/linux_os.rs index c8c4aeed84d2..418a6fd0ad20 100644 --- a/src/lib/linux_os.rs +++ b/src/lib/linux_os.rs @@ -4,72 +4,80 @@ Module: os TODO: Restructure and document */ +import ctypes::*; + +export libc; +export libc_constants; +export pipe; +export fd_FILE; +export close; +export fclose; +export waitpid; +export getcwd; +export exec_suffix; +export target_os; +export dylib_filename; +export get_exe_path; + // FIXME Somehow merge stuff duplicated here and macosx_os.rs. Made difficult // by https://github.com/graydon/rust/issues#issue/268 + #[link_name = ""] #[abi = "cdecl"] native mod libc { - fn read(fd: int, buf: *u8, count: uint) -> int; - fn write(fd: int, buf: *u8, count: uint) -> int; - fn fread(buf: *u8, size: uint, n: uint, f: libc::FILE) -> uint; - fn fwrite(buf: *u8, size: uint, n: uint, f: libc::FILE) -> uint; - fn open(s: str::sbuf, flags: int, mode: uint) -> int; - fn close(fd: int) -> int; + fn read(fd: fd_t, buf: *u8, count: size_t) -> ssize_t; + fn write(fd: fd_t, buf: *u8, count: size_t) -> ssize_t; + fn fread(buf: *u8, size: size_t, n: size_t, f: libc::FILE) -> size_t; + fn fwrite(buf: *u8, size: size_t, n: size_t, f: libc::FILE) -> size_t; + fn open(s: str::sbuf, flags: c_int, mode: unsigned) -> fd_t; + fn close(fd: fd_t) -> int; type FILE; fn fopen(path: str::sbuf, mode: str::sbuf) -> FILE; - fn fdopen(fd: int, mode: str::sbuf) -> FILE; + fn fdopen(fd: fd_t, mode: str::sbuf) -> FILE; fn fclose(f: FILE); - fn fgetc(f: FILE) -> int; - fn ungetc(c: int, f: FILE); - fn feof(f: FILE) -> int; - fn fseek(f: FILE, offset: int, whence: int) -> int; - fn ftell(f: FILE) -> int; + fn fgetc(f: FILE) -> c_int; + fn ungetc(c: c_int, f: FILE); + fn feof(f: FILE) -> c_int; + fn fseek(f: FILE, offset: long, whence: c_int) -> c_int; + fn ftell(f: FILE) -> long; type dir; fn opendir(d: str::sbuf) -> dir; - fn closedir(d: dir) -> int; + fn closedir(d: dir) -> c_int; type dirent; fn readdir(d: dir) -> dirent; fn getenv(n: str::sbuf) -> str::sbuf; - fn setenv(n: str::sbuf, v: str::sbuf, overwrite: int) -> int; - fn unsetenv(n: str::sbuf) -> int; - fn pipe(buf: *mutable int) -> int; - fn waitpid(pid: int, &status: int, options: int) -> int; - fn readlink(path: str::sbuf, buf: str::sbuf, - bufsize: ctypes::size_t) -> ctypes::ssize_t; + fn setenv(n: str::sbuf, v: str::sbuf, overwrite: c_int) -> c_int; + fn unsetenv(n: str::sbuf) -> c_int; + fn pipe(buf: *mutable fd_t) -> c_int; + fn waitpid(pid: pid_t, &status: c_int, options: c_int) -> pid_t; } mod libc_constants { - const O_RDONLY: int = 0; - const O_WRONLY: int = 1; - const O_RDWR: int = 2; - const O_APPEND: int = 1024; - const O_CREAT: int = 64; - const O_EXCL: int = 128; - const O_TRUNC: int = 512; - const O_TEXT: int = 0; // nonexistent in linux libc - const O_BINARY: int = 0; // nonexistent in linux libc + const O_RDONLY: c_int = 0; + const O_WRONLY: c_int = 1; + const O_RDWR: c_int = 2; + const O_APPEND: c_int = 1024; + const O_CREAT: c_int = 64; + const O_EXCL: c_int = 128; + const O_TRUNC: c_int = 512; + const O_TEXT: c_int = 0; // nonexistent in linux libc + const O_BINARY: c_int = 0; // nonexistent in linux libc - const S_IRUSR: uint = 256u; - const S_IWUSR: uint = 128u; + const S_IRUSR: unsigned = 256u; + const S_IWUSR: unsigned = 128u; } -// FIXME turn into constants -fn exec_suffix() -> str { ret ""; } -fn target_os() -> str { ret "linux"; } - -fn dylib_filename(base: str) -> str { ret "lib" + base + ".so"; } - -fn pipe() -> {in: int, out: int} { - let fds = {mutable in: 0, mutable out: 0}; - assert (os::libc::pipe(ptr::mut_addr_of(fds.in)) == 0); +fn pipe() -> {in: fd_t, out: fd_t} { + let fds = {mutable in: 0i32, mutable out: 0i32}; + assert (os::libc::pipe(ptr::mut_addr_of(fds.in)) == 0i32); ret {in: fds.in, out: fds.out}; } -fn fd_FILE(fd: int) -> libc::FILE { +fn fd_FILE(fd: fd_t) -> libc::FILE { ret str::as_buf("r", {|modebuf| libc::fdopen(fd, modebuf) }); } -fn close(fd: int) -> int { +fn close(fd: fd_t) -> int { libc::close(fd) } @@ -77,9 +85,9 @@ fn fclose(file: libc::FILE) { libc::fclose(file) } -fn waitpid(pid: int) -> int { - let status = 0; - assert (os::libc::waitpid(pid, status, 0) != -1); +fn waitpid(pid: pid_t) -> i32 { + let status = 0i32; + assert (os::libc::waitpid(pid, status, 0i32) != -1i32); ret status; } @@ -90,6 +98,12 @@ native mod rustrt { fn getcwd() -> str { ret rustrt::rust_getcwd(); } +fn exec_suffix() -> str { ret ""; } + +fn target_os() -> str { ret "linux"; } + +fn dylib_filename(base: str) -> str { ret "lib" + base + ".so"; } + /// Returns the directory containing the running program /// followed by a path separator fn get_exe_path() -> option::t { diff --git a/src/lib/macos_os.rs b/src/lib/macos_os.rs index efc158d4d5e8..0036af6c7a0c 100644 --- a/src/lib/macos_os.rs +++ b/src/lib/macos_os.rs @@ -1,68 +1,77 @@ +import ctypes::*; + +export libc; +export libc_constants; +export pipe; +export fd_FILE; +export close; +export fclose; +export waitpid; +export getcwd; +export exec_suffix; +export target_os; +export dylib_filename; +export get_exe_path; + +// FIXME Refactor into unix_os module or some such. Doesn't +// seem to work right now. #[link_name = ""] #[abi = "cdecl"] native mod libc { - fn read(fd: int, buf: *u8, count: uint) -> int; - fn write(fd: int, buf: *u8, count: uint) -> int; - fn fread(buf: *u8, size: uint, n: uint, f: libc::FILE) -> uint; - fn fwrite(buf: *u8, size: uint, n: uint, f: libc::FILE) -> uint; - fn open(s: str::sbuf, flags: int, mode: uint) -> int; - fn close(fd: int) -> int; + fn read(fd: fd_t, buf: *u8, count: size_t) -> ssize_t; + fn write(fd: fd_t, buf: *u8, count: size_t) -> ssize_t; + fn fread(buf: *u8, size: size_t, n: size_t, f: libc::FILE) -> size_t; + fn fwrite(buf: *u8, size: size_t, n: size_t, f: libc::FILE) -> size_t; + fn open(s: str::sbuf, flags: c_int, mode: unsigned) -> fd_t; + fn close(fd: fd_t) -> int; type FILE; fn fopen(path: str::sbuf, mode: str::sbuf) -> FILE; - fn fdopen(fd: int, mode: str::sbuf) -> FILE; + fn fdopen(fd: fd_t, mode: str::sbuf) -> FILE; fn fclose(f: FILE); - fn fgetc(f: FILE) -> int; - fn ungetc(c: int, f: FILE); - fn feof(f: FILE) -> int; - fn fseek(f: FILE, offset: int, whence: int) -> int; - fn ftell(f: FILE) -> int; + fn fgetc(f: FILE) -> c_int; + fn ungetc(c: c_int, f: FILE); + fn feof(f: FILE) -> c_int; + fn fseek(f: FILE, offset: long, whence: c_int) -> c_int; + fn ftell(f: FILE) -> long; type dir; fn opendir(d: str::sbuf) -> dir; - fn closedir(d: dir) -> int; + fn closedir(d: dir) -> c_int; type dirent; fn readdir(d: dir) -> dirent; fn getenv(n: str::sbuf) -> str::sbuf; - fn setenv(n: str::sbuf, v: str::sbuf, overwrite: int) -> int; - fn unsetenv(n: str::sbuf) -> int; - fn pipe(buf: *mutable int) -> int; - fn waitpid(pid: int, &status: int, options: int) -> int; - fn _NSGetExecutablePath(buf: str::sbuf, - bufsize: *mutable ctypes::uint32_t) -> int; + fn setenv(n: str::sbuf, v: str::sbuf, overwrite: c_int) -> c_int; + fn unsetenv(n: str::sbuf) -> c_int; + fn pipe(buf: *mutable fd_t) -> c_int; + fn waitpid(pid: pid_t, &status: c_int, options: c_int) -> pid_t; } mod libc_constants { - const O_RDONLY: int = 0; - const O_WRONLY: int = 1; - const O_RDWR: int = 2; - const O_APPEND: int = 8; - const O_CREAT: int = 512; - const O_EXCL: int = 2048; - const O_TRUNC: int = 1024; - const O_TEXT: int = 0; // nonexistent in darwin libc - const O_BINARY: int = 0; // nonexistent in darwin libc + const O_RDONLY: int = 0i32; + const O_WRONLY: int = 1i32; + const O_RDWR: int = 2i32; + const O_APPEND: int = 8i32; + const O_CREAT: int = 512i32; + const O_EXCL: int = 2048i32; + const O_TRUNC: int = 1024i32; + const O_TEXT: int = 0i32; // nonexistent in darwin libc + const O_BINARY: int = 0i32; // nonexistent in darwin libc - const S_IRUSR: uint = 256u; - const S_IWUSR: uint = 128u; + const S_IRUSR: uint = 256u32; + const S_IWUSR: uint = 128u32; } -// FIXME turn into constants -fn exec_suffix() -> str { ret ""; } -fn target_os() -> str { ret "macos"; } - -fn dylib_filename(base: str) -> str { ret "lib" + base + ".dylib"; } - -fn pipe() -> {in: int, out: int} { - let fds = {mutable in: 0, mutable out: 0}; - assert (os::libc::pipe(ptr::mut_addr_of(fds.in)) == 0); +fn pipe() -> {in: fd_t, out: fd_t} { + let fds = {mutable in: 0i32, mutable out: 0i32}; + assert (os::libc::pipe(ptr::mut_addr_of(fds.in)) == 0i32); ret {in: fds.in, out: fds.out}; } -fn fd_FILE(fd: int) -> libc::FILE { +fn fd_FILE(fd: fd_t) -> libc::FILE { ret str::as_buf("r", {|modebuf| libc::fdopen(fd, modebuf) }); } -fn close(fd: int) -> int { +fn close(fd: fd_t) -> int { libc::close(fd) } @@ -70,9 +79,9 @@ fn fclose(file: libc::FILE) { libc::fclose(file) } -fn waitpid(pid: int) -> int { - let status = 0; - assert (os::libc::waitpid(pid, status, 0) != -1); +fn waitpid(pid: pid_t) -> i32 { + let status = 0i32; + assert (os::libc::waitpid(pid, status, 0i32) != -1i32); ret status; } @@ -83,13 +92,24 @@ native mod rustrt { fn getcwd() -> str { ret rustrt::rust_getcwd(); } +native "cdecl" mod mac_libc = "" { + fn _NSGetExecutablePath(buf: str::sbuf, + bufsize: *mutable uint32_t) -> c_int; +} + +fn exec_suffix() -> str { ret ""; } + +fn target_os() -> str { ret "macos"; } + +fn dylib_filename(base: str) -> str { ret "lib" + base + ".dylib"; } + fn get_exe_path() -> option::t { // FIXME: This doesn't handle the case where the buffer is too small let bufsize = 1023u32; let path = str::unsafe_from_bytes(vec::init_elt(0u8, bufsize as uint)); ret str::as_buf(path, { |path_buf| - if libc::_NSGetExecutablePath(path_buf, - ptr::mut_addr_of(bufsize)) == 0 { + if mac_libc::_NSGetExecutablePath(path_buf, + ptr::mut_addr_of(bufsize)) == 0i32 { option::some(fs::dirname(path) + fs::path_sep()) } else { option::none diff --git a/src/lib/run_program.rs b/src/lib/run_program.rs index 915e6c0f3253..ea24bc6dee87 100644 --- a/src/lib/run_program.rs +++ b/src/lib/run_program.rs @@ -4,6 +4,7 @@ Module: run Process spawning */ import str::sbuf; +import ctypes::{fd_t, pid_t}; export program; export run_program; @@ -14,8 +15,8 @@ export waitpid; #[abi = "cdecl"] native mod rustrt { - fn rust_run_program(argv: *sbuf, in_fd: int, out_fd: int, err_fd: int) -> - int; + fn rust_run_program(argv: *sbuf, in_fd: fd_t, out_fd: fd_t, err_fd: fd_t) -> + pid_t; } /* Section: Types */ @@ -41,7 +42,7 @@ type program = obj { Returns the process id of the program */ - fn get_id() -> int; + fn get_id() -> pid_t; /* Method: input @@ -114,8 +115,8 @@ Returns: The process id of the spawned process */ -fn spawn_process(prog: str, args: [str], in_fd: int, out_fd: int, err_fd: int) - -> int unsafe { +fn spawn_process(prog: str, args: [str], in_fd: fd_t, out_fd: fd_t, err_fd: fd_t) + -> pid_t unsafe { // Note: we have to hold on to these vector references while we hold a // pointer to their buffers let prog = prog; @@ -142,7 +143,7 @@ Returns: The process id */ fn run_program(prog: str, args: [str]) -> int { - ret waitpid(spawn_process(prog, args, 0, 0, 0)); + ret waitpid(spawn_process(prog, args, 0i32, 0i32, 0i32)); } /* @@ -171,16 +172,16 @@ fn start_program(prog: str, args: [str]) -> @program_res { spawn_process(prog, args, pipe_input.in, pipe_output.out, pipe_err.out); - if pid == -1 { fail; } + if pid == -1i32 { fail; } os::libc::close(pipe_input.in); os::libc::close(pipe_output.out); os::libc::close(pipe_err.out); - obj new_program(pid: int, - mutable in_fd: int, + obj new_program(pid: pid_t, + mutable in_fd: fd_t, out_file: os::libc::FILE, err_file: os::libc::FILE, mutable finished: bool) { - fn get_id() -> int { ret pid; } + fn get_id() -> pid_t { ret pid; } fn input() -> io::writer { ret io::new_writer(io::fd_buf_writer(in_fd, option::none)); } @@ -191,7 +192,7 @@ fn start_program(prog: str, args: [str]) -> @program_res { ret io::new_reader(io::FILE_buf_reader(err_file, option::none)); } fn close_input() { - let invalid_fd = -1; + let invalid_fd = -1i32; if in_fd != invalid_fd { os::libc::close(in_fd); in_fd = invalid_fd; @@ -253,7 +254,7 @@ Function: waitpid Waits for a process to exit and returns the exit code */ -fn waitpid(pid: int) -> int { +fn waitpid(pid: pid_t) -> int { ret waitpid_os(pid); #[cfg(target_os = "win32")] @@ -263,30 +264,30 @@ fn waitpid(pid: int) -> int { #[cfg(target_os = "linux")] #[cfg(target_os = "macos")] - fn waitpid_os(pid: int) -> int { + fn waitpid_os(pid: pid_t) -> int { #[cfg(target_os = "linux")] - fn WIFEXITED(status: int) -> bool { - (status & 0xff) == 0 + fn WIFEXITED(status: i32) -> bool { + (status & 0xffi32) == 0i32 } #[cfg(target_os = "macos")] - fn WIFEXITED(status: int) -> bool { - (status & 0x7f) == 0 + fn WIFEXITED(status: i32) -> bool { + (status & 0x7fi32) == 0i32 } #[cfg(target_os = "linux")] - fn WEXITSTATUS(status: int) -> int { + fn WEXITSTATUS(status: i32) -> i32 { (status >> 8) & 0xff } #[cfg(target_os = "macos")] - fn WEXITSTATUS(status: int) -> int { - status >> 8 + fn WEXITSTATUS(status: i32) -> i32 { + status >> 8i32 } let status = os::waitpid(pid); ret if WIFEXITED(status) { - WEXITSTATUS(status) + WEXITSTATUS(status) as int } else { 1 }; diff --git a/src/test/stdtest/run.rs b/src/test/stdtest/run.rs index fca410020005..7b8248833b15 100644 --- a/src/test/stdtest/run.rs +++ b/src/test/stdtest/run.rs @@ -4,6 +4,7 @@ import std::os; import std::io; import std::option; import std::str; +import std::ctypes::fd_t; // Regression test for memory leaks #[ignore(cfg(target_os = "win32"))] // FIXME @@ -14,7 +15,7 @@ fn test_leaks() { } #[test] -fn test_pipes() unsafe { +fn test_pipes() { let pipe_in = os::pipe(); let pipe_out = os::pipe(); let pipe_err = os::pipe(); @@ -25,7 +26,7 @@ fn test_pipes() unsafe { os::close(pipe_out.out); os::close(pipe_err.out); - if pid == -1 { fail; } + if pid == -1i32 { fail; } let expected = "test"; writeclose(pipe_in.out, expected); let actual = readclose(pipe_out.in); @@ -36,14 +37,15 @@ fn test_pipes() unsafe { log actual; assert (expected == actual); - fn writeclose(fd: int, s: str) unsafe { + fn writeclose(fd: fd_t, s: str) { + log_err("writeclose", (fd, s)); let writer = io::new_writer(io::fd_buf_writer(fd, option::none)); writer.write_str(s); os::close(fd); } - fn readclose(fd: int) -> str unsafe { + fn readclose(fd: fd_t) -> str { // Copied from run::program_output let file = os::fd_FILE(fd); let reader = io::new_reader(io::FILE_buf_reader(file, option::none)); @@ -58,8 +60,8 @@ fn test_pipes() unsafe { } #[test] -fn waitpid() unsafe { - let pid = run::spawn_process("false", [], 0, 0, 0); +fn waitpid() { + let pid = run::spawn_process("false", [], 0i32, 0i32, 0i32); let status = run::waitpid(pid); assert status == 1; }