Просмотр исходного кода

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 лет назад
Родитель
Сommit
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 <me@krake.one>"]
+
+[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),