diff --git a/Cargo.lock b/Cargo.lock index c81e73fd0706a7b99047c932ec145a32a7317bd1..c4e0e0478ae2a33904295253de588ea684d4f8e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -331,6 +331,7 @@ dependencies = [ "stdlib 0.1.0", "string 0.1.0", "strings 0.1.0", + "sys_ioctl 0.1.0", "sys_mman 0.1.0", "sys_resource 0.1.0", "sys_socket 0.1.0", @@ -507,6 +508,14 @@ dependencies = [ "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sys_ioctl" +version = "0.1.0" +dependencies = [ + "cbindgen 0.5.2", + "platform 0.1.0", +] + [[package]] name = "sys_mman" version = "0.1.0" @@ -647,7 +656,7 @@ dependencies = [ "platform 0.1.0", "stdio 0.1.0", "string 0.1.0", - "sys_utsname 0.1.0", + "sys_ioctl 0.1.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 2f27d51315e33e08ea6c0952b8e1b70b8b709e0a..4af47a19934249c8c5e043378614730f7a17ddc5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ stdio = { path = "src/stdio" } stdlib = { path = "src/stdlib" } string = { path = "src/string" } strings = { path = "src/strings" } +sys_ioctl = { path = "src/sys_ioctl" } sys_mman = { path = "src/sys_mman" } sys_resource = { path = "src/sys_resource" } sys_socket = { path = "src/sys_socket" } diff --git a/include/bits/sys/ioctl.h b/include/bits/sys/ioctl.h new file mode 100644 index 0000000000000000000000000000000000000000..2a2aab608a68008f7c64d93079164aa665d97c67 --- /dev/null +++ b/include/bits/sys/ioctl.h @@ -0,0 +1,11 @@ +// Shamelessly copy-pasted from musl + +#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) ) +#define _IOC_NONE 0U +#define _IOC_WRITE 1U +#define _IOC_READ 2U + +#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0) +#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c)) +#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c)) +#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c)) diff --git a/src/dirent/src/lib.rs b/src/dirent/src/lib.rs index 33774e84837064f3e9db887e52c9518f7af7814a..819b4d4b0663e496e4177c1b18efe97e0d638ddf 100644 --- a/src/dirent/src/lib.rs +++ b/src/dirent/src/lib.rs @@ -1,6 +1,7 @@ +//! dirent implementation following http://pubs.opengroup.org/onlinepubs/009695399/basedefs/dirent.h.html + #![no_std] #![feature(alloc)] -///! dirent implementation following http://pubs.opengroup.org/onlinepubs/009695399/basedefs/dirent.h.html extern crate alloc; extern crate errno; diff --git a/src/lib.rs b/src/lib.rs index 2c170ceb53e6a04343146c967d5ea69d6b8d7752..d2825fe8d8c9c24d69cbbdf6f56dc9c208bb0b87 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,6 +23,7 @@ pub extern crate stdio; pub extern crate stdlib; pub extern crate string; pub extern crate strings; +pub extern crate sys_ioctl; pub extern crate sys_mman; pub extern crate sys_resource; pub extern crate sys_socket; diff --git a/src/platform/src/linux/mod.rs b/src/platform/src/linux/mod.rs index 29c0de44a9ec666ca5d052838bccccac58016257..4b61ba7541f81d2f0ff5f35714313a2799ec09bd 100644 --- a/src/platform/src/linux/mod.rs +++ b/src/platform/src/linux/mod.rs @@ -214,6 +214,10 @@ pub fn getuid() -> uid_t { e(unsafe { syscall!(GETUID) }) } +pub fn ioctl(fd: c_int, request: c_ulong, out: *mut c_void) -> c_int { + e(unsafe { syscall!(IOCTL, fd, request, out) }) as c_int +} + pub fn kill(pid: pid_t, sig: c_int) -> c_int { e(unsafe { syscall!(KILL, pid, sig) }) as c_int } diff --git a/src/sys_ioctl/Cargo.toml b/src/sys_ioctl/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..d0e42196c532445debbf1025a2ed88f142734336 --- /dev/null +++ b/src/sys_ioctl/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "sys_ioctl" +version = "0.1.0" +authors = ["jD91mZM2 <me@krake.one>"] + +[build-dependencies] +cbindgen = { path = "../../cbindgen" } + +[target.'cfg(target_os = "linux")'.dependencies] +platform = { path = "../platform" } diff --git a/src/sys_ioctl/build.rs b/src/sys_ioctl/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..e82221d0b378d1ced02c2478d49de5b34aaa3b0c --- /dev/null +++ b/src/sys_ioctl/build.rs @@ -0,0 +1,11 @@ +extern crate cbindgen; + +use std::{env, fs}; + +fn main() { + let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set"); + fs::create_dir_all("../../target/include").expect("failed to create include directory"); + cbindgen::generate(crate_dir) + .expect("failed to generate bindings") + .write_to_file("../../target/include/sys/ioctl.h"); +} diff --git a/src/sys_ioctl/cbindgen.toml b/src/sys_ioctl/cbindgen.toml new file mode 100644 index 0000000000000000000000000000000000000000..6a539376f7ddfc882d63266d5abd28906e4d28c4 --- /dev/null +++ b/src/sys_ioctl/cbindgen.toml @@ -0,0 +1,7 @@ +sys_includes = [] +include_guard = "_IOCTL_H" +language = "C" +style = "Tag" + +[enum] +prefix_with_name = true diff --git a/src/sys_ioctl/src/lib.rs b/src/sys_ioctl/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..de1f7e0d114ae586ed18aec510a0be48be605f6a --- /dev/null +++ b/src/sys_ioctl/src/lib.rs @@ -0,0 +1,216 @@ +//! ioctl implementation for linux + +#![no_std] + +#[cfg(target_os = "linux")] +pub mod inner { + extern crate platform; + + use self::platform::types::*; + + #[repr(C)] + #[derive(Default)] + pub struct winsize { + ws_row: c_ushort, + ws_col: c_ushort, + ws_xpixel: c_ushort, + ws_ypixel: c_ushort + } + + #[no_mangle] + pub extern "C" fn ioctl(fd: c_int, request: c_ulong, out: *mut c_void) -> c_int { + // TODO: Somehow support varargs to syscall?? + platform::ioctl(fd, request, out) + } + + pub const TCGETS: u32 = 0x5401; + pub const TCSETS: u32 = 0x5402; + pub const TCSETSW: u32 = 0x5403; + pub const TCSETSF: u32 = 0x5404; + pub const TCGETA: u32 = 0x5405; + pub const TCSETA: u32 = 0x5406; + pub const TCSETAW: u32 = 0x5407; + pub const TCSETAF: u32 = 0x5408; + pub const TCSBRK: u32 = 0x5409; + pub const TCXONC: u32 = 0x540A; + pub const TCFLSH: u32 = 0x540B; + pub const TIOCEXCL: u32 = 0x540C; + pub const TIOCNXCL: u32 = 0x540D; + pub const TIOCSCTTY: u32 = 0x540E; + pub const TIOCGPGRP: u32 = 0x540F; + pub const TIOCSPGRP: u32 = 0x5410; + pub const TIOCOUTQ: u32 = 0x5411; + pub const TIOCSTI: u32 = 0x5412; + pub const TIOCGWINSZ: u32 = 0x5413; + pub const TIOCSWINSZ: u32 = 0x5414; + pub const TIOCMGET: u32 = 0x5415; + pub const TIOCMBIS: u32 = 0x5416; + pub const TIOCMBIC: u32 = 0x5417; + pub const TIOCMSET: u32 = 0x5418; + pub const TIOCGSOFTCAR: u32 = 0x5419; + pub const TIOCSSOFTCAR: u32 = 0x541A; + pub const FIONREAD: u32 = 0x541B; + pub const TIOCINQ: u32 = FIONREAD; + pub const TIOCLINUX: u32 = 0x541C; + pub const TIOCCONS: u32 = 0x541D; + pub const TIOCGSERIAL: u32 = 0x541E; + pub const TIOCSSERIAL: u32 = 0x541F; + pub const TIOCPKT: u32 = 0x5420; + pub const FIONBIO: u32 = 0x5421; + pub const TIOCNOTTY: u32 = 0x5422; + pub const TIOCSETD: u32 = 0x5423; + pub const TIOCGETD: u32 = 0x5424; + pub const TCSBRKP: u32 = 0x5425; + pub const TIOCSBRK: u32 = 0x5427; + pub const TIOCCBRK: u32 = 0x5428; + pub const TIOCGSID: u32 = 0x5429; + pub const TIOCGRS485: u32 = 0x542E; + pub const TIOCSRS485: u32 = 0x542F; + pub const TIOCGPTN: u32 = 0x80045430; + pub const TIOCSPTLCK: u32 = 0x40045431; + pub const TIOCGDEV: u32 = 0x80045432; + pub const TCGETX: u32 = 0x5432; + pub const TCSETX: u32 = 0x5433; + pub const TCSETXF: u32 = 0x5434; + pub const TCSETXW: u32 = 0x5435; + pub const TIOCSIG: u32 = 0x40045436; + pub const TIOCVHANGUP: u32 = 0x5437; + pub const TIOCGPKT: u32 = 0x80045438; + pub const TIOCGPTLCK: u32 = 0x80045439; + pub const TIOCGEXCL: u32 = 0x80045440; + pub const TIOCGPTPEER: u32 = 0x5441; + + pub const FIONCLEX: u32 = 0x5450; + pub const FIOCLEX: u32 = 0x5451; + pub const FIOASYNC: u32 = 0x5452; + pub const TIOCSERCONFIG: u32 = 0x5453; + pub const TIOCSERGWILD: u32 = 0x5454; + pub const TIOCSERSWILD: u32 = 0x5455; + pub const TIOCGLCKTRMIOS: u32 = 0x5456; + pub const TIOCSLCKTRMIOS: u32 = 0x5457; + pub const TIOCSERGSTRUCT: u32 = 0x5458; + pub const TIOCSERGETLSR: u32 = 0x5459; + pub const TIOCSERGETMULTI: u32 = 0x545A; + pub const TIOCSERSETMULTI: u32 = 0x545B; + + pub const TIOCMIWAIT: u32 = 0x545C; + pub const TIOCGICOUNT: u32 = 0x545D; + pub const FIOQSIZE: u32 = 0x5460; + + pub const TIOCPKT_DATA: u32 = 0; + pub const TIOCPKT_FLUSHREAD: u32 = 1; + pub const TIOCPKT_FLUSHWRITE: u32 = 2; + pub const TIOCPKT_STOP: u32 = 4; + pub const TIOCPKT_START: u32 = 8; + pub const TIOCPKT_NOSTOP: u32 = 16; + pub const TIOCPKT_DOSTOP: u32 = 32; + pub const TIOCPKT_IOCTL: u32 = 64; + + pub const TIOCSER_TEMT: u32 = 0x01; + + pub const TIOCM_LE: u32 = 0x001; + pub const TIOCM_DTR: u32 = 0x002; + pub const TIOCM_RTS: u32 = 0x004; + pub const TIOCM_ST: u32 = 0x008; + pub const TIOCM_SR: u32 = 0x010; + pub const TIOCM_CTS: u32 = 0x020; + pub const TIOCM_CAR: u32 = 0x040; + pub const TIOCM_RNG: u32 = 0x080; + pub const TIOCM_DSR: u32 = 0x100; + pub const TIOCM_CD: u32 = TIOCM_CAR; + pub const TIOCM_RI: u32 = TIOCM_RNG; + pub const TIOCM_OUT1: u32 = 0x2000; + pub const TIOCM_OUT2: u32 = 0x4000; + pub const TIOCM_LOOP: u32 = 0x8000; + + pub const N_TTY: u32 = 0; + pub const N_SLIP: u32 = 1; + pub const N_MOUSE: u32 = 2; + pub const N_PPP: u32 = 3; + pub const N_STRIP: u32 = 4; + pub const N_AX25: u32 = 5; + pub const N_X25: u32 = 6; + pub const N_6PACK: u32 = 7; + pub const N_MASC: u32 = 8; + pub const N_R3964: u32 = 9; + pub const N_PROFIBUS_FDL: u32 = 10; + pub const N_IRDA: u32 = 11; + pub const N_SMSBLOCK: u32 = 12; + pub const N_HDLC: u32 = 13; + pub const N_SYNC_PPP: u32 = 14; + pub const N_HCI: u32 = 15; + + pub const FIOSETOWN: u32 = 0x8901; + pub const SIOCSPGRP: u32 = 0x8902; + pub const FIOGETOWN: u32 = 0x8903; + pub const SIOCGPGRP: u32 = 0x8904; + pub const SIOCATMARK: u32 = 0x8905; + pub const SIOCGSTAMP: u32 = 0x8906; + pub const SIOCGSTAMPNS: u32 = 0x8907; + + pub const SIOCADDRT: u32 = 0x890B; + pub const SIOCDELRT: u32 = 0x890C; + pub const SIOCRTMSG: u32 = 0x890D; + + pub const SIOCGIFNAME: u32 = 0x8910; + pub const SIOCSIFLINK: u32 = 0x8911; + pub const SIOCGIFCONF: u32 = 0x8912; + pub const SIOCGIFFLAGS: u32 = 0x8913; + pub const SIOCSIFFLAGS: u32 = 0x8914; + pub const SIOCGIFADDR: u32 = 0x8915; + pub const SIOCSIFADDR: u32 = 0x8916; + pub const SIOCGIFDSTADDR: u32 = 0x8917; + pub const SIOCSIFDSTADDR: u32 = 0x8918; + pub const SIOCGIFBRDADDR: u32 = 0x8919; + pub const SIOCSIFBRDADDR: u32 = 0x891a; + pub const SIOCGIFNETMASK: u32 = 0x891b; + pub const SIOCSIFNETMASK: u32 = 0x891c; + pub const SIOCGIFMETRIC: u32 = 0x891d; + pub const SIOCSIFMETRIC: u32 = 0x891e; + pub const SIOCGIFMEM: u32 = 0x891f; + pub const SIOCSIFMEM: u32 = 0x8920; + pub const SIOCGIFMTU: u32 = 0x8921; + pub const SIOCSIFMTU: u32 = 0x8922; + pub const SIOCSIFNAME: u32 = 0x8923; + pub const SIOCSIFHWADDR: u32 = 0x8924; + pub const SIOCGIFENCAP: u32 = 0x8925; + pub const SIOCSIFENCAP: u32 = 0x8926; + pub const SIOCGIFHWADDR: u32 = 0x8927; + pub const SIOCGIFSLAVE: u32 = 0x8929; + pub const SIOCSIFSLAVE: u32 = 0x8930; + pub const SIOCADDMULTI: u32 = 0x8931; + pub const SIOCDELMULTI: u32 = 0x8932; + pub const SIOCGIFINDEX: u32 = 0x8933; + pub const SIOGIFINDEX: u32 = SIOCGIFINDEX; + pub const SIOCSIFPFLAGS: u32 = 0x8934; + pub const SIOCGIFPFLAGS: u32 = 0x8935; + pub const SIOCDIFADDR: u32 = 0x8936; + pub const SIOCSIFHWBROADCAST: u32 = 0x8937; + pub const SIOCGIFCOUNT: u32 = 0x8938; + + pub const SIOCGIFBR: u32 = 0x8940; + pub const SIOCSIFBR: u32 = 0x8941; + + pub const SIOCGIFTXQLEN: u32 = 0x8942; + pub const SIOCSIFTXQLEN: u32 = 0x8943; + + pub const SIOCDARP: u32 = 0x8953; + pub const SIOCGARP: u32 = 0x8954; + pub const SIOCSARP: u32 = 0x8955; + + pub const SIOCDRARP: u32 = 0x8960; + pub const SIOCGRARP: u32 = 0x8961; + pub const SIOCSRARP: u32 = 0x8962; + + pub const SIOCGIFMAP: u32 = 0x8970; + pub const SIOCSIFMAP: u32 = 0x8971; + + pub const SIOCADDDLCI: u32 = 0x8980; + pub const SIOCDELDLCI: u32 = 0x8981; + + pub const SIOCDEVPRIVATE: u32 = 0x89F0; + pub const SIOCPROTOPRIVATE: u32 = 0x89E0; +} + +#[cfg(target_os = "linux")] +pub use inner::*; diff --git a/src/sys_utsname/Cargo.toml b/src/sys_utsname/Cargo.toml index e03fbb2fd0d17bd553fa07fa1fd832e870340cce..69edfcfea930b5e47b44a8a990d5815e88255479 100644 --- a/src/sys_utsname/Cargo.toml +++ b/src/sys_utsname/Cargo.toml @@ -7,5 +7,5 @@ build = "build.rs" [build-dependencies] cbindgen = { path = "../../cbindgen" } -[dependencies] +[target.'cfg(target_os = "linux")'.dependencies] platform = { path = "../platform" } diff --git a/src/sys_utsname/src/lib.rs b/src/sys_utsname/src/lib.rs index ae6c16f4bf08d2b732dab878c3140a2fe8a72e15..916ed56e0fa968043bb40578cfd1c2b4efa88783 100644 --- a/src/sys_utsname/src/lib.rs +++ b/src/sys_utsname/src/lib.rs @@ -1,4 +1,4 @@ -//! sys/utsname implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/sysutsname.h.html +//! sys/utsname implementation for linux, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/sysutsname.h.html #![no_std] @@ -10,7 +10,6 @@ mod inner { const UTSLENGTH: usize = 65; - #[no_mangle] #[repr(C)] pub struct utsname { pub sysname: [c_char; UTSLENGTH], diff --git a/src/unistd/Cargo.toml b/src/unistd/Cargo.toml index b5311385a8e84560fee21646fcc3e38ef0620f5d..3cf577728daa7b1468e8f11ad3bcdacfebb1f059 100644 --- a/src/unistd/Cargo.toml +++ b/src/unistd/Cargo.toml @@ -12,4 +12,4 @@ errno = { path = "../errno" } platform = { path = "../platform" } stdio = { path = "../stdio" } string = { path = "../string" } -sys_utsname = { path = "../sys_utsname" } +sys_ioctl = { path = "../sys_ioctl" } diff --git a/src/unistd/src/lib.rs b/src/unistd/src/lib.rs index 6350031fbd58fc3bf2e7f30f18c9109b32724b57..a6a1ab2939f803a42553cf4ff89ddcaf58d0f6ee 100644 --- a/src/unistd/src/lib.rs +++ b/src/unistd/src/lib.rs @@ -1,19 +1,17 @@ //! unistd implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/unistd.h.html #![no_std] -#![cfg_attr(target_os = "redox", feature(alloc))] -#[cfg(target_os = "redox")] -extern crate alloc; extern crate errno; extern crate platform; extern crate stdio; extern crate string; -extern crate sys_utsname; +extern crate sys_ioctl; use core::{ptr, slice}; use platform::types::*; +use sys_ioctl::{ioctl, winsize}; pub use brk::*; pub use getopt::*; @@ -264,9 +262,10 @@ pub extern "C" fn getwd(path_name: *mut c_char) -> *mut c_char { getcwd(path_name, 4096 /* PATH_MAX */) } -// #[no_mangle] -pub extern "C" fn isatty(fildes: c_int) -> c_int { - unimplemented!(); +#[no_mangle] +pub extern "C" fn isatty(fd: c_int) -> c_int { + let mut winsize = winsize::default(); + (ioctl(fd, sys_ioctl::TIOCGWINSZ as c_ulong, &mut winsize as *mut _ as *mut c_void) == 0) as c_int } // #[no_mangle] diff --git a/tests/.gitignore b/tests/.gitignore index 768338b9d44391a5503391f053e0f8f6737785c7..253dece984710d1aef5c80ff7bb9ab4f05d6d9c7 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -53,6 +53,7 @@ unistd/fchdir unistd/fsync unistd/ftruncate unistd/getopt +unistd/isatty unistd/pipe unistd/rmdir unistd/sleep diff --git a/tests/Makefile b/tests/Makefile index b9b9bfdc05fc953f46ca39dd592309fb95a8b715..432466dc58da6220790bc5786e5603fc2fdc2a7b 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -52,6 +52,7 @@ EXPECT_BINS=\ unistd/fsync \ unistd/ftruncate \ unistd/getopt \ + unistd/isatty \ unistd/pipe \ unistd/rmdir \ unistd/sleep \ diff --git a/tests/expected/unistd/isatty.stderr b/tests/expected/unistd/isatty.stderr new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/expected/unistd/isatty.stdout b/tests/expected/unistd/isatty.stdout new file mode 100644 index 0000000000000000000000000000000000000000..83637aee6a3e3582d8186dbb6f2098de3727e06c --- /dev/null +++ b/tests/expected/unistd/isatty.stdout @@ -0,0 +1 @@ +Whatever a tty is, it's not me diff --git a/tests/unistd/isatty.c b/tests/unistd/isatty.c new file mode 100644 index 0000000000000000000000000000000000000000..9647282aa6a1fff298ea0273bf4d0c1396ec6fcf --- /dev/null +++ b/tests/unistd/isatty.c @@ -0,0 +1,11 @@ +#include <stdio.h> +#include <unistd.h> + +int main() { + // 1 is stdout + if (isatty(1)) { + puts("'Tis a tty :D"); + } else { + puts("Whatever a tty is, it's not me"); + } +}