|  | #pragma once | 
|  |  | 
|  | #include <ros/bits/syscall.h> | 
|  | #include <ros/arch/syscall.h> | 
|  | #include <ros/event.h> | 
|  | #include <ros/atomic.h> | 
|  |  | 
|  | /* Flags for an individual syscall. */ | 
|  | #define SC_DONE			0x0001	/* SC is done */ | 
|  | #define SC_PROGRESS		0x0002	/* SC made progress */ | 
|  | #define SC_UEVENT		0x0004	/* user has an ev_q */ | 
|  | #define SC_K_LOCK		0x0008	/* kernel locked sysc */ | 
|  | #define SC_ABORT		0x0010	/* syscall abort attempted */ | 
|  |  | 
|  | #define MAX_ERRSTR_LEN		128 | 
|  | #define SYSTR_BUF_SZ		PGSIZE | 
|  |  | 
|  | struct syscall { | 
|  | unsigned int			num; | 
|  | int				err;		/* errno */ | 
|  | long				retval; | 
|  | atomic_t			flags; | 
|  | struct event_queue		*ev_q; | 
|  | void				*u_data; | 
|  | long				arg0; | 
|  | long				arg1; | 
|  | long				arg2; | 
|  | long				arg3; | 
|  | long				arg4; | 
|  | long				arg5; | 
|  | char				errstr[MAX_ERRSTR_LEN]; | 
|  | }; | 
|  |  | 
|  | static inline bool syscall_retval_is_error(unsigned int sysc_nr, long retval) | 
|  | { | 
|  | switch (sysc_nr) { | 
|  | case SYS_getpcoreid: | 
|  | case SYS_getvcoreid: | 
|  | case SYS_reboot: | 
|  | case SYS_proc_yield: | 
|  | case SYS_vc_entry: | 
|  | case SYS_umask: | 
|  | case SYS_init_arsc: | 
|  | return false; | 
|  | case SYS_abort_sysc: | 
|  | case SYS_abort_sysc_fd: | 
|  | /* These two are a little weird */ | 
|  | return false; | 
|  | case SYS_null: | 
|  | case SYS_block: | 
|  | case SYS_nanosleep: | 
|  | case SYS_cache_invalidate: | 
|  | case SYS_proc_run: | 
|  | case SYS_proc_destroy: | 
|  | case SYS_exec: | 
|  | case SYS_munmap: | 
|  | case SYS_mprotect: | 
|  | case SYS_notify: | 
|  | case SYS_self_notify: | 
|  | case SYS_send_event: | 
|  | case SYS_halt_core: | 
|  | case SYS_pop_ctx: | 
|  | case SYS_vmm_poke_guest: | 
|  | case SYS_poke_ksched: | 
|  | case SYS_llseek: | 
|  | case SYS_close: | 
|  | case SYS_fstat: | 
|  | case SYS_stat: | 
|  | case SYS_lstat: | 
|  | case SYS_access: | 
|  | case SYS_link: | 
|  | case SYS_unlink: | 
|  | case SYS_symlink: | 
|  | case SYS_chdir: | 
|  | case SYS_fchdir: | 
|  | case SYS_mkdir: | 
|  | case SYS_rmdir: | 
|  | case SYS_tcgetattr: | 
|  | case SYS_tcsetattr: | 
|  | case SYS_setuid: | 
|  | case SYS_setgid: | 
|  | case SYS_rename: | 
|  | case SYS_nunmount: | 
|  | case SYS_fd2path: | 
|  | return retval != 0; | 
|  | case SYS_proc_create: | 
|  | case SYS_change_vcore: | 
|  | case SYS_fork: | 
|  | case SYS_waitpid: | 
|  | case SYS_shared_page_alloc: | 
|  | case SYS_shared_page_free: | 
|  | case SYS_provision: | 
|  | case SYS_change_to_m: | 
|  | case SYS_vmm_ctl: | 
|  | case SYS_read: | 
|  | case SYS_write: | 
|  | case SYS_openat: | 
|  | case SYS_fcntl: | 
|  | case SYS_readlink: | 
|  | case SYS_getcwd: | 
|  | case SYS_nbind: | 
|  | case SYS_nmount: | 
|  | case SYS_wstat: | 
|  | case SYS_fwstat: | 
|  | return retval < 0; | 
|  | case SYS_mmap: | 
|  | return retval == -1; /* MAP_FAILED */ | 
|  | case SYS_vmm_add_gpcs: | 
|  | case SYS_populate_va: | 
|  | case SYS_dup_fds_to: | 
|  | case SYS_tap_fds: | 
|  | return retval <= 0; | 
|  | }; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | struct childfdmap { | 
|  | unsigned int			parentfd; | 
|  | unsigned int			childfd; | 
|  | int				ok; | 
|  | }; | 
|  |  | 
|  | struct argenv { | 
|  | size_t argc; | 
|  | size_t envc; | 
|  | char buf[]; | 
|  | /* The buf array is laid out as follows: | 
|  | * buf { | 
|  | *   char *argv[argc]; // Offset of arg relative to &argbuf[0] | 
|  | *   char *envp[envc]; // Offset of envvar relative to &argbuf[0] | 
|  | *   char argbuf[sum(map(strlen + 1, argv + envp))]; | 
|  | * } | 
|  | */ | 
|  | }; | 
|  |  | 
|  | #ifndef ROS_KERNEL | 
|  |  | 
|  | /* Temp hack, til the rest of glibc/userspace uses sys/syscall.h */ | 
|  | #include <sys/syscall.h> | 
|  | #endif /* ifndef ROS_KERNEL */ |