📄 emul_unix.c
字号:
#else target.st_blocks = 0;#endif target.st_atimx = H2T_4(host->st_atime); target.st_ctimx = H2T_4(host->st_ctime); target.st_mtimx = H2T_4(host->st_mtime); target.__unused1 = 0; target.__unused2 = 0; target.__unused3 = 0; target.__unused4 = 0; target.__unused5 = 0; emul_write_buffer(&target, addr, sizeof(target), processor, cia);}#endif /* HAVE_SYS_STAT_H */#ifndef HAVE_STAT#define do_linux_stat 0#elsestatic voiddo_linux_stat(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; unsigned_word stat_pkt = cpu_registers(processor)->gpr[arg0+1]; char path_buf[PATH_MAX]; struct stat buf; char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0x%lx [%s], 0x%lx", (long)path_addr, path, (long)stat_pkt); status = stat (path, &buf); if (status == 0) convert_to_linux_stat (stat_pkt, &buf, processor, cia); emul_write_status(processor, status, errno);}#endif#ifndef HAVE_LSTAT#define do_linux_lstat 0#elsestatic voiddo_linux_lstat(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; unsigned_word stat_pkt = cpu_registers(processor)->gpr[arg0+1]; char path_buf[PATH_MAX]; struct stat buf; char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0x%lx [%s], 0x%lx", (long)path_addr, path, (long)stat_pkt); status = lstat (path, &buf); if (status == 0) convert_to_linux_stat (stat_pkt, &buf, processor, cia); emul_write_status(processor, status, errno);}#endif#ifndef HAVE_FSTAT#define do_linux_fstat 0#elsestatic voiddo_linux_fstat(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ int fildes = (int)cpu_registers(processor)->gpr[arg0]; unsigned_word stat_pkt = cpu_registers(processor)->gpr[arg0+1]; struct stat buf; int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%d, 0x%lx", fildes, (long)stat_pkt); status = fstat (fildes, &buf); if (status == 0) convert_to_linux_stat (stat_pkt, &buf, processor, cia); emul_write_status(processor, status, errno);}#endif#if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE)#define LINUX_NCC 10#define LINUX_NCCS 19 #define LINUX_VINTR 0#define LINUX_VQUIT 1#define LINUX_VERASE 2#define LINUX_VKILL 3#define LINUX_VEOF 4#define LINUX_VMIN 5#define LINUX_VEOL 6#define LINUX_VTIME 7#define LINUX_VEOL2 8#define LINUX_VSWTC 9#define LINUX_VWERASE 10#define LINUX_VREPRINT 11#define LINUX_VSUSP 12#define LINUX_VSTART 13#define LINUX_VSTOP 14#define LINUX_VLNEXT 15#define LINUX_VDISCARD 16 #define LINUX_IOC_NRBITS 8#define LINUX_IOC_TYPEBITS 8#define LINUX_IOC_SIZEBITS 13#define LINUX_IOC_DIRBITS 3#define LINUX_IOC_NRMASK ((1 << LINUX_IOC_NRBITS)-1)#define LINUX_IOC_TYPEMASK ((1 << LINUX_IOC_TYPEBITS)-1)#define LINUX_IOC_SIZEMASK ((1 << LINUX_IOC_SIZEBITS)-1)#define LINUX_IOC_DIRMASK ((1 << LINUX_IOC_DIRBITS)-1)#define LINUX_IOC_NRSHIFT 0#define LINUX_IOC_TYPESHIFT (LINUX_IOC_NRSHIFT+LINUX_IOC_NRBITS)#define LINUX_IOC_SIZESHIFT (LINUX_IOC_TYPESHIFT+LINUX_IOC_TYPEBITS)#define LINUX_IOC_DIRSHIFT (LINUX_IOC_SIZESHIFT+LINUX_IOC_SIZEBITS)/* * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit. * And this turns out useful to catch old ioctl numbers in header * files for us. */#define LINUX_IOC_NONE 1U#define LINUX_IOC_READ 2U#define LINUX_IOC_WRITE 4U#define LINUX_IOC(dir,type,nr,size) \ (((dir) << LINUX_IOC_DIRSHIFT) | \ ((type) << LINUX_IOC_TYPESHIFT) | \ ((nr) << LINUX_IOC_NRSHIFT) | \ ((size) << LINUX_IOC_SIZESHIFT))/* used to create numbers */#define LINUX_IO(type,nr) LINUX_IOC(LINUX_IOC_NONE,(type),(nr),0)#define LINUX_IOR(type,nr,size) LINUX_IOC(LINUX_IOC_READ,(type),(nr),sizeof(size))#define LINUX_IOW(type,nr,size) LINUX_IOC(LINUX_IOC_WRITE,(type),(nr),sizeof(size))#define LINUX_IOWR(type,nr,size) LINUX_IOC(LINUX_IOC_READ|LINUX_IOC_WRITE,(type),(nr),sizeof(size))#endif#if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE)/* Convert to/from host termio structure */struct linux_termio { unsigned16 c_iflag; /* input modes */ unsigned16 c_oflag; /* output modes */ unsigned16 c_cflag; /* control modes */ unsigned16 c_lflag; /* line discipline modes */ unsigned8 c_line; /* line discipline */ unsigned8 c_cc[LINUX_NCC]; /* control chars */};STATIC_INLINE_EMUL_UNIX voidconvert_to_linux_termio(unsigned_word addr, struct termio *host, cpu *processor, unsigned_word cia){ struct linux_termio target; int i; target.c_iflag = H2T_2 (host->c_iflag); target.c_oflag = H2T_2 (host->c_oflag); target.c_cflag = H2T_2 (host->c_cflag); target.c_lflag = H2T_2 (host->c_lflag);#if defined(HAVE_TERMIO_CLINE) || defined(HAVE_TERMIOS_CLINE) target.c_line = host->c_line;#else target.c_line = 0;#endif for (i = 0; i < LINUX_NCC; i++) target.c_cc[i] = 0;#ifdef VINTR target.c_cc[LINUX_VINTR] = host->c_cc[VINTR];#endif#ifdef VQUIT target.c_cc[LINUX_VQUIT] = host->c_cc[VQUIT];#endif#ifdef VERASE target.c_cc[LINUX_VERASE] = host->c_cc[VERASE];#endif#ifdef VKILL target.c_cc[LINUX_VKILL] = host->c_cc[VKILL];#endif#ifdef VEOF target.c_cc[LINUX_VEOF] = host->c_cc[VEOF];#endif#ifdef VMIN target.c_cc[LINUX_VMIN] = host->c_cc[VMIN];#endif#ifdef VEOL target.c_cc[LINUX_VEOL] = host->c_cc[VEOL];#endif#ifdef VTIME target.c_cc[LINUX_VTIME] = host->c_cc[VTIME];#endif#ifdef VEOL2 target.c_cc[LINUX_VEOL2] = host->c_cc[VEOL2];#endif#ifdef VSWTC target.c_cc[LINUX_VSWTC] = host->c_cc[VSWTC];#endif#ifdef VSWTCH target.c_cc[LINUX_VSWTC] = host->c_cc[VSWTCH];#endif emul_write_buffer(&target, addr, sizeof(target), processor, cia);}#endif /* HAVE_TERMIO_STRUCTURE */#ifdef HAVE_TERMIOS_STRUCTURE/* Convert to/from host termios structure */typedef unsigned32 linux_tcflag_t;typedef unsigned8 linux_cc_t;typedef unsigned32 linux_speed_t;struct linux_termios { linux_tcflag_t c_iflag; linux_tcflag_t c_oflag; linux_tcflag_t c_cflag; linux_tcflag_t c_lflag; linux_cc_t c_cc[LINUX_NCCS]; linux_cc_t c_line; signed32 c_ispeed; signed32 c_ospeed;};STATIC_INLINE_EMUL_UNIX voidconvert_to_linux_termios(unsigned_word addr, struct termios *host, cpu *processor, unsigned_word cia){ struct linux_termios target; int i; target.c_iflag = H2T_4 (host->c_iflag); target.c_oflag = H2T_4 (host->c_oflag); target.c_cflag = H2T_4 (host->c_cflag); target.c_lflag = H2T_4 (host->c_lflag); for (i = 0; i < LINUX_NCCS; i++) target.c_cc[i] = 0;#ifdef VINTR target.c_cc[LINUX_VINTR] = host->c_cc[VINTR];#endif#ifdef VQUIT target.c_cc[LINUX_VQUIT] = host->c_cc[VQUIT];#endif#ifdef VERASE target.c_cc[LINUX_VERASE] = host->c_cc[VERASE];#endif#ifdef VKILL target.c_cc[LINUX_VKILL] = host->c_cc[VKILL];#endif#ifdef VEOF target.c_cc[LINUX_VEOF] = host->c_cc[VEOF];#endif#ifdef VEOL target.c_cc[LINUX_VEOL] = host->c_cc[VEOL];#endif#ifdef VEOL2 target.c_cc[LINUX_VEOL2] = host->c_cc[VEOL2];#endif#ifdef VSWTCH target.c_cc[LINUX_VSWTC] = host->c_cc[VSWTCH];#endif#ifdef HAVE_TERMIOS_CLINE target.c_line = host->c_line;#else target.c_line = 0;#endif#ifdef HAVE_CFGETISPEED target.c_ispeed = cfgetispeed (host);#else target.c_ispeed = 0;#endif#ifdef HAVE_CFGETOSPEED target.c_ospeed = cfgetospeed (host);#else target.c_ospeed = 0;#endif emul_write_buffer(&target, addr, sizeof(target), processor, cia);}#endif /* HAVE_TERMIOS_STRUCTURE */#ifndef HAVE_IOCTL#define do_linux_ioctl 0#elsestatic voiddo_linux_ioctl(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ int fildes = cpu_registers(processor)->gpr[arg0]; unsigned request = cpu_registers(processor)->gpr[arg0+1]; unsigned_word argp_addr = cpu_registers(processor)->gpr[arg0+2]; int status = 0; const char *name = "<unknown>";#ifdef HAVE_TERMIOS_STRUCTURE struct termios host_termio;#else#ifdef HAVE_TERMIO_STRUCTURE struct termio host_termio;#endif#endif switch (request) { case 0: /* make sure we have at least one case */ default: status = -1; errno = EINVAL; break;#if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE)#if defined(TCGETA) || defined(TCGETS) || defined(HAVE_TCGETATTR) case LINUX_IOR('t', 23, struct linux_termio): /* TCGETA */ name = "TCGETA";#ifdef HAVE_TCGETATTR status = tcgetattr(fildes, &host_termio);#elif defined(TCGETS) status = ioctl (fildes, TCGETS, &host_termio);#else status = ioctl (fildes, TCGETA, &host_termio);#endif if (status == 0) convert_to_linux_termio (argp_addr, &host_termio, processor, cia); break;#endif /* TCGETA */#endif /* HAVE_TERMIO_STRUCTURE */#ifdef HAVE_TERMIOS_STRUCTURE#if defined(TCGETS) || defined(HAVE_TCGETATTR) case LINUX_IOR('t', 19, struct linux_termios): /* TCGETS */ name = "TCGETS";#ifdef HAVE_TCGETATTR status = tcgetattr(fildes, &host_termio);#else status = ioctl (fildes, TCGETS, &host_termio);#endif if (status == 0) convert_to_linux_termios (argp_addr, &host_termio, processor, cia); break;#endif /* TCGETS */#endif /* HAVE_TERMIOS_STRUCTURE */ } emul_write_status(processor, status, errno); if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%d, 0x%x [%s], 0x%lx", fildes, request, name, (long)argp_addr);}#endif /* HAVE_IOCTL */static emul_syscall_descriptor linux_descriptors[] = { /* 0 */ { 0, "setup" }, /* 1 */ { do_unix_exit, "exit" }, /* 2 */ { 0, "fork" }, /* 3 */ { do_unix_read, "read" }, /* 4 */ { do_unix_write, "write" }, /* 5 */ { do_unix_open, "open" }, /* 6 */ { do_unix_close, "close" }, /* 7 */ { 0, "waitpid" }, /* 8 */ { 0, "creat" }, /* 9 */ { do_unix_link, "link" }, /* 10 */ { do_unix_unlink, "unlink" }, /* 11 */ { 0, "execve" }, /* 12 */ { do_unix_chdir, "chdir" }, /* 13 */ { do_unix_time, "time" }, /* 14 */ { 0, "mknod" }, /* 15 */ { 0, "chmod" }, /* 16 */ { 0, "chown" }, /* 17 */ { 0, "break" }, /* 18 */ { 0, "stat" }, /* 19 */ { do_unix_lseek, "lseek" }, /* 20 */ { do_unix_getpid, "getpid" }, /* 21 */ { 0, "mount" }, /* 22 */ { 0, "umount" }, /* 23 */ { 0, "setuid" }, /* 24 */ { do_unix_getuid, "getuid" }, /* 25 */ { 0, "stime" }, /* 26 */ { 0, "ptrace" }, /* 27 */ { 0, "alarm" }, /* 28 */ { 0, "fstat" }, /* 29 */ { 0, "pause" }, /* 30 */ { 0, "utime" }, /* 31 */ { 0, "stty" }, /* 32 */ { 0, "gtty" }, /* 33 */ { do_unix_access, "access" }, /* 34 */ { 0, "nice" }, /* 35 */ { 0, "ftime" }, /* 36 */ { 0, "sync" }, /* 37 */ { 0, "kill" }, /* 38 */ { 0, "rename" }, /* 39 */ { do_unix_mkdir, "mkdir" }, /* 40 */ { do_unix_rmdir, "rmdir" }, /* 41 */ { do_unix_dup, "dup" }, /* 42 */ { 0, "pipe" }, /* 43 */ { 0, "times" }, /* 44 */ { 0, "prof" }, /* 45 */ { do_unix_break, "brk" }, /* 46 */ { 0, "setgid" }, /* 47 */ { do_unix_getgid, "getgid" }, /* 48 */ { 0, "signal" }, /* 49 */ { do_unix_geteuid, "geteuid" }, /* 50 */ { do_unix_getegid, "getegid" }, /* 51 */ { 0, "acct" }, /* 52 */ { 0, "phys" }, /* 53 */ { 0, "lock" }, /* 54 */ { do_linux_ioctl, "ioctl" }, /* 55 */ { 0, "fcntl" }, /* 56 */ { 0, "mpx" }, /* 57 */ { 0, "setpgid" }, /* 58 */ { 0, "ulimit" }, /* 59 */ { 0, "olduname" }, /* 60 */ { do_unix_umask, "umask" }, /* 61 */ { 0, "chroot" }, /* 62 */ { 0, "ustat" }, /* 63 */ { do_unix_dup2, "dup2" }, /* 64 */ { do_unix_getppid, "getppid" }, /* 65 */ { 0, "getpgrp" }, /* 66 */ { 0, "setsid" }, /* 67 */ { 0, "sigaction" }, /* 68 */ { 0, "sgetmask" }, /* 69 */ { 0, "ssetmask" }, /* 70 */ { 0, "setreuid" }, /* 71 */ { 0, "setregid" }, /* 72 */ { 0, "sigsuspend" }, /* 73 */ { 0, "sigpending" }, /* 74 */ { 0, "sethostname" }, /* 75 */ { 0, "setrlimit" }, /* 76 */ { 0, "getrlimit" }, /* 77 */ { do_unix_getrusage, "getrusage" }, /* 78 */ { do_unix_gettimeofday, "gettimeofday" }, /* 79 */ { 0, "settimeofday" }, /* 80 */ { 0, "getgroups" }, /* 81 */ { 0, "setgroups" }, /* 82 */ { 0, "select" }, /* 83 */ { do_unix_symlink, "symlink" }, /* 84 */ { 0, "lstat" }, /* 85 */ { 0, "readlink" }, /* 86 */ { 0, "uselib" }, /* 87 */ { 0, "swapon" }, /* 88 */ { 0, "reboot" }, /* 89 */ { 0, "readdir" }, /* 90 */ { 0, "mmap" }, /* 91 */ { 0, "munmap" }, /* 92 */ { 0, "truncate" }, /* 93 */ { 0, "ftruncate" }, /* 94 */ { 0, "fchmod" }, /* 95 */ { 0, "fchown" }, /* 96 */ { 0, "getpriority" }, /* 97 */ { 0, "setpriority" }, /* 98 */ { 0, "profil" }, /* 99 */ { 0, "statfs" }, /* 100 */ { 0, "fstatfs" },
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -