浏览代码

Implement isatty

jD91mZM2 6 年之前
父节点
当前提交
2bf426b0fb

+ 10 - 1
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]]

+ 1 - 0
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" }

+ 11 - 0
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))

+ 2 - 1
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;

+ 1 - 0
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;

+ 4 - 0
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
 }

+ 10 - 0
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" }

+ 11 - 0
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");
+}

+ 7 - 0
src/sys_ioctl/cbindgen.toml

@@ -0,0 +1,7 @@
+sys_includes = []
+include_guard = "_IOCTL_H"
+language = "C"
+style = "Tag"
+
+[enum]
+prefix_with_name = true

+ 216 - 0
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::*;

+ 1 - 1
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" }

+ 1 - 2
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],

+ 1 - 1
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" }

+ 6 - 7
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]

+ 1 - 0
tests/.gitignore

@@ -53,6 +53,7 @@ unistd/fchdir
 unistd/fsync
 unistd/ftruncate
 unistd/getopt
+unistd/isatty
 unistd/pipe
 unistd/rmdir
 unistd/sleep

+ 1 - 0
tests/Makefile

@@ -52,6 +52,7 @@ EXPECT_BINS=\
 	unistd/fsync \
 	unistd/ftruncate \
 	unistd/getopt \
+	unistd/isatty \
 	unistd/pipe \
 	unistd/rmdir \
 	unistd/sleep \

+ 0 - 0
tests/expected/unistd/isatty.stderr


+ 1 - 0
tests/expected/unistd/isatty.stdout

@@ -0,0 +1 @@
+Whatever a tty is, it's not me

+ 11 - 0
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");
+    }
+}