📄 emul_unix.c
字号:
/* This file is part of the program psim. Copyright (C) 1996-1998, Andrew Cagney <cagney@highland.com.au> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#ifndef _EMUL_UNIX_C_#define _EMUL_UNIX_C_/* Note: this module is called via a table. There is no benefit in making it inline */#include "emul_generic.h"#include "emul_unix.h"#ifdef HAVE_STRING_H#include <string.h>#else#ifdef HAVE_STRINGS_H#include <strings.h>#endif#endif#ifdef HAVE_SYS_TYPES_H#include <sys/types.h>#endif#ifdef HAVE_SYS_TYPES_H#include <sys/stat.h>#else#undef HAVE_STAT#undef HAVE_LSTAT#undef HAVE_FSTAT#endif#include <stdio.h>#include <signal.h>#include <errno.h>#ifdef HAVE_FCNTL_H#include <fcntl.h>#endif#ifdef HAVE_SYS_PARAM_H#include <sys/param.h>#endif#ifdef HAVE_SYS_TIME_H#include <sys/time.h>#endif#ifndef HAVE_TERMIOS_STRUCTURE#undef HAVE_SYS_TERMIOS_H#undef HAVE_TCGETATTR#else#ifndef HAVE_SYS_TERMIOS_H#undef HAVE_TERMIOS_STRUCTURE#endif#endif#ifdef HAVE_TERMIOS_STRUCTURE#include <sys/termios.h>/* If we have TERMIOS, use that for the termio structure, since some systems don't like including both sys/termios.h and sys/termio.h at the same time. */#undef HAVE_TERMIO_STRUCTURE#undef TCGETA#undef termio#define termio termios#endif#ifndef HAVE_TERMIO_STRUCTURE#undef HAVE_SYS_TERMIO_H#else#ifndef HAVE_SYS_TERMIO_H#undef HAVE_TERMIO_STRUCTURE#endif#endif#ifdef HAVE_TERMIO_STRUCTURE#include <sys/termio.h>#endif#ifdef HAVE_GETRUSAGE#ifndef HAVE_SYS_RESOURCE_H#undef HAVE_GETRUSAGE#endif#endif#ifdef HAVE_GETRUSAGE#include <sys/resource.h>int getrusage();#endif#if HAVE_DIRENT_H# include <dirent.h># define NAMLEN(dirent) strlen((dirent)->d_name)#else# define dirent direct# define NAMLEN(dirent) (dirent)->d_namlen# if HAVE_SYS_NDIR_H# include <sys/ndir.h># endif# if HAVE_SYS_DIR_H# include <sys/dir.h># endif# if HAVE_NDIR_H# include <ndir.h># endif#endif#ifdef HAVE_UNISTD_H#undef MAXPATHLEN /* sys/param.h might define this also */#include <unistd.h>#endif#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#if defined(BSD) && !defined(errno) && (BSD < 199306) /* here BSD as just a bug */extern int errno;#endif#ifndef STATIC_INLINE_EMUL_UNIX#define STATIC_INLINE_EMUL_UNIX STATIC_INLINE#endif#ifndef PATH_MAX#define PATH_MAX 1024#endif#ifndef EINVAL#define EINVAL -1#endif/* UNIX's idea of what is needed to implement emulations */struct _os_emul_data { device *vm; emul_syscall *syscalls;};/* Emulation of simple UNIX system calls that are common on all systems. *//* Structures that are common agmonst the UNIX varients */struct unix_timeval { signed32 tv_sec; /* seconds */ signed32 tv_usec; /* microseconds */};struct unix_timezone { signed32 tz_minuteswest; /* minutes west of Greenwich */ signed32 tz_dsttime; /* type of dst correction */};#define UNIX_RUSAGE_SELF 0#define UNIX_RUSAGE_CHILDREN (-1)#define UNIX_RUSAGE_BOTH (-2) /* sys_wait4() uses this */struct unix_rusage { struct unix_timeval ru_utime; /* user time used */ struct unix_timeval ru_stime; /* system time used */ signed32 ru_maxrss; /* maximum resident set size */ signed32 ru_ixrss; /* integral shared memory size */ signed32 ru_idrss; /* integral unshared data size */ signed32 ru_isrss; /* integral unshared stack size */ signed32 ru_minflt; /* any page faults not requiring I/O */ signed32 ru_majflt; /* any page faults requiring I/O */ signed32 ru_nswap; /* swaps */ signed32 ru_inblock; /* block input operations */ signed32 ru_oublock; /* block output operations */ signed32 ru_msgsnd; /* messages sent */ signed32 ru_msgrcv; /* messages received */ signed32 ru_nsignals; /* signals received */ signed32 ru_nvcsw; /* voluntary context switches */ signed32 ru_nivcsw; /* involuntary " */};static voiddo_unix_exit(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ int status = (int)cpu_registers(processor)->gpr[arg0]; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%d)\n", status); cpu_halt(processor, cia, was_exited, status);}static voiddo_unix_read(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ void *scratch_buffer; int d = (int)cpu_registers(processor)->gpr[arg0]; unsigned_word buf = cpu_registers(processor)->gpr[arg0+1]; int nbytes = cpu_registers(processor)->gpr[arg0+2]; int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%d, 0x%lx, %d", d, (long)buf, nbytes); /* get a tempoary bufer */ scratch_buffer = zalloc(nbytes); /* check if buffer exists by reading it */ emul_read_buffer(scratch_buffer, buf, nbytes, processor, cia); /* read */ status = read (d, scratch_buffer, nbytes); emul_write_status(processor, status, errno); if (status > 0) emul_write_buffer(scratch_buffer, buf, status, processor, cia); zfree(scratch_buffer);}static voiddo_unix_write(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ void *scratch_buffer = NULL; int d = (int)cpu_registers(processor)->gpr[arg0]; unsigned_word buf = cpu_registers(processor)->gpr[arg0+1]; int nbytes = cpu_registers(processor)->gpr[arg0+2]; int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%d, 0x%lx, %d", d, (long)buf, nbytes); /* get a tempoary bufer */ scratch_buffer = zalloc(nbytes); /* FIXME - nbytes == 0 */ /* copy in */ emul_read_buffer(scratch_buffer, buf, nbytes, processor, cia); /* write */ status = write(d, scratch_buffer, nbytes); emul_write_status(processor, status, errno); zfree(scratch_buffer); flush_stdoutput();}static voiddo_unix_open(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; char path_buf[PATH_MAX]; char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); int flags = (int)cpu_registers(processor)->gpr[arg0+1]; int mode = (int)cpu_registers(processor)->gpr[arg0+2]; int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0x%lx [%s], 0x%x, 0x%x", (long)path_addr, path, flags, mode); status = open(path, flags, mode); emul_write_status(processor, status, errno);}static voiddo_unix_close(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ int d = (int)cpu_registers(processor)->gpr[arg0]; int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%d", d); status = close(d); emul_write_status(processor, status, errno);}static voiddo_unix_break(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ /* just pass this onto the `vm' device */ unsigned_word new_break = cpu_registers(processor)->gpr[arg0]; int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0x%lx", (long)cpu_registers(processor)->gpr[arg0]); status = device_ioctl(emul->vm, processor, cia, device_ioctl_break, new_break); /*ioctl-data*/ emul_write_status(processor, 0, status);}#ifndef HAVE_ACCESS#define do_unix_access 0#elsestatic voiddo_unix_access(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; char path_buf[PATH_MAX]; char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); int mode = (int)cpu_registers(processor)->gpr[arg0+1]; int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0x%lx [%s], 0x%x [0%o]", (long)path_addr, path, mode, mode); status = access(path, mode); emul_write_status(processor, status, errno);}#endif#ifndef HAVE_GETPID#define do_unix_getpid 0#elsestatic voiddo_unix_getpid(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ pid_t status = getpid(); emul_write_status(processor, (int)status, errno);}#endif#ifndef HAVE_GETPPID#define do_unix_getppid 0#elsestatic voiddo_unix_getppid(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ pid_t status = getppid(); emul_write_status(processor, (int)status, errno);}#endif#if !defined(HAVE_GETPID) || !defined(HAVE_GETPPID)#define do_unix_getpid2 0#elsestatic voiddo_unix_getpid2(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ int pid = (int)getpid(); int ppid = (int)getppid(); emul_write2_status(processor, pid, ppid, errno);}#endif#if !defined(HAVE_GETUID) || !defined(HAVE_GETEUID)#define do_unix_getuid2 0#elsestatic voiddo_unix_getuid2(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ uid_t uid = getuid(); uid_t euid = geteuid(); emul_write2_status(processor, (int)uid, (int)euid, errno);}#endif#ifndef HAVE_GETUID#define do_unix_getuid 0#elsestatic voiddo_unix_getuid(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ uid_t status = getuid(); emul_write_status(processor, (int)status, errno);}#endif#ifndef HAVE_GETEUID#define do_unix_geteuid 0#elsestatic voiddo_unix_geteuid(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ uid_t status = geteuid(); emul_write_status(processor, (int)status, errno);}#endif#if 0#ifndef HAVE_KILL#define do_unix_kill 0#elsestatic voiddo_unix_kill(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ pid_t pid = cpu_registers(processor)->gpr[arg0]; int sig = cpu_registers(processor)->gpr[arg0+1]; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%d, %d", (int)pid, sig); printf_filtered("SYS_kill at 0x%lx - more to this than just being killed\n", (long)cia); cpu_halt(processor, cia, was_signalled, sig);}#endif#endif#ifndef HAVE_DUP#define do_unix_dup 0#elsestatic voiddo_unix_dup(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ int oldd = cpu_registers(processor)->gpr[arg0]; int status = dup(oldd); int err = errno; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%d", oldd); emul_write_status(processor, status, err);}#endif#ifndef HAVE_DUP2#define do_unix_dup2 0#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -