├── .gitignore ├── Cargo.toml ├── README.md ├── examples ├── access.rs ├── changemod.rs ├── fileflags.rs ├── filetype.rs ├── getcputc.rs ├── hello.rs ├── hole.rs ├── ls1.rs ├── mycat.rs ├── pipe1.rs ├── seek.rs ├── setfl.rs ├── shell1.rs ├── shell2.rs ├── testerror.rs ├── uidgid.rs ├── umask.rs └── unlink.rs ├── run_all.sh └── src └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "apue" 3 | version = "0.1.0" 4 | authors = ["Shuyu Wang "] 5 | description = "Code from the APUE book. in Rust." 6 | homepage = "https://github.com/andelf/rust-apue" 7 | repository = "https://github.com/andelf/rust-apue.git" 8 | keywords = [ 9 | "algorithm", 10 | "book" 11 | ] 12 | license = "MIT" 13 | 14 | [dependencies] 15 | libc = "*" 16 | 17 | [dependencies.bindgen_plugin] 18 | git = "https://github.com/crabtw/rust-bindgen.git" 19 | path = "bindgen_plugin" 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rust-apue 2 | 3 | 坑。 4 | 5 | Programs from the APUE Book(Advanced Programming in the UNIX® Environment). 6 | 7 | [Book Site](http://www.apuebook.com/) 8 | 9 | ## Progress 10 | 11 | - [x] Chapter 1: intro 12 | - [x] Chapter 2: no file :() 13 | - [x] Chapter 3: fileio 14 | - [ ] Chapter 4: filedir 15 | - [ ] TODO 16 | 17 | ## List 18 | 19 | ``` 20 | TODO: ... 21 | ``` 22 | 23 | ## How to build 24 | 25 | ``` 26 | export DYLD_LIBRARY_PATH=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/ 27 | cargo run --example ... 28 | ``` 29 | -------------------------------------------------------------------------------- /examples/access.rs: -------------------------------------------------------------------------------- 1 | // List 4-2 2 | #![feature(convert)] 3 | extern crate apue; 4 | 5 | use apue::unistd::*; 6 | use apue::fcntl::*; 7 | use std::ffi::CString; 8 | use std::str; 9 | use std::env; 10 | 11 | use apue::consts::*; 12 | 13 | 14 | fn main() { 15 | let args: Vec = env::args_os().map(|s| s.to_cstring().unwrap()).collect(); 16 | if args.len() != 2 { 17 | panic!("usage: {} ", str::from_utf8(args[0].as_bytes()).unwrap()); 18 | } 19 | unsafe { 20 | if access(args[1].as_ptr(), R_OK) < 0 { 21 | panic!("access error for {}", str::from_utf8(args[1].as_bytes()).unwrap()) 22 | } else { 23 | println!("read access OK"); 24 | } 25 | 26 | if open(args[1].as_ptr(), O_RDONLY, 0) < 0 { 27 | panic!("open error for {}", str::from_utf8(args[1].as_bytes()).unwrap()); 28 | } else { 29 | println!("open for reading OK"); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/changemod.rs: -------------------------------------------------------------------------------- 1 | // List 4-4 2 | extern crate apue; 3 | 4 | use apue::stat::*; 5 | use std::ffi::CString; 6 | use std::mem; 7 | use apue::consts::*; 8 | 9 | fn main() { 10 | unsafe { 11 | let mut statbuf = mem::zeroed(); 12 | 13 | if stat(CString::new("foo").unwrap().as_ptr(), &mut statbuf) < 0 { 14 | panic!("stat error for foo"); 15 | } 16 | 17 | if chmod(CString::new("foo").unwrap().as_ptr(), 18 | statbuf.st_mode & !S_IXGRP) < 0{ 19 | panic!("chmod error for foo"); 20 | } 21 | 22 | // set absolute mode to "rw-r--r--" 23 | if chmod(CString::new("bar").unwrap().as_ptr(), 24 | S_IRUSR | S_IWUSR | S_IWGRP | S_IROTH) < 0 { 25 | panic!("chmod error for bar"); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/fileflags.rs: -------------------------------------------------------------------------------- 1 | // List 3-4 2 | #![feature(convert)] 3 | extern crate apue; 4 | extern crate libc; 5 | 6 | 7 | // cargo run --example fileflags 2 2>>temp.foo 8 | 9 | use std::env; 10 | use std::ffi::CString; 11 | use apue::fcntl::*; 12 | 13 | use libc::{ 14 | atoi, 15 | c_int, 16 | F_GETFL, 17 | O_RDONLY, 18 | O_WRONLY, 19 | O_RDWR, 20 | O_APPEND, 21 | O_NONBLOCK, 22 | O_SYNC, 23 | // O_FSYNC 24 | }; 25 | // use libc::consts::os::posix01::O_ACCMODE; 26 | // FIXME: 27 | pub const O_ACCMODE : c_int = 3; 28 | 29 | fn main() { 30 | let args: Vec = env::args_os().map(|s| s.to_cstring().unwrap()).collect(); 31 | 32 | if args.len() != 2 { 33 | panic!("useage: {} ", env::args().next().unwrap()) 34 | } 35 | 36 | unsafe { 37 | let val = fcntl(atoi(args[1].as_ptr()), F_GETFL, 0); 38 | if val < 0 { 39 | panic!("fcntl error for fd {}", atoi(args[1].as_ptr())); 40 | } 41 | 42 | match val & O_ACCMODE { 43 | O_RDONLY => print!("read only"), 44 | O_WRONLY => print!("write only"), 45 | O_RDWR => print!("read write"), 46 | _ => panic!("unknown access mode") 47 | } 48 | 49 | if val & O_APPEND != 0 { 50 | print!(", append"); 51 | } 52 | if val & O_NONBLOCK != 0 { 53 | print!(", nonblocking"); 54 | } 55 | 56 | if val & O_SYNC != 0 { 57 | print!(", synchronous writes"); 58 | } 59 | 60 | // if val & O_FSYNC { 61 | // print!(", synchronous writes"); 62 | // } 63 | 64 | println!(""); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /examples/filetype.rs: -------------------------------------------------------------------------------- 1 | // List 4-1 2 | #![feature(convert)] 3 | extern crate apue; 4 | 5 | use apue::stat::*; 6 | use std::ffi::CString; 7 | use std::str; 8 | use std::env; 9 | use std::mem; 10 | 11 | 12 | fn main() { 13 | let args: Vec = env::args_os().map(|s| s.to_cstring().unwrap()).collect(); 14 | for arg in args[1..].iter() { 15 | print!("{}: ", str::from_utf8(arg.as_bytes()).unwrap()); 16 | 17 | unsafe { 18 | let mut buf: stat = mem::zeroed(); 19 | if lstat(arg.as_ptr(), &mut buf) < 0 { 20 | println!("lstat error"); 21 | continue; 22 | } 23 | 24 | let description = if S_ISREG(buf.st_mode) { 25 | "regular" 26 | } else if S_ISDIR(buf.st_mode) { 27 | "directory" 28 | } else if S_ISCHR(buf.st_mode) { 29 | "character special" 30 | } else if S_ISBLK(buf.st_mode) { 31 | "block special" 32 | } else if S_ISFIFO(buf.st_mode) { 33 | "fifo" 34 | } else if S_ISLNK(buf.st_mode) { 35 | "symbolic link" 36 | } else if S_ISSOCK(buf.st_mode) { 37 | "socket" 38 | } else { 39 | "** unknown mode **" 40 | }; 41 | 42 | println!("{}", description); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /examples/getcputc.rs: -------------------------------------------------------------------------------- 1 | extern crate apue; 2 | extern crate libc; 3 | 4 | use libc::{ 5 | ferror, 6 | EOF 7 | }; 8 | 9 | use apue::stdio::{ 10 | stdin, 11 | stdout, 12 | getc, 13 | putc 14 | }; 15 | 16 | 17 | fn main() { 18 | unsafe { 19 | loop { 20 | let c = getc(stdin); 21 | if c != EOF { 22 | if putc(c, stdout) == EOF { 23 | panic!("output error"); 24 | } 25 | } else { 26 | break; 27 | } 28 | } 29 | if ferror(stdin) != 0 { 30 | panic!("input error"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/hello.rs: -------------------------------------------------------------------------------- 1 | extern crate apue; 2 | extern crate libc; 3 | 4 | use libc::{ 5 | getpid 6 | }; 7 | 8 | 9 | fn main() { 10 | unsafe { 11 | println!("hello world from process ID {}", getpid()) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/hole.rs: -------------------------------------------------------------------------------- 1 | // List 3-2 2 | extern crate apue; 3 | extern crate libc; 4 | 5 | use std::ffi::CString; 6 | 7 | use apue::fcntl::*; 8 | use apue::unistd::*; 9 | use apue::stdio::*; 10 | use apue::FILE_MODE; 11 | 12 | use libc::c_void; 13 | 14 | 15 | fn main() { 16 | let buf1 = CString::new("abcdefghij").unwrap(); 17 | let buf2 = CString::new("ABCDEFGHIJ").unwrap(); 18 | 19 | unsafe { 20 | let fd = creat(CString::new("file.hole").unwrap().as_ptr(), FILE_MODE); 21 | if fd < 0 { 22 | panic!("creat error"); 23 | } 24 | 25 | if write(fd, buf1.as_ptr() as *const c_void, 10) != 10 { 26 | panic!("buf1 write error"); 27 | } 28 | // offset now = 10 29 | 30 | if lseek(fd, 16384, SEEK_SET) == -1 { 31 | panic!("lseek error"); 32 | } 33 | // offset now = 16384 34 | 35 | if write(fd, buf2.as_ptr() as *const c_void, 10) != 10 { 36 | panic!("buf2 write error"); 37 | } 38 | // offset now = 16394 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /examples/ls1.rs: -------------------------------------------------------------------------------- 1 | // List 1-1 2 | #![feature(convert)] 3 | 4 | extern crate apue; 5 | extern crate libc; 6 | 7 | 8 | //use libc::types::common::posix88::*; 9 | use std::ffi::{CString, CStr}; 10 | use std::str; 11 | use apue::dirent::{opendir, readdir, closedir}; 12 | 13 | use std::env; 14 | 15 | 16 | fn main() { 17 | let args: Vec = env::args_os().map(|s| s.to_cstring().unwrap()).collect(); 18 | 19 | if args.len() != 2 { 20 | panic!("useage: ls directory_name"); 21 | } 22 | 23 | unsafe { 24 | let dp = opendir(args[1].as_ptr()); 25 | if dp.is_null() { 26 | panic!("can't open {:?}", args[1]); 27 | } 28 | 29 | let mut dirp = readdir(dp); 30 | while !dirp.is_null() { 31 | println!("{}", str::from_utf8(CStr::from_ptr(&(*dirp).d_name[0]).to_bytes()).unwrap()); 32 | dirp = readdir(dp); 33 | } 34 | closedir(dp); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /examples/mycat.rs: -------------------------------------------------------------------------------- 1 | // List 1-2 2 | // List 3-3 3 | extern crate apue; 4 | extern crate libc; 5 | 6 | use apue::unistd::*; 7 | use apue::consts::*; 8 | use libc::{ 9 | c_char, 10 | size_t, 11 | c_void 12 | }; 13 | 14 | const BUFFSIZE: usize = 4096; 15 | 16 | 17 | fn main() { 18 | 19 | let mut buf: [c_char; BUFFSIZE] = [0; BUFFSIZE]; 20 | let mut n; 21 | unsafe { 22 | loop { 23 | n = read(STDIN_FILENO, &mut buf[0] as *mut c_char as *mut c_void, BUFFSIZE as size_t); 24 | if n > 0 { 25 | if write(STDOUT_FILENO, &buf[0] as *const c_char as *const c_void, n as size_t) != n { 26 | panic!("write error"); 27 | } 28 | } else { 29 | break; 30 | } 31 | } 32 | } 33 | 34 | if n < 0 { 35 | panic!("read error"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /examples/pipe1.rs: -------------------------------------------------------------------------------- 1 | // List 15-1 2 | extern crate apue; 3 | extern crate libc; 4 | 5 | use apue::unistd::*; 6 | use apue::consts::*; 7 | use apue::MAXLINE; 8 | use apue::string::strlen; 9 | use std::ffi::CString; 10 | use libc::{ 11 | c_int, 12 | c_void, 13 | c_char, 14 | size_t 15 | }; 16 | 17 | fn main() { 18 | let mut line = [0 as c_char; MAXLINE]; 19 | 20 | unsafe { 21 | let mut fd = [0 as c_int; 2]; 22 | 23 | if pipe(&mut fd[0]) < 0 { 24 | panic!("pipe error"); 25 | } 26 | // println!("got fds => {:?}", fd); 27 | let pid = fork(); 28 | if pid < 0 { 29 | panic!("fork error"); 30 | } else if pid > 0 { // parent 31 | close(fd[0]); 32 | let msg = CString::new("hello world\n").unwrap().as_ptr(); 33 | write(fd[1], msg as *const c_void, strlen(msg)); 34 | } else { // child 35 | close(fd[1]); 36 | let n = read(fd[0], &mut line[0] as *mut c_char as *mut c_void, MAXLINE as size_t); 37 | write(STDOUT_FILENO, &line[0] as *const c_char as *const c_void, n as size_t); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /examples/seek.rs: -------------------------------------------------------------------------------- 1 | // List 3-1 2 | extern crate apue; 3 | 4 | //use apue::fcntl::*; 5 | use apue::unistd::*; 6 | use apue::stdio::*; 7 | use apue::consts::*; 8 | 9 | fn main() { 10 | unsafe { 11 | if lseek(STDIN_FILENO, 0, SEEK_CUR) == -1 { 12 | println!("cannot seek"); 13 | } else { 14 | println!("seek OK"); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/setfl.rs: -------------------------------------------------------------------------------- 1 | // List 3-5 2 | extern crate apue; 3 | extern crate libc; 4 | 5 | use apue::fcntl::*; 6 | 7 | use libc::{ 8 | c_int, 9 | F_GETFL, 10 | F_SETFL, 11 | // O_RDONLY, 12 | // O_WRONLY, 13 | // O_RDWR, 14 | // O_APPEND, 15 | O_NONBLOCK, 16 | O_SYNC, 17 | }; 18 | 19 | 20 | unsafe fn set_fl(fd: c_int, flags: c_int) { 21 | let mut val = fcntl(fd, F_GETFL, 0); 22 | if val < 0 { 23 | panic!("fcntl F_GETFL error"); 24 | } 25 | 26 | val |= flags; // turn on flags 27 | 28 | if fcntl(fd, F_SETFL, val) < 0 { 29 | panic!("fcntl F_SETFL error"); 30 | } 31 | } 32 | 33 | fn main() { 34 | unsafe { 35 | set_fl(0, O_SYNC | O_NONBLOCK); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /examples/shell1.rs: -------------------------------------------------------------------------------- 1 | // List 1-5 2 | extern crate apue; 3 | extern crate libc; 4 | 5 | use std::ptr; 6 | use std::io::prelude::*; 7 | use std::io; 8 | use std::process::exit; 9 | use std::ffi::CStr; 10 | use std::str; 11 | use libc::{ 12 | strlen, 13 | fgets, 14 | fork, 15 | // execlp, 16 | waitpid, 17 | c_char, 18 | c_int, 19 | }; 20 | 21 | use apue::{ 22 | MAXLINE, 23 | errno 24 | }; 25 | use apue::stdio::stdin; 26 | 27 | extern { 28 | // this is a var arg func in C 29 | // int execlp(const char *file, const char *arg0, ... /*, (char *)0 */); 30 | fn execlp(file: *const c_char, arg0: *const c_char, _: *const c_char); 31 | } 32 | 33 | fn main() { 34 | let mut buf: [c_char; MAXLINE] = [0; MAXLINE]; 35 | print!("% "); 36 | io::stdout().flush().unwrap(); 37 | unsafe { 38 | loop { 39 | if fgets(&mut buf[0], MAXLINE as c_int, stdin).is_null() { 40 | break; 41 | } 42 | 43 | let end_char_pos = strlen(&buf[0]) as usize - 1; 44 | if buf[end_char_pos] == '\n' as c_char { 45 | buf[end_char_pos] = 0; 46 | } 47 | 48 | let mut pid = fork(); 49 | if pid < 0 { 50 | panic!("fork error"); 51 | } else if pid == 0 { // child 52 | execlp(&buf[0], &buf[0], ptr::null()); 53 | if errno() != 0 { 54 | println!("couldn't execute: {}", str::from_utf8(CStr::from_ptr(&buf[0]).to_bytes()).unwrap()); 55 | exit(127); 56 | } 57 | } 58 | // parent 59 | let status = 0; 60 | pid = waitpid(pid, &status, 0); 61 | if pid < 0 { 62 | panic!("waitpid error"); 63 | } 64 | 65 | print!("% "); 66 | io::stdout().flush().unwrap(); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /examples/shell2.rs: -------------------------------------------------------------------------------- 1 | // List 1-8 2 | extern crate apue; 3 | extern crate libc; 4 | 5 | use std::ptr; 6 | use std::io::prelude::*; 7 | use std::io; 8 | use std::process::exit; 9 | use std::ffi::CStr; 10 | use std::str; 11 | use libc::{ 12 | strlen, 13 | fgets, 14 | fork, 15 | // execlp, 16 | waitpid, 17 | c_char, 18 | c_int, 19 | SIGINT, 20 | }; 21 | use libc::funcs::posix01::signal::signal; 22 | use libc::types::os::common::posix01::sighandler_t; 23 | use apue::{ 24 | MAXLINE, 25 | errno 26 | }; 27 | use apue::stdio::stdin; 28 | 29 | 30 | 31 | extern { 32 | // this is a var arg func in C 33 | // int execlp(const char *file, const char *arg0, ... /*, (char *)0 */); 34 | fn execlp(file: *const c_char, arg0: *const c_char, _: *const c_char); 35 | } 36 | 37 | 38 | // our signal-catching function 39 | extern "C" fn sig_int(_signo: c_int) { 40 | println!("interrupt\n% "); 41 | } 42 | 43 | 44 | #[allow(non_snake_case)] 45 | fn main() { 46 | let mut buf: [c_char; MAXLINE] = [0; MAXLINE]; 47 | unsafe { 48 | let SIG_ERR = -1; 49 | if signal(SIGINT, sig_int as sighandler_t) == SIG_ERR { 50 | panic!("signal error"); 51 | } 52 | print!("% "); 53 | io::stdout().flush().unwrap(); 54 | loop { 55 | if fgets(&mut buf[0], MAXLINE as c_int, stdin).is_null() { 56 | break; 57 | } 58 | 59 | let end_char_pos = strlen(&buf[0]) as usize - 1; 60 | if buf[end_char_pos] == '\n' as c_char { 61 | buf[end_char_pos] = 0; 62 | } 63 | 64 | let mut pid = fork(); 65 | if pid < 0 { 66 | panic!("fork error"); 67 | } else if pid == 0 { // child 68 | execlp(&buf[0], &buf[0], ptr::null()); 69 | if errno() != 0 { 70 | println!("couldn't execute: {}", str::from_utf8(CStr::from_ptr(&buf[0]).to_bytes()).unwrap()); 71 | exit(127); 72 | } 73 | } 74 | // parent 75 | let status = 0; 76 | pid = waitpid(pid, &status, 0); 77 | if pid < 0 { 78 | panic!("waitpid error"); 79 | } 80 | 81 | print!("% "); 82 | io::stdout().flush().unwrap(); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /examples/testerror.rs: -------------------------------------------------------------------------------- 1 | // List 1-6 2 | extern crate apue; 3 | extern crate libc; 4 | 5 | use std::io::prelude::*; 6 | use std::io; 7 | use std::str; 8 | use std::env; 9 | use std::ffi::{CStr, CString}; 10 | use libc::{ 11 | strerror, 12 | perror 13 | }; 14 | use apue::{ 15 | errno, 16 | }; 17 | 18 | 19 | fn main() { 20 | unsafe { 21 | write!(io::stderr(), "EACCESS: {}\n", 22 | str::from_utf8(CStr::from_ptr(strerror(errno())).to_bytes()).unwrap()).unwrap(); 23 | perror(CString::new(env::args().next().unwrap()).unwrap().as_ptr()) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/uidgid.rs: -------------------------------------------------------------------------------- 1 | // List 1-7 2 | extern crate libc; 3 | 4 | use libc::{ 5 | getuid, 6 | getgid 7 | }; 8 | 9 | 10 | fn main() { 11 | unsafe { 12 | println!("uid = {}, gid = {}", getuid(), getgid()); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /examples/umask.rs: -------------------------------------------------------------------------------- 1 | // List 4-3 2 | extern crate apue; 3 | 4 | use apue::stat::*; 5 | use apue::fcntl::*; 6 | use std::ffi::CString; 7 | use apue::consts::*; 8 | use apue::types::*; 9 | 10 | const RWRWRW: mode_t = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; 11 | 12 | fn main() { 13 | unsafe { 14 | umask(0); 15 | if creat(CString::new("foo").unwrap().as_ptr(), RWRWRW) < 0 { 16 | panic!("creat error for foo"); 17 | } 18 | 19 | umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); 20 | if creat(CString::new("bar").unwrap().as_ptr(), RWRWRW) < 0 { 21 | panic!("creat error for bar"); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /examples/unlink.rs: -------------------------------------------------------------------------------- 1 | // List 4-5 2 | extern crate apue; 3 | 4 | use apue::unistd::*; 5 | use apue::fcntl::*; 6 | use std::ffi::CString; 7 | use apue::consts::*; 8 | 9 | fn main() { 10 | unsafe { 11 | if open(CString::new("tempfile").unwrap().as_ptr(), O_RDWR, 0) < 0 { 12 | panic!("open error"); 13 | } 14 | if unlink(CString::new("tempfile").unwrap().as_ptr()) < 0 { 15 | panic!("unlink error"); 16 | } 17 | println!("file unlinked"); 18 | sleep(15); 19 | println!("done"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /run_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh +x 2 | 3 | 4 | cargo run --example ls1 .. 5 | 6 | echo "HELLO WORLD" | cargo run --example mycat 7 | 8 | echo hello | cargo run --example getcputc 9 | 10 | cargo run --example hello 11 | 12 | echo date | cargo run --example shell1 13 | 14 | cargo run --example testerror 15 | 16 | cargo run --example uidgid 17 | 18 | cargo run --example seek 19 | 20 | cargo run --example hole 21 | 22 | cargo run --example fileflags 1 23 | 24 | cargo run --example setfl 25 | 26 | cargo run --example filetype README.md 27 | 28 | cargo run --example access README.md 29 | 30 | cargo run --example umask 31 | 32 | cargo run --example changemod 33 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(plugin)] 2 | #![plugin(bindgen_plugin)] 3 | 4 | 5 | extern crate libc; 6 | 7 | use libc::types::os::arch::posix88::*; 8 | use self::s_ifmt::*; 9 | 10 | pub const MAXLINE: usize = 4096; 11 | pub const FILE_MODE: libc::mode_t = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 12 | 13 | 14 | 15 | pub mod types { 16 | pub use libc::types::os::arch::posix88::*; 17 | } 18 | 19 | pub mod consts { 20 | pub use libc::consts::os::posix88::{ 21 | O_APPEND, 22 | O_CREAT, 23 | O_EXCL, 24 | O_NOCTTY, 25 | O_RDONLY, 26 | O_RDWR, 27 | O_TRUNC, 28 | O_WRONLY, 29 | F_OK, 30 | R_OK, 31 | W_OK, 32 | X_OK 33 | }; 34 | pub use libc::consts::os::posix88::{ 35 | STDIN_FILENO, 36 | STDOUT_FILENO, 37 | STDERR_FILENO 38 | }; 39 | pub use super::s_ifmt::*; 40 | } 41 | 42 | // errno 43 | extern { 44 | #[cfg_attr(any(target_os = "macos", 45 | target_os = "ios", 46 | target_os = "freebsd"), 47 | link_name = "__error")] 48 | pub fn errnop() -> *mut libc::c_int; 49 | } 50 | pub fn errno() -> libc::c_int { 51 | unsafe { 52 | *errnop() 53 | } 54 | } 55 | 56 | 57 | 58 | pub mod fcntl { 59 | pub use libc::funcs::posix88::fcntl::{ 60 | open, 61 | creat, 62 | fcntl 63 | }; 64 | } 65 | 66 | 67 | pub mod unistd { 68 | pub use libc::funcs::posix88::unistd::*; 69 | } 70 | 71 | pub mod dirent { 72 | // the functions in this mod maybe linked with wrong version 73 | #[allow(dead_code, non_camel_case_types, non_snake_case)] 74 | mod ffi { 75 | bindgen!("/usr/include/dirent.h", match="dirent.h"); 76 | } 77 | 78 | pub use self::ffi::{ 79 | DIR, Struct_dirent, closedir, 80 | }; 81 | use libc::c_char; 82 | 83 | #[cfg(target_os = "macos")] 84 | extern { 85 | #[link_name="opendir$INODE64"] 86 | pub fn opendir(arg1: *const c_char) -> *mut DIR; 87 | #[link_name="readdir$INODE64"] 88 | pub fn readdir(arg1: *mut DIR) -> *mut Struct_dirent; 89 | } 90 | 91 | #[cfg(not(target_os = "macos"))] 92 | extern { 93 | #[link_name="opendir"] 94 | pub fn opendir(arg1: *const c_char) -> *mut DIR; 95 | #[link_name="readdir"] 96 | pub fn readdir(arg1: *mut DIR) -> *mut Struct_dirent; 97 | } 98 | } 99 | 100 | 101 | pub mod stdio { 102 | use libc::{ 103 | FILE, 104 | c_int, 105 | fgetc, 106 | fputc 107 | }; 108 | 109 | pub use libc::{ 110 | SEEK_SET, 111 | SEEK_CUR, 112 | SEEK_END 113 | }; 114 | 115 | extern { 116 | #[link_name="__stdinp"] 117 | pub static stdin: *mut FILE; 118 | 119 | #[link_name="__stdoutp"] 120 | pub static stdout: *mut FILE; 121 | } 122 | 123 | #[inline] 124 | pub unsafe fn getc(stream: *mut FILE) -> c_int { 125 | fgetc(stream) 126 | } 127 | 128 | #[inline] 129 | pub unsafe fn putc(c: c_int, stream: *mut FILE) -> c_int { 130 | fputc(c, stream) 131 | } 132 | } 133 | 134 | 135 | pub mod string { 136 | pub use libc::funcs::c95::string::*; 137 | } 138 | 139 | #[allow(non_snake_case, overflowing_literals)] 140 | mod s_ifmt { 141 | use libc::types::os::arch::posix88::mode_t; 142 | 143 | pub use libc::consts::os::posix88::{ 144 | S_IEXEC, 145 | S_IFBLK, 146 | S_IFCHR, 147 | S_IFDIR, 148 | S_IFIFO, 149 | S_IFLNK, 150 | S_IFMT, 151 | S_IFREG, 152 | S_IREAD, 153 | S_IRGRP, 154 | S_IROTH, 155 | S_IRUSR, 156 | S_IRWXG, 157 | S_IRWXO, 158 | S_IRWXU, 159 | S_IWGRP, 160 | S_IWOTH, 161 | S_IWRITE, 162 | S_IWUSR, 163 | S_IXGRP, 164 | S_IXOTH, 165 | S_IXUSR, 166 | }; 167 | 168 | pub const S_IFSOCK: mode_t = 0140000; 169 | } 170 | 171 | #[allow(non_snake_case, overflowing_literals)] 172 | pub mod stat { 173 | pub use libc::funcs::posix88::stat_::*; 174 | pub use libc::types::os::arch::posix01::stat; 175 | pub use libc::funcs::posix01::stat_::lstat; 176 | 177 | use libc::types::os::arch::posix88::mode_t; 178 | use super::s_ifmt::*; 179 | 180 | #[allow(dead_code, non_camel_case_types, non_snake_case)] 181 | mod ffi { 182 | bindgen!("/usr/include/sys/stat.h", match="stat.h"); 183 | } 184 | 185 | pub use self::ffi::{ 186 | umask 187 | }; 188 | 189 | #[inline] 190 | pub fn S_ISBLK(m: mode_t) -> bool { 191 | (((m) & S_IFMT) == S_IFBLK) /* block special */ 192 | } 193 | 194 | #[inline] 195 | pub fn S_ISCHR(m: mode_t) -> bool { 196 | (((m) & S_IFMT) == S_IFCHR) /* char special */ 197 | } 198 | 199 | #[inline] 200 | pub fn S_ISDIR(m: mode_t) -> bool { 201 | (((m) & S_IFMT) == S_IFDIR) /* directory */ 202 | } 203 | 204 | #[inline] 205 | pub fn S_ISFIFO(m: mode_t) -> bool { 206 | (((m) & S_IFMT) == S_IFIFO) /* fifo or socket */ 207 | } 208 | 209 | #[inline] 210 | pub fn S_ISREG(m: mode_t) -> bool { 211 | (((m) & S_IFMT) == S_IFREG) /* regular file */ 212 | } 213 | 214 | #[inline] 215 | pub fn S_ISLNK(m: mode_t) -> bool { 216 | (((m) & S_IFMT) == S_IFLNK) /* symbolic link */ 217 | } 218 | 219 | #[inline] 220 | pub fn S_ISSOCK(m: mode_t) -> bool { 221 | (((m) & S_IFMT) == S_IFSOCK) /* socket */ 222 | } 223 | } 224 | --------------------------------------------------------------------------------