/* Copyright (C) 1992, Digital Equipment Corporation */ /* All rights reserved. */ /* See the file COPYRIGHT for a full description. */ /* Last modified on Thu Dec 24 13:32:19 PST 1992 by jdd */ /* This file implements wrappers for almost all Ultrix system calls that take pointers as arguments. These wrappers allow the system calls to take arguments that might point to the traced heap, which may be VM-protected in the Ultrix implementation of the collector. The wrappers read and write the referents of all pointers about to passed to the system call, which ensures that the pages are not protected when the call is made. Each wrapper is a critical section, with RTou__inCritical non-zero, so that another thread cannot cause the pages to become reprotected before the system call is performed. A few system calls are not handled here, or are handled only partially. This restricts the system calls that can be made from Modula-3, or from libaries that are passed pointers into the Modula-3 traced heap. These system calls are: 1) sigvec. Sigvec takes 3 arguments, but passes 4 to the kernel. The extra argument is the address of the sigtramp code, which is copyrighted by MIPS. The sigtramp code appears in the the stndard .o file that also defines sigvec, so that sigvec cannot be redefined here without including sigtramp. Rewriting sigtramp seemed too error-prone, so sigvec is not supported here, meaning that sigvec cannot be called with arguments on the heap. 2) syscall. Implementing syscall would require a huge case statement, with one case per system call. This seemed too error-prone, so syscall cannot take arguments that point into the traced heap. 3) ioctl. Ioctl's third argument is a pointer, and some device drivers might interpret the referent as containing more pointers. These second-level pointers are not handled here, so they must not point into the traced heap if they exist. Handling this problem in general is impossible, since the set of device drivers is open-ended. 4) Undocumented system calls. There are private system calls with no manual pages, so it was impossible to write wrappers. 5) audgen, whose manpage is incomprehensible. Also, longjmp must not be used from a signal handler to abnormally exit from a system call. Finally, if a system call references an object on the heap, each pointer must reference only one object. Therefore, it is not possible to write the heap contents with a single write. */ #include #include #include #include #include #include #include #include #include #include extern int RT0u__inCritical; /* The following wrappers all have the same structure. */ int accept(s, addr, addrlen) int s; struct sockaddr *addr; int *addrlen; { int result; char c; ++RT0u__inCritical; if (addr) { c = *(char*)addr; *(char*)addr = c; } if (addrlen) { c = *(char*)addrlen; *(char*)addrlen = c; } result = syscall(SYS_accept, s, addr, addrlen); --RT0u__inCritical; return result; } int access(path, mode) char *path; int mode; { int result; char c; ++RT0u__inCritical; if (path) { c = *(char*)path; *(char*)path = c; } result = syscall(SYS_access, path, mode); --RT0u__inCritical; return result; } int acct(file) char *file; { int result; char c; ++RT0u__inCritical; if (file) { c = *(char*)file; *(char*)file = c; } result = syscall(SYS_acct, file); --RT0u__inCritical; return result; } int adjtime(delta, olddelta) struct timeval *delta; struct timeval *olddelta; { int result; char c; ++RT0u__inCritical; if (delta) { c = *(char*)delta; *(char*)delta = c; } if (olddelta) { c = *(char*)olddelta; *(char*)olddelta = c; } result = syscall(SYS_adjtime, delta, olddelta); --RT0u__inCritical; return result; } int atomic_op(op, addr) int op; int *addr; { int result; char c; ++RT0u__inCritical; if (addr) { c = *(char*)addr; *(char*)addr = c; } result = syscall(SYS_atomic_op, op, addr); --RT0u__inCritical; return result; } int audcntl(request, argp, len, flag, audit_id) int request; char *argp; int len; int flag; audit_ID_t audit_id; { int result; char c; ++RT0u__inCritical; if (argp) { c = *(char*)argp; *(char*)argp = c; } result = syscall(SYS_audcntl, request, argp, len, flag, audit_id); --RT0u__inCritical; return result; } int audgen(event, tokenp, argv) int event; char *tokenp, *argv[]; { int result; char c; ++RT0u__inCritical; { char *t, **a; for (t = tokenp, a = argv; t; t++, a++) { if (A_TOKEN_PTR(*t)) { if (*a) { c = **a; **a = c; } } } } result = syscall(SYS_audgen, tokenp, argv); --RT0u__inCritical; return result; } int bind(s, name, namelen) int s; struct sockaddr *name; int namelen; { int result; char c; ++RT0u__inCritical; if (name) { c = *(char*)name; *(char*)name = c; } result = syscall(SYS_bind, s, name, namelen); --RT0u__inCritical; return result; } int cachectl(addr, nbytes, op) char *addr; int nbytes, op; { int result; char c; ++RT0u__inCritical; if (addr) { c = *(char*)addr; *(char*)addr = c; } result = syscall(SYS_cachectl, addr, nbytes, op); --RT0u__inCritical; return result; } int cacheflush(addr, nbytes, cache) char *addr; int nbytes, cache; { int result; char c; ++RT0u__inCritical; if (addr) { c = *(char*)addr; *(char*)addr = c; } result = syscall(SYS_cacheflush, addr, nbytes, cache); --RT0u__inCritical; return result; } int chdir(path) char *path; { int result; char c; ++RT0u__inCritical; if (path) { c = *(char*)path; *(char*)path = c; } result = syscall(SYS_chdir, path); --RT0u__inCritical; return result; } int chmod(path, mode) char *path; mode_t mode; { int result; char c; ++RT0u__inCritical; if (path) { c = *(char*)path; *(char*)path = c; } result = syscall(SYS_chmod, path, mode); --RT0u__inCritical; return result; } int chown(path, owner, group) char *path; uid_t owner; gid_t group; { int result; char c; ++RT0u__inCritical; if (path) { c = *(char*)path; *(char*)path = c; } result = syscall(SYS_chown, path, owner, group); --RT0u__inCritical; return result; } int chroot(dirname) char *dirname; { int result; char c; ++RT0u__inCritical; if (dirname) { c = *(char*)dirname; *(char*)dirname = c; } result = syscall(SYS_chroot, dirname); --RT0u__inCritical; return result; } int connect(s, name, namelen) int s; struct sockaddr *name; int namelen; { int result; char c; ++RT0u__inCritical; if (name) { c = *(char*)name; *(char*)name = c; } result = syscall(SYS_connect, s, name, namelen); --RT0u__inCritical; return result; } int creat(name, mode) char *name; mode_t mode; { int result; char c; ++RT0u__inCritical; if (name) { c = *(char*)name; *(char*)name = c; } result = syscall(SYS_creat, name, mode); --RT0u__inCritical; return result; } /* execve is implemented differently since it does not return, which would leave RT0u__inCritical set in the parent if called in the child of a vfork. Many calls leave the process in an undefined state in the case of EFAULT, but we assume that execve is not one of these. */ int execve(name, argv, envp) char *name; char *argv[]; char *envp[]; { int result; char c; for (;;) { result = syscall(SYS_execve, name, argv, envp); if (result == -1 && errno == EFAULT) { if (name) { c = *(char*)name; *(char*)name = c; } { char **a; for (a = argv; *a; a++) { c = **a; **a = c; }} { char **e; for (e = envp; *e; e++) { c = **e; **e = c; }} } else { return result; } } } int exportfs(name, rootuid, exflags) char *name; int rootuid, exflags; { int result; char c; ++RT0u__inCritical; if (name) { c = *(char*)name; *(char*)name = c; } result = syscall(SYS_exportfs, name, rootuid, exflags); --RT0u__inCritical; return result; } int fchmod(fd, mode) int fd; mode_t mode; { int result; char c; ++RT0u__inCritical; result = syscall(SYS_fchmod, fd, mode); --RT0u__inCritical; return result; } int fcntl(fd, request, arg) int fd, request, arg; { int result; char c; ++RT0u__inCritical; if (request == F_GETLK || request == F_SETLK || request == F_SETLKW) { c = *(char*)arg; *(char*)arg = c; } result = syscall(SYS_fcntl, fd, request, arg); --RT0u__inCritical; return result; } int fstat(fd, buf) int fd; struct stat *buf; { int result; char c; ++RT0u__inCritical; if (buf) { c = *(char*)buf; *(char*)buf = c; } result = syscall(SYS_fstat, fd, buf); --RT0u__inCritical; return result; } int getdirentries(fd, buf, nbytes, basep) int fd; char *buf; int nbytes; long *basep; { int result; char c; ++RT0u__inCritical; if (buf) { c = *(char*)buf; *(char*)buf = c; } if (basep) { c = *(char*)basep; *(char*)basep = c; } result = syscall(SYS_getdirentries, fd, buf, nbytes, basep); --RT0u__inCritical; return result; } int getdomainname(name, namelen) char *name; int namelen; { int result; char c; ++RT0u__inCritical; if (name) { c = *(char*)name; *(char*)name = c; } result = syscall(SYS_getdomainname, name, namelen); --RT0u__inCritical; return result; } int gethostname(name, namelen) char *name; int namelen; { int result; char c; ++RT0u__inCritical; if (name) { c = *(char*)name; *(char*)name = c; } result = syscall(SYS_gethostname, name, namelen); --RT0u__inCritical; return result; } int getgroups(gidsetsize, grouplist) int gidsetsize; int grouplist[]; { int result; char c; ++RT0u__inCritical; { c = *(char*)grouplist; *(char*)grouplist = c; } result = syscall(SYS_getgroups, gidsetsize, grouplist); --RT0u__inCritical; return result; } int getitimer(which, value) int which; struct itimerval *value; { int result; char c; ++RT0u__inCritical; if (value) { c = *(char*)value; *(char*)value = c; } result = syscall(SYS_getitimer, which, value); --RT0u__inCritical; return result; } int getmnt(start, buffer, nbytes, mode, path) int *start; struct fs_data *buffer; int nbytes, mode; char *path; { int result; char c; ++RT0u__inCritical; if (start) { c = *(char*)start; *(char*)start = c; } if (buffer) { c = *(char*)buffer; *(char*)buffer = c; } if (path) { c = *(char*)path; *(char*)path = c; } result = syscall(SYS_getmnt, start, buffer, nbytes, mode, path); --RT0u__inCritical; return result; } int getpeername(s, name, namelen) int s; struct sockaddr *name; int *namelen; { int result; char c; ++RT0u__inCritical; if (name) { c = *(char*)name; *(char*)name = c; } if (namelen) { c = *(char*)namelen; *(char*)namelen = c; } result = syscall(SYS_getpeername, s, name, namelen); --RT0u__inCritical; return result; } int getrlimit(resource, rlp) int resource; struct rlimit *rlp; { int result; char c; ++RT0u__inCritical; if (rlp) { c = *(char*)rlp; *(char*)rlp = c; } result = syscall(SYS_getrlimit, resource, rlp); --RT0u__inCritical; return result; } int getrusage(who, rusage) int who; struct rusage *rusage; { int result; char c; ++RT0u__inCritical; if (rusage) { c = *(char*)rusage; *(char*)rusage = c; } result = syscall(SYS_getrusage, who, rusage); --RT0u__inCritical; return result; } int getsockname(s, name, namelen) int s; struct sockaddr *name; int *namelen; { int result; char c; ++RT0u__inCritical; if (name) { c = *(char*)name; *(char*)name = c; } if (namelen) { c = *(char*)namelen; *(char*)namelen = c; } result = syscall(SYS_getsockname, s, name, namelen); --RT0u__inCritical; return result; } int getsockopt(s, level, optname, optval, optlen) int s, level, optname; char *optval; int *optlen; { int result; char c; ++RT0u__inCritical; if (optval) { c = *(char*)optval; *(char*)optval = c; } if (optlen) { c = *(char*)optlen; *(char*)optlen = c; } result = syscall(SYS_getsockopt, s, level, optname, optval, optlen); --RT0u__inCritical; return result; } int getsysinfo(op, buffer, nbytes, start, arg) unsigned op; char *buffer; unsigned nbytes; int *start; char *arg; { int result; char c; ++RT0u__inCritical; if (buffer) { c = *(char*)buffer; *(char*)buffer = c; } if (start) { c = *(char*)start; *(char*)start = c; } if (arg) { c = *(char*)arg; *(char*)arg = c; } result = syscall(SYS_getsysinfo, op, buffer, nbytes, start, arg); --RT0u__inCritical; return result; } int gettimeofday(tp, tzp) struct timeval *tp; struct timezone *tzp; { int result; char c; ++RT0u__inCritical; if (tp) { c = *(char*)tp; *(char*)tp = c; } if (tzp) { c = *(char*)tzp; *(char*)tzp = c; } result = syscall(SYS_gettimeofday, tp, tzp); --RT0u__inCritical; return result; } int ioctl(d, request, argp) int d, request; char *argp; { int result; char c; ++RT0u__inCritical; if (argp) { c = *(char*)argp; *(char*)argp = c; } result = syscall(SYS_ioctl, d, request, argp); --RT0u__inCritical; return result; } int link(name1, name2) char *name1; char *name2; { int result; char c; ++RT0u__inCritical; if (name1) { c = *(char*)name1; *(char*)name1 = c; } if (name2) { c = *(char*)name2; *(char*)name2 = c; } result = syscall(SYS_link, name1, name2); --RT0u__inCritical; return result; } int lstat(path, buf) char *path; struct stat *buf; { int result; char c; ++RT0u__inCritical; if (path) { c = *(char*)path; *(char*)path = c; } if (buf) { c = *(char*)buf; *(char*)buf = c; } result = syscall(SYS_lstat, path, buf); --RT0u__inCritical; return result; } int mkdir(path, mode) char *path; mode_t mode; { int result; char c; ++RT0u__inCritical; if (path) { c = *(char*)path; *(char*)path = c; } result = syscall(SYS_mkdir, path, mode); --RT0u__inCritical; return result; } int mknod(path, mode, dev) char *path; mode_t mode; int dev; { int result; char c; ++RT0u__inCritical; if (path) { c = *(char*)path; *(char*)path = c; } result = syscall(SYS_mknod, path, mode, dev); --RT0u__inCritical; return result; } int mount(special, name, rwflag, type, options) char *special; char *name; int rwflag, type; char *options; { int result; char c; ++RT0u__inCritical; if (special) { c = *(char*)special; *(char*)special = c; } if (name) { c = *(char*)name; *(char*)name = c; } if (options) { c = *(char*)options; *(char*)options = c; } result = syscall(SYS_mount, special, name, rwflag, type, options); --RT0u__inCritical; if (result != -1) result = 0; return result; } int msgctl(msqid, cmd, buf) int msqid, cmd; struct msqid_ds *buf; { int result; char c; ++RT0u__inCritical; if (buf) { c = *(char*)buf; *(char*)buf = c; } result = syscall(SYS_msgctl, msqid, cmd, buf); --RT0u__inCritical; return result; } int msgrcv(msqid, msgp, msgsz, msgtyp, msgflg) int msqid; void *msgp; size_t msgsz; long msgtyp; int msgflg; { int result; char c; ++RT0u__inCritical; if (msgp) { c = *(char*)msgp; *(char*)msgp = c; } result = syscall(SYS_msgrcv, msqid, msgp, msgsz, msgtyp, msgflg); --RT0u__inCritical; return result; } int msgsnd(msqid, msgp, msgsz, msgflg) int msqid; void *msgp; size_t msgsz; int msgflg; { int result; char c; ++RT0u__inCritical; if (msgp) { c = *(char*)msgp; *(char*)msgp = c; } result = syscall(SYS_msgsnd, msqid, msgp, msgsz, msgflg); --RT0u__inCritical; return result; } int open(path, flags, mode) char *path; int flags, mode; { int result; char c; ++RT0u__inCritical; if (path) { c = *(char*)path; *(char*)path = c; } result = syscall(SYS_open, path, flags, mode); --RT0u__inCritical; return result; } int quota(cmd, uid, arg, addr) int cmd, uid, arg; caddr_t addr; { int result; char c; ++RT0u__inCritical; if (addr) { c = *(char*)addr; *(char*)addr = c; } result = syscall(SYS_quota, cmd, uid, arg, addr); --RT0u__inCritical; return result; } int read(d, buf, nbytes) int d; char *buf; int nbytes; { int result; char c; ++RT0u__inCritical; if (buf) { c = *(char*)buf; *(char*)buf = c; } result = syscall(SYS_read, d, buf, nbytes); --RT0u__inCritical; return result; } int readlink(path, buf, bufsiz) char *path; char *buf; int bufsiz; { int result; char c; ++RT0u__inCritical; if (path) { c = *(char*)path; *(char*)path = c; } if (buf) { c = *(char*)buf; *(char*)buf = c; } result = syscall(SYS_readlink, path, buf, bufsiz); --RT0u__inCritical; return result; } int readv(d, iov, iovcnt) int d; struct iovec *iov; int iovcnt; { int result; char c; ++RT0u__inCritical; { int i; for (i = 0; i < iovcnt; i++) { { c = *(char*)iov[i].iov_base; *(char*)iov[i].iov_base = c; } } } result = syscall(SYS_readv, d, iov, iovcnt); --RT0u__inCritical; return result; } int recv(s, buf, len, flags) int s; char *buf; int len, flags; { int result; char c; ++RT0u__inCritical; if (buf) { c = *(char*)buf; *(char*)buf = c; } result = syscall(SYS_recv, s, buf, len, flags); --RT0u__inCritical; return result; } int recvfrom(s, buf, len, flags, from, fromlen) int s; char *buf; int len, flags; struct sockaddr *from; int *fromlen; { int result; char c; ++RT0u__inCritical; if (buf) { c = *(char*)buf; *(char*)buf = c; } if (from) { c = *(char*)from; *(char*)from = c; } if (fromlen) { c = *(char*)fromlen; *(char*)fromlen = c; } result = syscall(SYS_recvfrom, s, buf, len, flags, from, fromlen); --RT0u__inCritical; return result; } int recvmsg(s, msg, flags) int s; struct msghdr msg[]; int flags; { int result; char c; ++RT0u__inCritical; if (msg->msg_name) { char c; c = *(char*)msg->msg_name; *(char*)msg->msg_name = c; } { int i; for (i = 0; i < msg->msg_iovlen; i++) { if (msg->msg_iov[i].iov_len > 0) { c = *(char*)msg->msg_iov[i].iov_base; *(char*)msg->msg_iov[i].iov_base = c; } } } if (msg->msg_accrights) { c = *(char*)msg->msg_accrights; *(char*)msg->msg_accrights = c; } result = syscall(SYS_recvmsg, s, msg, flags); --RT0u__inCritical; return result; } int rename(from, to) char *from; char *to; { int result; char c; ++RT0u__inCritical; if (from) { c = *(char*)from; *(char*)from = c; } if (to) { c = *(char*)to; *(char*)to = c; } result = syscall(SYS_rename, from, to); --RT0u__inCritical; return result; } int rmdir(path) char *path; { int result; char c; ++RT0u__inCritical; if (path) { c = *(char*)path; *(char*)path = c; } result = syscall(SYS_rmdir, path); --RT0u__inCritical; return result; } int select(nfds, readfds, writefds, exceptfds, timeout) fd_set *readfds; fd_set *writefds; fd_set *exceptfds; struct timeval *timeout; { int result; char c; ++RT0u__inCritical; if (readfds) { c = *(char*)readfds; *(char*)readfds = c; } if (writefds) { c = *(char*)writefds; *(char*)writefds = c; } if (exceptfds) { c = *(char*)exceptfds; *(char*)exceptfds = c; } if (timeout) { c = *(char*)timeout; *(char*)timeout = c; } result = syscall(SYS_select, nfds, readfds, writefds, exceptfds, timeout); --RT0u__inCritical; return result; } int semctl(semid, semnum, cmd, arg) int semid, cmd; int semnum; union semun { int val; struct semid_ds *buf; ushort array[1]; } arg; { int result; char c; ++RT0u__inCritical; if (cmd == IPC_STAT || cmd == IPC_SET) { c = *(char*)arg.buf; *(char*)arg.buf = c; } result = syscall(SYS_semctl, semid, semnum, cmd, arg); --RT0u__inCritical; return result; } int semop(semid, sops, nsops) int semid; struct sembuf *sops[]; int nsops; { int result; char c; ++RT0u__inCritical; { int i; for (i = 0; i < nsops; i++) { c = *(char*)sops[i]; *(char*)sops[i] = c; } } result = syscall(SYS_semop, semid, sops, nsops); --RT0u__inCritical; return result; } int send(s, msg, len, flags) int s; char *msg; int len, flags; { int result; char c; ++RT0u__inCritical; if (msg) { c = *(char*)msg; *(char*)msg = c; } result = syscall(SYS_send, s, msg, len, flags); --RT0u__inCritical; return result; } int sendmsg(s, msg, flags) int s; struct msghdr msg[]; int flags; { int result; char c; ++RT0u__inCritical; if (msg->msg_name) { c = *(char*)msg->msg_name; *(char*)msg->msg_name = c; } { int i; for (i = 0; i < msg->msg_iovlen; i++) { if (msg->msg_iov[i].iov_len > 0) { c = *(char*)msg->msg_iov[i].iov_base; *(char*)msg->msg_iov[i].iov_base = c; } } } if (msg->msg_accrights) { c = *(char*)msg->msg_accrights; *(char*)msg->msg_accrights = c; } result = syscall(SYS_sendmsg, s, msg, flags); --RT0u__inCritical; return result; } int sendto(s, msg, len, flags, to, tolen) int s; char *msg; int len, flags; struct sockaddr *to; int tolen; { int result; char c; ++RT0u__inCritical; if (msg) { c = *(char*)msg; *(char*)msg = c; } if (to) { c = *(char*)to; *(char*)to = c; } result = syscall(SYS_sendto, s, msg, len, flags, to, tolen); --RT0u__inCritical; return result; } int setdomainname(name, namelen) char *name; int namelen; { int result; char c; ++RT0u__inCritical; if (name) { c = *(char*)name; *(char*)name = c; } result = syscall(SYS_setdomainname, name, namelen); --RT0u__inCritical; return result; } int setgroups(ngroups, gidset) int ngroups; int *gidset; { int result; char c; ++RT0u__inCritical; if (gidset) { c = *(char*)gidset; *(char*)gidset = c; } result = syscall(SYS_setgroups, ngroups, gidset); --RT0u__inCritical; return result; } int sethostname(name, namelen) char *name; int namelen; { int result; char c; ++RT0u__inCritical; if (name) { c = *(char*)name; *(char*)name = c; } result = syscall(SYS_sethostname, name, namelen); --RT0u__inCritical; return result; } int setitimer(which, value, ovalue) int which; struct itimerval *value; struct itimerval *ovalue; { int result; char c; ++RT0u__inCritical; if (value) { c = *(char*)value; *(char*)value = c; } if (ovalue) { c = *(char*)ovalue; *(char*)ovalue = c; } result = syscall(SYS_setitimer, which, value, ovalue); --RT0u__inCritical; return result; } int setquota(special, file) char *special; char *file; { int result; char c; ++RT0u__inCritical; if (special) { c = *(char*)special; *(char*)special = c; } if (file) { c = *(char*)file; *(char*)file = c; } result = syscall(SYS_setquota, special, file); --RT0u__inCritical; return result; } int setrlimit(resource, rlp) int resource; struct rlimit *rlp; { int result; char c; ++RT0u__inCritical; if (rlp) { c = *(char*)rlp; *(char*)rlp = c; } result = syscall(SYS_setrlimit, resource, rlp); --RT0u__inCritical; return result; } int setsockopt(s, level, optname, optval, optlen) int s, level, optname; char *optval; int optlen; { int result; char c; ++RT0u__inCritical; if (optval) { c = *(char*)optval; *(char*)optval = c; } result = syscall(SYS_setsockopt, s, level, optname, optval, optlen); --RT0u__inCritical; return result; } int setsysinfo(op, buffer, nbytes, arg, flag) unsigned op; char *buffer; unsigned nbytes; unsigned arg; unsigned flag; { int result; char c; ++RT0u__inCritical; if (buffer) { c = *(char*)buffer; *(char*)buffer = c; } result = syscall(SYS_setsysinfo, op, buffer, nbytes, arg, flag); --RT0u__inCritical; return result; } int settimeofday(tp, tzp) struct timeval *tp; struct timezone *tzp; { int result; char c; ++RT0u__inCritical; if (tp) { c = *(char*)tp; *(char*)tp = c; } if (tzp) { c = *(char*)tzp; *(char*)tzp = c; } result = syscall(SYS_settimeofday, tp, tzp); --RT0u__inCritical; return result; } int sigpending(set) sigset_t *set; { int result; char c; ++RT0u__inCritical; if (set) { c = *(char*)set; *(char*)set = c; } result = syscall(SYS_sigpending, set); --RT0u__inCritical; return result; } int sigstack(ss, oss) struct sigstack *ss; struct sigstack *oss; { int result; char c; ++RT0u__inCritical; if (ss) { c = *(char*)ss; *(char*)ss = c; } if (oss) { c = *(char*)oss; *(char*)oss = c; } result = syscall(SYS_sigstack, ss, oss); --RT0u__inCritical; return result; } int socketpair(d, type, protocol, sv) int d, type, protocol; int sv[2]; { int result; char c; ++RT0u__inCritical; { c = *(char*)sv; *(char*)sv = c; } result = syscall(SYS_socketpair, d, type, protocol, sv); --RT0u__inCritical; return result; } int stat(path, buf) char *path; struct stat *buf; { int result; char c; ++RT0u__inCritical; if (path) { c = *(char*)path; *(char*)path = c; } if (buf) { c = *(char*)buf; *(char*)buf = c; } result = syscall(SYS_stat, path, buf); --RT0u__inCritical; return result; } int swapon(special) char *special; { int result; char c; ++RT0u__inCritical; if (special) { c = *(char*)special; *(char*)special = c; } result = syscall(SYS_swapon, special); --RT0u__inCritical; return result; } int symlink(name1, name2) char *name1; char *name2; { int result; char c; ++RT0u__inCritical; if (name1) { c = *(char*)name1; *(char*)name1 = c; } if (name2) { c = *(char*)name2; *(char*)name2 = c; } result = syscall(SYS_symlink, name1, name2); --RT0u__inCritical; return result; } int truncate(path, length) char *path; int length; { int result; char c; ++RT0u__inCritical; if (path) { c = *(char*)path; *(char*)path = c; } result = syscall(SYS_truncate, path, length); --RT0u__inCritical; return result; } int uname(name) struct utsname *name; { int result; char c; ++RT0u__inCritical; if (name) { c = *(char*)name; *(char*)name = c; } result = syscall(SYS_uname, name); --RT0u__inCritical; return result; } int unlink(path) char *path; { int result; char c; ++RT0u__inCritical; if (path) { c = *(char*)path; *(char*)path = c; } result = syscall(SYS_unlink, path); --RT0u__inCritical; return result; } int ustat(dev, buf) dev_t dev; struct ustat *buf; { int result; char c; ++RT0u__inCritical; if (buf) { c = *(char*)buf; *(char*)buf = c; } result = syscall(SYS_ustat, dev, buf); --RT0u__inCritical; return result; } int utimes(file, tvp) char *file; struct timeval *tvp; { int result; char c; ++RT0u__inCritical; if (file) { c = *(char*)file; *(char*)file = c; } if (tvp) { c = *(char*)tvp; *(char*)tvp = c; } result = syscall(SYS_utimes, file, tvp); --RT0u__inCritical; return result; } pid_t wait(status) union wait *status; { wait3(status, 0, 0); } pid_t wait3(status, options, rusage) union wait *status; int options; struct rusage *rusage; { int result; char c; ++RT0u__inCritical; if (status) { c = *(char*)status; *(char*)status = c; } if (rusage) { c = *(char*)rusage; *(char*)rusage = c; } result = syscall(SYS_wait3, status, options, rusage); --RT0u__inCritical; return result; } pid_t waitpid(pid, status, options) union wait *status; int options; { int result; char c; ++RT0u__inCritical; if (status) { c = *(char*)status; *(char*)status = c; } result = syscall(SYS_waitpid, pid, status, options); --RT0u__inCritical; return result; } int write(fd, buf, nbytes) int fd; char *buf; int nbytes; { int result; char c; ++RT0u__inCritical; if (buf) { c = *(char*)buf; *(char*)buf = c; } result = syscall(SYS_write, fd, buf, nbytes); --RT0u__inCritical; return result; } int writev(fd, iov, ioveclen) int fd; struct iovec *iov; int ioveclen; { int result; char c; ++RT0u__inCritical; { int i; for (i = 0; i < ioveclen; i++) { if (iov[i].iov_len > 0) { { c = *(char*)iov[i].iov_base; *(char*)iov[i].iov_base = c; } } } } result = syscall(SYS_writev, fd, iov, ioveclen); --RT0u__inCritical; return result; } /* fork also requires special treatment, although it takes no argument. fork crashes Ultrix if some pages are unreadable, so we must unprotect the heap before calling fork */ pid_t fork() { pid_t result; pid_t me = getpid(); ++RT0u__inCritical; RTHeap__FinishVM(); result = syscall(SYS_fork); --RT0u__inCritical; if (result == me) { result = 0; } return result; }