Commit 019011f0 authored by jD91mZM2's avatar jD91mZM2

WIP env support

parent dc443a8c
Pipeline #683 failed with stages
in 8 minutes and 47 seconds
//! crt0
#![no_std]
#![feature(alloc)]
#![feature(asm)]
#![feature(linkage)]
#![feature(naked_functions)]
#![feature(panic_implementation)]
#![feature(lang_items)]
extern crate alloc;
extern crate platform;
use alloc::Vec;
use core::ptr;
use platform::types::*;
#[no_mangle]
......@@ -47,6 +51,10 @@ impl Stack {
fn argv(&self) -> *const *const u8 {
&self.argv0 as *const *const u8
}
fn envp(&self) -> *const *const u8 {
unsafe { self.argv().offset(self.argc() + 1) }
}
}
#[inline(never)]
......@@ -59,6 +67,28 @@ pub unsafe extern "C" fn _start_rust(sp: &'static Stack) -> ! {
let argc = sp.argc();
let argv = sp.argv();
let envp = sp.envp();
let mut len = 0;
while *envp.offset(len) != ptr::null() {
len += 1;
}
platform::inner_environ = Vec::with_capacity(len as usize + 1);
for i in 0..len {
let mut item = *envp.offset(i);
let mut len = 0;
while *item.offset(len) != 0 {
len += 1;
}
let buf = platform::alloc(len as usize + 1) as *mut c_char;
for i in 0..=len {
*buf.offset(i) = *item.offset(i) as c_char;
}
platform::inner_environ.push(buf);
}
platform::inner_environ.push(ptr::null_mut());
platform::environ = platform::inner_environ.as_mut_ptr();
platform::exit(main(argc, argv));
}
......
#![no_std]
#![allow(non_camel_case_types)]
#![feature(alloc)]
#![feature(allocator_api)]
#![feature(alloc, allocator_api, const_vec_new)]
//TODO #![feature(thread_local)]
#[cfg_attr(target_os = "redox", macro_use)]
......@@ -36,7 +35,8 @@ mod sys;
pub mod types;
use core::fmt;
use alloc::Vec;
use core::{fmt, ptr};
use types::*;
......@@ -64,6 +64,12 @@ pub struct sockaddr {
#[no_mangle]
pub static mut errno: c_int = 0;
#[allow(non_upper_case_globals)]
#[no_mangle]
pub static mut environ: *mut *mut c_char = ptr::null_mut();
#[allow(non_upper_case_globals)]
pub static mut inner_environ: Vec<*mut c_char> = Vec::new();
pub unsafe fn c_str_mut<'a>(s: *mut c_char) -> &'a mut [u8] {
use core::usize;
......
......@@ -260,9 +260,38 @@ pub extern "C" fn gcvt(value: c_double, ndigit: c_int, buf: *mut c_char) -> *mut
unimplemented!();
}
// #[no_mangle]
pub extern "C" fn getenv(name: *const c_char) -> *mut c_char {
unimplemented!();
unsafe fn find_env(name: *const c_char) -> Option<(usize, *mut c_char)> {
for (i, item) in platform::inner_environ.iter().enumerate() {
let mut item = *item;
if item == ptr::null_mut() {
assert_eq!(i, platform::inner_environ.len() - 1, "an early null pointer in environ vector");
break;
}
let mut name = name;
loop {
let end_of_name = *name == 0 || *name == b'=' as c_char;
if *item == 0 || *item == b'=' as c_char || end_of_name {
if *item == b'=' as c_char || end_of_name {
return Some((i, item.offset(1)));
} else {
break;
}
}
if *item != *name {
break;
}
item = item.offset(1);
name = name.offset(1);
}
}
None
}
#[no_mangle]
pub unsafe extern "C" fn getenv(name: *const c_char) -> *mut c_char {
find_env(name).map(|val| val.1).unwrap_or(ptr::null_mut())
}
// #[no_mangle]
......@@ -443,9 +472,42 @@ pub extern "C" fn ptsname(fildes: c_int) -> *mut c_char {
unimplemented!();
}
// #[no_mangle]
pub extern "C" fn putenv(s: *mut c_char) -> c_int {
unimplemented!();
#[no_mangle]
pub unsafe extern "C" fn putenv(s: *mut c_char) -> c_int {
let mut s_len = 0;
while *s.offset(s_len) != 0 {
s_len += 1;
}
let ptr;
if let Some((i, _)) = find_env(s) {
let mut item = platform::inner_environ[i];
let mut item_len = 0;
while *item.offset(item_len) != 0 {
item_len += 1;
}
if item_len > s_len {
ptr = item;
} else {
platform::free(item as *mut c_void);
ptr = platform::alloc(s_len as usize + 1) as *mut c_char;
platform::inner_environ[i] = ptr;
}
} else {
ptr = platform::alloc(s_len as usize + 1) as *mut c_char;
let i = platform::inner_environ.len() - 1;
assert_eq!(platform::inner_environ[i], ptr::null_mut(), "last element in environ vector was not null");
platform::inner_environ[i] = ptr;
platform::inner_environ.push(ptr::null_mut());
platform::environ = platform::inner_environ.as_mut_ptr();
}
for i in 0..=s_len {
*ptr.offset(i) = *s.offset(i);
}
0
}
#[no_mangle]
......
......@@ -41,9 +41,6 @@ pub const STDIN_FILENO: c_int = 0;
pub const STDOUT_FILENO: c_int = 1;
pub const STDERR_FILENO: c_int = 2;
#[no_mangle]
pub static mut environ: *mut *mut c_char = ptr::null_mut();
#[no_mangle]
pub extern "C" fn _exit(status: c_int) {
platform::exit(status)
......@@ -125,7 +122,7 @@ pub extern "C" fn encrypt(block: [c_char; 64], edflag: c_int) {
#[no_mangle]
pub unsafe extern "C" fn execv(path: *const c_char, argv: *const *mut c_char) -> c_int {
execve(path, argv, environ)
execve(path, argv, platform::environ)
}
#[no_mangle]
......
# Automatically generated by 'make ignore'
/*.out
/gen/
alloc
args
asctime
assert
atof
atoi
brk
args
chdir
create
ctype
dup
env
error
exec
fchdir
......@@ -16,6 +20,10 @@ fcntl
fsync
ftruncate
getc_unget
gethostname
getid
gmtime
link
locale
localtime
math
......@@ -26,43 +34,36 @@ printf
rename
rmdir
scanf
setid
setjmp
sleep
sprintf
strings
stdio/fwrite
stdio/all
stdio/freopen
stdlib/strtol
stdlib/strtoul
stdio/fwrite
stdlib/a64l
stdlib/bsearch
stdlib/mktemp
stdlib/rand
string/strncmp
string/strcspn
stdlib/strtol
stdlib/strtoul
string/strchr
string/strcspn
string/strncmp
string/strpbrk
string/strrchr
string/strspn
string/strstr
string/strpbrk
string/strtok
string/strtok_r
strings
system
time
unistd/getopt
unlink
waitpid
wchar/mbrtowc
wchar/mbsrtowcs
wchar/putwchar
wchar/wcrtomb
write
time
gmtime
asctime
alloc
chdir
gethostname
getid
link
setid
stdlib/bsearch
stdlib/mktemp
unlink
......@@ -8,6 +8,7 @@ EXPECT_BINS=\
create \
ctype \
dup \
env \
error \
exec \
fchdir \
......
#include <stdio.h>
#include <stdlib.h>
int main() {
puts(getenv("SHELL"));
puts(getenv("CC"));
putenv("KEK=lol");
puts(getenv("KEK"));
}
/nix/store/zqh3l3lyw32q1ayb15bnvg9f24j5v2p0-bash-4.4-p12/bin/bash
gcc
lol
//http://www2.cs.uregina.ca/~hamilton/courses/330/notes/unix/pipes/pipes.html
#include <stdio.h>
#include <string.h>
#include <unistd.h>
......@@ -14,19 +15,25 @@ int main()
pid = fork();
if (pid == 0) /* child : sends message to parent*/
{
puts("Child: Close Read");
/* close read end */
close(pip[0]);
puts("Child: Write");
/* send 7 characters in the string, including end-of-string */
write(pip[1], outstring, strlen(outstring));
puts("Child: Close Write");
/* close write end */
close(pip[1]);
}
else /* parent : receives message from child */
{
puts("Parent: Close Write");
/* close write end */
close(pip[1]);
puts("Parent: Read");
/* read from the pipe */
read(pip[0], instring, 7);
puts("Parent: Close Read");
/* close read end */
close(pip[0]);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment