Update libstd. Add CWD and associated syscalls. Remove debugging
This commit is contained in:
		
							parent
							
								
									7561839cfc
								
							
						
					
					
						commit
						57f5699664
					
				
					 12 changed files with 113 additions and 12 deletions
				
			
		
							
								
								
									
										3
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							|  | @ -7,3 +7,6 @@ | |||
| [submodule "ralloc"] | ||||
| 	path = ralloc | ||||
| 	url = https://github.com/redox-os/ralloc | ||||
| [submodule "ion"] | ||||
| 	path = ion | ||||
| 	url = https://github.com/redox-os/ion.git | ||||
|  |  | |||
							
								
								
									
										13
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -12,9 +12,9 @@ KCARGOFLAGS=--target $(KTARGET).json -- -C soft-float | |||
| TARGET=$(ARCH)-unknown-redox | ||||
| BUILD=build/userspace | ||||
| RUSTC=./rustc.sh | ||||
| RUSTCFLAGS=--target $(TARGET).json -O -C soft-float --cfg redox | ||||
| RUSTCFLAGS=--target $(TARGET).json -C soft-float --cfg redox | ||||
| CARGO=RUSTC="$(RUSTC)" cargo | ||||
| CARGOFLAGS=--target $(TARGET).json -- -O -C soft-float --cfg redox | ||||
| CARGOFLAGS=--target $(TARGET).json -- -C soft-float --cfg redox | ||||
| 
 | ||||
| # Default targets
 | ||||
| .PHONY: all clean qemu bochs FORCE | ||||
|  | @ -25,6 +25,7 @@ clean: | |||
| 	cargo clean | ||||
| 	cargo clean --manifest-path libstd/Cargo.toml | ||||
| 	cargo clean --manifest-path init/Cargo.toml | ||||
| 	cargo clean --manifest-path ion/Cargo.toml | ||||
| 	cargo clean --manifest-path drivers/pcid/Cargo.toml | ||||
| 	rm -rf build | ||||
| 
 | ||||
|  | @ -93,7 +94,7 @@ $(KBUILD)/librustc_unicode.rlib: rust/src/librustc_unicode/lib.rs $(KBUILD)/libc | |||
| $(KBUILD)/libcollections.rlib: rust/src/libcollections/lib.rs $(KBUILD)/libcore.rlib $(KBUILD)/liballoc.rlib $(KBUILD)/librustc_unicode.rlib | ||||
| 	$(KRUSTC) $(KRUSTCFLAGS) -o $@ $< | ||||
| 
 | ||||
| $(KBUILD)/libkernel.a: kernel/** $(KBUILD)/libcore.rlib $(KBUILD)/liballoc.rlib $(KBUILD)/libcollections.rlib $(BUILD)/init $(BUILD)/pcid FORCE | ||||
| $(KBUILD)/libkernel.a: kernel/** $(KBUILD)/libcore.rlib $(KBUILD)/liballoc.rlib $(KBUILD)/libcollections.rlib $(BUILD)/initfs.rs FORCE | ||||
| 	$(KCARGO) rustc $(KCARGOFLAGS) -o $@ | ||||
| 
 | ||||
| $(KBUILD)/kernel: $(KBUILD)/libkernel.a | ||||
|  | @ -124,6 +125,12 @@ $(BUILD)/init: init/Cargo.toml init/src/*.rs $(BUILD)/libstd.rlib | |||
| 	$(CARGO) rustc --manifest-path $< $(CARGOFLAGS) -o $@ | ||||
| 	strip $@ | ||||
| 
 | ||||
| $(BUILD)/ion: ion/Cargo.toml ion/src/*.rs $(BUILD)/libstd.rlib | ||||
| 	$(CARGO) rustc --manifest-path $< $(CARGOFLAGS) -o $@ | ||||
| 	strip $@ | ||||
| 
 | ||||
| $(BUILD)/pcid: drivers/pcid/Cargo.toml drivers/pcid/src/** $(BUILD)/libstd.rlib | ||||
| 	$(CARGO) rustc --manifest-path $< $(CARGOFLAGS) -o $@ | ||||
| 	strip $@ | ||||
| 
 | ||||
| $(BUILD)/initfs.rs: $(BUILD)/init $(BUILD)/ion $(BUILD)/pcid | ||||
|  |  | |||
							
								
								
									
										1
									
								
								ion
									
										
									
									
									
										Submodule
									
								
							
							
						
						
									
										1
									
								
								ion
									
										
									
									
									
										Submodule
									
								
							|  | @ -0,0 +1 @@ | |||
| Subproject commit cbb3c3003f654d09cd3b3cf1a179469bb1b558b3 | ||||
|  | @ -33,6 +33,8 @@ pub struct Context { | |||
|     pub heap: Option<SharedMemory>, | ||||
|     /// User stack
 | ||||
|     pub stack: Option<Memory>, | ||||
|     /// The current working directory
 | ||||
|     pub cwd: Arc<Mutex<Vec<u8>>>, | ||||
|     /// The open files in the scheme
 | ||||
|     pub files: Arc<Mutex<Vec<Option<File>>>> | ||||
| } | ||||
|  | @ -49,10 +51,46 @@ impl Context { | |||
|             image: Vec::new(), | ||||
|             heap: None, | ||||
|             stack: None, | ||||
|             cwd: Arc::new(Mutex::new(Vec::new())), | ||||
|             files: Arc::new(Mutex::new(Vec::new())) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn canonicalize(&self, path: &[u8]) -> Vec<u8> { | ||||
|         if path.iter().position(|&b| b == b':').is_none() { | ||||
|             let cwd = self.cwd.lock(); | ||||
|             if path == b"." { | ||||
|                 cwd.clone() | ||||
|             } else if path == b".." { | ||||
|                 cwd[..cwd[..cwd.len() - 1] | ||||
|                                    .iter().rposition(|&b| b == b'/') | ||||
|                                    .map_or(cwd.len(), |i| i + 1)] | ||||
|                    .to_vec() | ||||
|             } else if path.starts_with(b"./") { | ||||
|                 let mut canon = cwd.clone(); | ||||
|                 canon.extend_from_slice(&path[2..]); | ||||
|                 canon | ||||
|             } else if path.starts_with(b"../") { | ||||
|                 let mut canon = cwd[..cwd[..cwd.len() - 1] | ||||
|                                    .iter().rposition(|&b| b == b'/') | ||||
|                                    .map_or(cwd.len(), |i| i + 1)] | ||||
|                    .to_vec(); | ||||
|                 canon.extend_from_slice(&path[3..]); | ||||
|                 canon | ||||
|             } else if path.starts_with(b"/") { | ||||
|                 let mut canon = cwd[..cwd.iter().position(|&b| b == b':').map_or(1, |i| i + 1)].to_vec(); | ||||
|                 canon.extend_from_slice(&path); | ||||
|                 canon | ||||
|             } else { | ||||
|                 let mut canon = cwd.clone(); | ||||
|                 canon.extend_from_slice(&path); | ||||
|                 canon | ||||
|             } | ||||
|         } else { | ||||
|             path.to_vec() | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Add a file to the lowest available slot.
 | ||||
|     /// Return the file descriptor number or None if no slot was found
 | ||||
|     pub fn add_file(&mut self, file: File) -> Option<usize> { | ||||
|  |  | |||
|  | @ -128,6 +128,8 @@ pub fn cpu_id() -> usize { | |||
| } | ||||
| 
 | ||||
| pub extern fn userspace_init() { | ||||
|     assert_eq!(syscall::chdir(b"initfs:"), Ok(0)); | ||||
| 
 | ||||
|     assert_eq!(syscall::open(b"debug:", 0), Ok(0)); | ||||
|     assert_eq!(syscall::open(b"debug:", 0), Ok(1)); | ||||
|     assert_eq!(syscall::open(b"debug:", 0), Ok(2)); | ||||
|  |  | |||
|  | @ -19,8 +19,9 @@ impl InitFsScheme { | |||
|         let mut files: BTreeMap<&'static [u8], &'static [u8]> = BTreeMap::new(); | ||||
| 
 | ||||
|         files.insert(b"bin/init", include_bytes!("../../build/userspace/init")); | ||||
|         files.insert(b"bin/ion", include_bytes!("../../build/userspace/ion")); | ||||
|         files.insert(b"bin/pcid", include_bytes!("../../build/userspace/pcid")); | ||||
|         files.insert(b"etc/init.rc", b"echo testing\ninitfs:bin/pcid\n"); | ||||
|         files.insert(b"etc/init.rc", b"echo testing\ninitfs:bin/pcid\ninitfs:bin/ion"); | ||||
| 
 | ||||
|         InitFsScheme { | ||||
|             next_id: 0, | ||||
|  |  | |||
|  | @ -19,6 +19,8 @@ pub enum Call { | |||
|     WaitPid = 7, | ||||
|     /// Execute syscall
 | ||||
|     Exec = 11, | ||||
|     /// Change working directory
 | ||||
|     ChDir = 12, | ||||
|     /// Get process ID
 | ||||
|     GetPid = 20, | ||||
|     /// Duplicate file descriptor
 | ||||
|  | @ -30,12 +32,15 @@ pub enum Call { | |||
|     /// Clone process
 | ||||
|     Clone = 120, | ||||
|     /// Yield to scheduler
 | ||||
|     SchedYield = 158 | ||||
|     SchedYield = 158, | ||||
|     /// Get process working directory
 | ||||
|     GetCwd = 183 | ||||
| } | ||||
| 
 | ||||
| /// Convert numbers to calls
 | ||||
| /// See http://syscalls.kernelgrok.com/
 | ||||
| impl Call { | ||||
|     //TODO: Return Option<Call>
 | ||||
|     pub fn from(number: usize) -> Result<Call> { | ||||
|         match number { | ||||
|             1 => Ok(Call::Exit), | ||||
|  | @ -45,12 +50,14 @@ impl Call { | |||
|             6 => Ok(Call::Close), | ||||
|             7 => Ok(Call::WaitPid), | ||||
|             11 => Ok(Call::Exec), | ||||
|             12 => Ok(Call::ChDir), | ||||
|             20 => Ok(Call::GetPid), | ||||
|             41 => Ok(Call::Dup), | ||||
|             45 => Ok(Call::Brk), | ||||
|             110 => Ok(Call::Iopl), | ||||
|             120 => Ok(Call::Clone), | ||||
|             158 => Ok(Call::SchedYield), | ||||
|             183 => Ok(Call::GetCwd), | ||||
|             _ => Err(Error::NoCall) | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -5,6 +5,28 @@ use scheme; | |||
| 
 | ||||
| use super::{Error, Result}; | ||||
| 
 | ||||
| pub fn chdir(path: &[u8]) -> Result<usize> { | ||||
|     let contexts = context::contexts(); | ||||
|     let context_lock = contexts.current().ok_or(Error::NoProcess)?; | ||||
|     let context = context_lock.read(); | ||||
|     let canonical = context.canonicalize(path); | ||||
|     *context.cwd.lock() = canonical; | ||||
|     Ok(0) | ||||
| } | ||||
| 
 | ||||
| pub fn getcwd(buf: &mut [u8]) -> Result<usize> { | ||||
|     let contexts = context::contexts(); | ||||
|     let context_lock = contexts.current().ok_or(Error::NoProcess)?; | ||||
|     let context = context_lock.read(); | ||||
|     let cwd = context.cwd.lock(); | ||||
|     let mut i = 0; | ||||
|     while i < buf.len() && i < cwd.len() { | ||||
|         buf[i] = cwd[i]; | ||||
|         i += 1; | ||||
|     } | ||||
|     Ok(i) | ||||
| } | ||||
| 
 | ||||
| /// Read syscall
 | ||||
| pub fn read(fd: usize, buf: &mut [u8]) -> Result<usize> { | ||||
|     let file = { | ||||
|  |  | |||
|  | @ -34,12 +34,14 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize | |||
|                 Call::Close => close(b), | ||||
|                 Call::WaitPid => waitpid(b, c, d), | ||||
|                 Call::Exec => exec(validate_slice(b as *const u8, c)?, validate_slice(d as *const [usize; 2], e)?), | ||||
|                 Call::ChDir => chdir(validate_slice(b as *const u8, c)?), | ||||
|                 Call::GetPid => getpid(), | ||||
|                 Call::Dup => dup(b), | ||||
|                 Call::Brk => brk(b), | ||||
|                 Call::Iopl => iopl(b), | ||||
|                 Call::Clone => clone(b, stack), | ||||
|                 Call::SchedYield => sched_yield() | ||||
|                 Call::SchedYield => sched_yield(), | ||||
|                 Call::GetCwd => getcwd(validate_slice_mut(b as *mut u8, c)?) | ||||
|             }, | ||||
|             Err(err) => { | ||||
|                 println!("Unknown syscall {}", a); | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| ///! Process syscalls
 | ||||
| 
 | ||||
| use alloc::arc::Arc; | ||||
| use collections::Vec; | ||||
| use core::mem; | ||||
| use core::str; | ||||
| use spin::Mutex; | ||||
|  | @ -53,7 +54,9 @@ pub const CLONE_FILES: usize = 0x400; | |||
| pub const CLONE_VFORK: usize = 0x4000; | ||||
| pub fn clone(flags: usize, stack_base: usize) -> Result<usize> { | ||||
|     //TODO: Copy on write?
 | ||||
|     println!("Clone {:X}: {:X}", flags, stack_base); | ||||
| 
 | ||||
|     // vfork not supported
 | ||||
|     assert!(flags & CLONE_VFORK == 0); | ||||
| 
 | ||||
|     let ppid; | ||||
|     let pid; | ||||
|  | @ -64,7 +67,8 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> { | |||
|         let mut image = vec![]; | ||||
|         let mut heap_option = None; | ||||
|         let mut stack_option = None; | ||||
|         let mut files = Arc::new(Mutex::new(vec![])); | ||||
|         let cwd; | ||||
|         let files; | ||||
| 
 | ||||
|         // Copy from old process
 | ||||
|         { | ||||
|  | @ -159,9 +163,16 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> { | |||
|                 stack_option = Some(new_stack); | ||||
|             } | ||||
| 
 | ||||
|             if flags & CLONE_FS == CLONE_FS { | ||||
|                 cwd = context.cwd.clone(); | ||||
|             } else { | ||||
|                 cwd = Arc::new(Mutex::new(context.cwd.lock().clone())); | ||||
|             } | ||||
| 
 | ||||
|             if flags & CLONE_FILES == CLONE_FILES { | ||||
|                 files = context.files.clone(); | ||||
|             } else { | ||||
|                 let mut files_vec = Vec::new(); | ||||
|                 for (fd, file_option) in context.files.lock().iter().enumerate() { | ||||
|                     if let Some(file) = *file_option { | ||||
|                         let result = { | ||||
|  | @ -172,16 +183,17 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> { | |||
|                         }; | ||||
|                         match result { | ||||
|                             Ok(new_number) => { | ||||
|                                 files.lock().push(Some(context::file::File { scheme: file.scheme, number: new_number })); | ||||
|                                 files_vec.push(Some(context::file::File { scheme: file.scheme, number: new_number })); | ||||
|                             }, | ||||
|                             Err(err) => { | ||||
|                                 println!("clone: failed to dup {}: {:?}", fd, err); | ||||
|                             } | ||||
|                         } | ||||
|                     } else { | ||||
|                         files.lock().push(None); | ||||
|                         files_vec.push(None); | ||||
|                     } | ||||
|                 } | ||||
|                 files = Arc::new(Mutex::new(files_vec)); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -289,6 +301,8 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> { | |||
|                 context.stack = Some(stack); | ||||
|             } | ||||
| 
 | ||||
|             context.cwd = cwd; | ||||
| 
 | ||||
|             context.files = files; | ||||
| 
 | ||||
|             context.arch.set_page_table(unsafe { new_table.address() }); | ||||
|  | @ -322,7 +336,6 @@ pub fn exec(path: &[u8], _args: &[[usize; 2]]) -> Result<usize> { | |||
|     //TODO: Use args
 | ||||
|     //TODO: Unmap previous mappings
 | ||||
|     //TODO: Drop data vec
 | ||||
|     println!("Exec {}", unsafe { str::from_utf8_unchecked(path) }); | ||||
| 
 | ||||
|     let file = syscall::open(path, 0)?; | ||||
|     let mut data = vec![]; | ||||
|  |  | |||
							
								
								
									
										2
									
								
								libstd
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								libstd
									
										
									
									
									
								
							|  | @ -1 +1 @@ | |||
| Subproject commit 00920975234a9bc774ad6e33efd57a56a40c0ee8 | ||||
| Subproject commit 3483097e4f5172fe8b4cbe0dee868d18201c12f8 | ||||
|  | @ -48,6 +48,7 @@ pub const SYS_FUTEX: usize = 240; | |||
|     pub const FUTEX_WAIT: usize = 0; | ||||
|     pub const FUTEX_WAKE: usize = 1; | ||||
|     pub const FUTEX_REQUEUE: usize = 2; | ||||
| pub const SYS_GETCWD: usize = 183; | ||||
| pub const SYS_GETPID: usize = 20; | ||||
| pub const SYS_IOPL: usize = 110; | ||||
| pub const SYS_LINK: usize = 9; | ||||
|  | @ -153,6 +154,10 @@ pub unsafe fn futex(addr: *mut i32, op: usize, val: i32, val2: usize, addr2: *mu | |||
|     syscall5(SYS_FUTEX, addr as usize, op, (val as isize) as usize, val2, addr2 as usize) | ||||
| } | ||||
| 
 | ||||
| pub fn getcwd(buf: &mut [u8]) -> Result<usize> { | ||||
|     unsafe { syscall2(SYS_GETCWD, buf.as_mut_ptr() as usize, buf.len()) } | ||||
| } | ||||
| 
 | ||||
| pub fn getpid() -> Result<usize> { | ||||
|     unsafe { syscall0(SYS_GETPID) } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jeremy Soller
						Jeremy Soller