Browse Source

Kind of get bash to compile

Doesn't link yet due to "multiple definitions of malloc", because some are supplied by some library of bash itself. Really odd.
jD91mZM2 6 years ago
parent
commit
44599a032e

+ 9 - 10
Cargo.lock

@@ -337,7 +337,6 @@ dependencies = [
  "pwd 0.1.0",
  "semaphore 0.1.0",
  "setjmp 0.1.0",
- "sgtty 0.1.0",
  "signal 0.1.0",
  "stdio 0.1.0",
  "stdlib 0.1.0",
@@ -354,6 +353,7 @@ dependencies = [
  "sys_un 0.1.0",
  "sys_utsname 0.1.0",
  "sys_wait 0.1.0",
+ "termios 0.1.0",
  "time 0.1.0",
  "unistd 0.1.0",
  "utime 0.1.0",
@@ -423,15 +423,6 @@ dependencies = [
 name = "setjmp"
 version = "0.1.0"
 
-[[package]]
-name = "sgtty"
-version = "0.1.0"
-dependencies = [
- "cbindgen 0.5.2",
- "platform 0.1.0",
- "sys_ioctl 0.1.0",
-]
-
 [[package]]
 name = "signal"
 version = "0.1.0"
@@ -643,6 +634,14 @@ dependencies = [
  "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "termios"
+version = "0.1.0"
+dependencies = [
+ "cbindgen 0.5.2",
+ "platform 0.1.0",
+]
+
 [[package]]
 name = "textwrap"
 version = "0.10.0"

+ 1 - 1
Cargo.toml

@@ -29,7 +29,6 @@ platform = { path = "src/platform" }
 pwd = { path = "src/pwd" }
 semaphore = { path = "src/semaphore" }
 setjmp = { path = "src/setjmp" }
-sgtty = { path = "src/sgtty" }
 signal = { path = "src/signal" }
 stdio = { path = "src/stdio" }
 stdlib = { path = "src/stdlib" }
@@ -46,6 +45,7 @@ sys_times = { path = "src/sys_times" }
 sys_un = { path = "src/sys_un" }
 sys_utsname = { path = "src/sys_utsname" }
 sys_wait = { path = "src/sys_wait" }
+termios = { path = "src/termios" }
 time = { path = "src/time" }
 unistd = { path = "src/unistd" }
 utime = { path = "src/utime" }

+ 1 - 0
include/bits/sys/stat.h

@@ -10,5 +10,6 @@
 
 #define st_atime st_atim.tv_sec
 #define st_mtime st_mtim.tv_sec
+#define st_ctime st_ctim.tv_sec
 
 #endif

+ 2 - 0
include/bits/unistd.h

@@ -1,6 +1,8 @@
 #ifndef _BITS_UNISTD_H
 #define _BITS_UNISTD_H
 
+#define _POSIX_VERSION 200809L
+
 int execl(const char *path, const char* argv0, ...);
 int execle(const char *path, const char* argv0, ...);
 

+ 1 - 1
src/lib.rs

@@ -19,7 +19,6 @@ pub extern crate netinet;
 pub extern crate pwd;
 pub extern crate semaphore;
 pub extern crate setjmp;
-pub extern crate sgtty;
 pub extern crate signal;
 pub extern crate stdio;
 pub extern crate stdlib;
@@ -36,6 +35,7 @@ pub extern crate sys_times;
 pub extern crate sys_un;
 pub extern crate sys_utsname;
 pub extern crate sys_wait;
+pub extern crate termios;
 pub extern crate time;
 pub extern crate unistd;
 pub extern crate utime;

+ 19 - 0
src/platform/src/linux/mod.rs

@@ -3,6 +3,10 @@ use core::{mem, ptr};
 use errno;
 use types::*;
 
+const EINVAL: c_int = 22;
+
+const TCGETS: c_ulong = 0x5401;
+const TCSETS: c_ulong = 0x5402;
 const TIOCGWINSZ: c_ulong = 0x5413;
 
 const AT_FDCWD: c_int = -100;
@@ -420,6 +424,21 @@ pub fn socketpair(domain: c_int, kind: c_int, protocol: c_int, socket_vector: *m
     e(unsafe { syscall!(SOCKETPAIR, domain, kind, protocol, socket_vector) }) as c_int
 }
 
+pub fn tcgetattr(fd: c_int, out: *mut termios) -> c_int {
+    ioctl(fd, TCGETS, out as *mut c_void)
+}
+
+pub fn tcsetattr(fd: c_int, act: c_int, value: *const termios) -> c_int {
+    if act < 0 || act > 2 {
+        unsafe {
+            errno = EINVAL;
+        }
+        return -1;
+    }
+    // This is safe because ioctl shouldn't modify the value
+    ioctl(fd, TCSETS + act as c_ulong, value as *mut c_void)
+}
+
 pub fn times(out: *mut tms) -> clock_t {
     unsafe { syscall!(TIMES, out) as clock_t }
 }

+ 36 - 0
src/platform/src/redox/mod.rs

@@ -992,6 +992,42 @@ pub fn socketpair(domain: c_int, kind: c_int, protocol: c_int, socket_vector: *m
     -1
 }
 
+pub fn tcgetattr(fd: c_int, out: *mut termios) -> c_int {
+    let dup = e(syscall::dup(fd as usize, b"termios"));
+    if dup == !0 {
+        return -1;
+    }
+
+    let read = e(syscall::read(dup, unsafe { slice::from_raw_parts_mut(
+        out as *mut u8,
+        mem::size_of::<termios>()
+    ) }));
+    let _ = syscall::close(dup);
+
+    if read == !0 {
+        return -1;
+    }
+    0
+}
+
+pub fn tcsetattr(fd: c_int, _act: c_int, value: *const termios) -> c_int {
+    let dup = e(syscall::dup(fd as usize, b"termios"));
+    if dup == !0 {
+        return -1;
+    }
+
+    let write = e(syscall::write(dup, unsafe { slice::from_raw_parts(
+        value as *const u8,
+        mem::size_of::<termios>()
+    ) }));
+    let _ = syscall::close(dup);
+
+    if write == !0 {
+        return -1;
+    }
+    0
+}
+
 pub fn times(out: *mut tms) -> clock_t {
     let _ = write!(FileWriter(2), "unimplemented: times({:p})", out);
     !0

+ 18 - 0
src/platform/src/types.rs

@@ -241,3 +241,21 @@ pub const F_OK: c_int = 0;
 pub const R_OK: c_int = 4;
 pub const W_OK: c_int = 2;
 pub const X_OK: c_int = 1;
+
+pub type cc_t = u8;
+pub type speed_t = u32;
+pub type tcflag_t = u32;
+
+pub const NCCS: usize = 32;
+
+#[repr(C)]
+pub struct termios {
+    c_iflag: tcflag_t,
+    c_oflag: tcflag_t,
+    c_cflag: tcflag_t,
+    c_lflag: tcflag_t,
+    c_line: cc_t,
+    c_cc: [cc_t; NCCS],
+    __c_ispeed: speed_t,
+    __c_ospeed: speed_t
+}

+ 10 - 0
src/termios/Cargo.toml

@@ -0,0 +1,10 @@
+[package]
+name = "termios"
+version = "0.1.0"
+authors = ["jD91mZM2 <[email protected]>"]
+
+[build-dependencies]
+cbindgen = { path = "../../cbindgen" }
+
+[dependencies]
+platform = { path = "../platform" }

+ 11 - 0
src/termios/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/termios.h");
+}

+ 7 - 0
src/termios/cbindgen.toml

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

+ 149 - 0
src/termios/src/lib.rs

@@ -0,0 +1,149 @@
+//! termios implementation, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/termios.h.html
+#![no_std]
+
+extern crate platform;
+
+use platform::types::*;
+
+pub type cc_t = u8;
+pub type speed_t = u32;
+pub type tcflag_t = u32;
+
+pub const NCCS: usize = 32;
+
+#[repr(C)]
+pub struct termios {
+    c_iflag: tcflag_t,
+    c_oflag: tcflag_t,
+    c_cflag: tcflag_t,
+    c_lflag: tcflag_t,
+    c_line: cc_t,
+    c_cc: [cc_t; NCCS],
+    __c_ispeed: speed_t,
+    __c_ospeed: speed_t
+}
+
+#[no_mangle]
+pub extern "C" fn tcgetattr(fd: c_int, out: *mut termios) -> c_int {
+    platform::tcgetattr(fd, out as *mut platform::types::termios)
+}
+
+#[no_mangle]
+pub extern "C" fn tcsetattr(fd: c_int, act: c_int, value: *mut termios) -> c_int {
+    platform::tcsetattr(fd, act, value as *mut platform::types::termios)
+}
+
+pub const VINTR: usize = 0;
+pub const VQUIT: usize = 1;
+pub const VERASE: usize = 2;
+pub const VKILL: usize = 3;
+pub const VEOF: usize = 4;
+pub const VTIME: usize = 5;
+pub const VMIN: usize = 6;
+pub const VSWTC: usize = 7;
+pub const VSTART: usize = 8;
+pub const VSTOP: usize = 9;
+pub const VSUSP: usize = 10;
+pub const VEOL: usize = 11;
+pub const VREPRINT: usize = 12;
+pub const VDISCARD: usize = 13;
+pub const VWERASE: usize = 14;
+pub const VLNEXT: usize = 15;
+pub const VEOL2: usize = 16;
+
+pub const IGNBRK: usize = 0o000001;
+pub const BRKINT: usize = 0o000002;
+pub const IGNPAR: usize = 0o000004;
+pub const PARMRK: usize = 0o000010;
+pub const INPCK: usize = 0o000020;
+pub const ISTRIP: usize = 0o000040;
+pub const INLCR: usize = 0o000100;
+pub const IGNCR: usize = 0o000200;
+pub const ICRNL: usize = 0o000400;
+pub const IUCLC: usize = 0o001000;
+pub const IXON: usize = 0o002000;
+pub const IXANY: usize = 0o004000;
+pub const IXOFF: usize = 0o010000;
+pub const IMAXBEL: usize = 0o020000;
+pub const IUTF8: usize = 0o040000;
+
+pub const OPOST: usize = 0o000001;
+pub const OLCUC: usize = 0o000002;
+pub const ONLCR: usize = 0o000004;
+pub const OCRNL: usize = 0o000010;
+pub const ONOCR: usize = 0o000020;
+pub const ONLRET: usize = 0o000040;
+pub const OFILL: usize = 0o000100;
+pub const OFDEL: usize = 0o000200;
+
+pub const VTDLY: usize = 0o040000;
+pub const VT0: usize = 0o000000;
+pub const VT1: usize = 0o040000;
+
+pub const B0: usize = 0o000000;
+pub const B50: usize = 0o000001;
+pub const B75: usize = 0o000002;
+pub const B110: usize = 0o000003;
+pub const B134: usize = 0o000004;
+pub const B150: usize = 0o000005;
+pub const B200: usize = 0o000006;
+pub const B300: usize = 0o000007;
+pub const B600: usize = 0o000010;
+pub const B1200: usize = 0o000011;
+pub const B1800: usize = 0o000012;
+pub const B2400: usize = 0o000013;
+pub const B4800: usize = 0o000014;
+pub const B9600: usize = 0o000015;
+pub const B19200: usize = 0o000016;
+pub const B38400: usize = 0o000017;
+
+pub const B57600: usize = 0o010001;
+pub const B115200: usize = 0o010002;
+pub const B230400: usize = 0o010003;
+pub const B460800: usize = 0o010004;
+pub const B500000: usize = 0o010005;
+pub const B576000: usize = 0o010006;
+pub const B921600: usize = 0o010007;
+pub const B1000000: usize = 0o010010;
+pub const B1152000: usize = 0o010011;
+pub const B1500000: usize = 0o010012;
+pub const B2000000: usize = 0o010013;
+pub const B2500000: usize = 0o010014;
+pub const B3000000: usize = 0o010015;
+pub const B3500000: usize = 0o010016;
+pub const B4000000: usize = 0o010017;
+
+pub const CSIZE: usize = 0o000060;
+pub const CS5: usize = 0o000000;
+pub const CS6: usize = 0o000020;
+pub const CS7: usize = 0o000040;
+pub const CS8: usize = 0o000060;
+pub const CSTOPB: usize = 0o000100;
+pub const CREAD: usize = 0o000200;
+pub const PARENB: usize = 0o000400;
+pub const PARODD: usize = 0o001000;
+pub const HUPCL: usize = 0o002000;
+pub const CLOCAL: usize = 0o004000;
+
+pub const ISIG: usize = 0o000001;
+pub const ICANON: usize = 0o000002;
+pub const ECHO: usize = 0o000010;
+pub const ECHOE: usize = 0o000020;
+pub const ECHOK: usize = 0o000040;
+pub const ECHONL: usize = 0o000100;
+pub const NOFLSH: usize = 0o000200;
+pub const TOSTOP: usize = 0o000400;
+pub const IEXTEN: usize = 0o100000;
+
+pub const TCOOFF: usize = 0;
+pub const TCOON: usize = 1;
+pub const TCIOFF: usize = 2;
+pub const TCION: usize = 3;
+
+pub const TCIFLUSH: usize = 0;
+pub const TCOFLUSH: usize = 1;
+pub const TCIOFLUSH: usize = 2;
+
+pub const TCSANOW: usize = 0;
+pub const TCSADRAIN: usize = 1;
+pub const TCSAFLUSH: usize = 2;

+ 1 - 1
src/time/src/lib.rs

@@ -287,7 +287,7 @@ pub unsafe extern "C" fn localtime_r(clock: *const time_t, t: *mut tm) -> *mut t
 }
 
 #[no_mangle]
-pub unsafe extern "C" fn mktime(t: *const tm) -> time_t {
+pub unsafe extern "C" fn mktime(t: *mut tm) -> time_t {
     let mut year = (*t).tm_year + 1900;
     let mut month = (*t).tm_mon;
     let mut day = (*t).tm_mday as i64 - 1;

+ 2 - 1
src/time/src/strftime.rs

@@ -120,7 +120,8 @@ pub unsafe fn strftime<W: Write>(
             b'P' => w!(if (*t).tm_hour < 12 { "am" } else { "pm" }),
             b'r' => w!(recurse "%I:%M:%S %p"),
             b'R' => w!(recurse "%H:%M"),
-            b's' => w!("{}", ::mktime(t)),
+            // Nothing is modified in mktime, but the C standard of course requires a mutable pointer ._.
+            b's' => w!("{}", ::mktime(t as *mut tm)),
             b'S' => w!("{:02}", (*t).tm_sec),
             b'T' => w!(recurse "%H:%M:%S"),
             b'u' => w!("{}", ((*t).tm_wday + 7 - 1) % 7 + 1),