1. Introduction
What's going on
As of March 30, 1989, the Portable Common Runtime, also known as PCR, underlies all uses of Mesa or Cedar on Sun workstations. Even though PCR can live on top of Unix, it does not allow free access through to Unix. PCR is like a little operating system in itself. When using PCR, you must use the PCR system calls. Not all Unix system calls are PCR system calls (and vice versa).
As a convenience for Cedar/Mesa programmers using PCR on Unix, a number of Unix system calls have been made accessible in the UnixSysCalls interface. The implementation of this interface is NOT to directly call the Unix kernel. Most routines are implemented via a fairly complex route, via PCR IOP's. It is never safe to call the Unix kernel directly from PCR or PCedar.
See UnixSysCallExtensions for some interesting PCR system calls that are not Unix system calls. See below for why not all Unix system calls are available in UnixSysCalls. See UIO.h for the C-language interfaces directly into the PCR Unix system call emulations.
General Principles for inclusion/exclusion in
UnixSysCalls
Three principles were used in choosing to include or exclude a Unix system call in UnixSysCalls. The meta-principle is: include as little as possible.
Principle 1: If it is obsolete or can be emulated via other calls, don't include it (Ex: CREAT is obsolete, and can be emulated by OPEN.)
Principle 2: If it is available only to the super user, or affects only global Unix state, or is a brash and bold Unixism, don't include it. (Ex: MOUNT.)
Principle 3: If its use would interfere with the PCR kernel implementation, or simply will not work given the PCR implementation, don't include it, or implement only a non-interfering subset. (Ex: FLOCK cannot work with multiple VP's, only a subset of POLL is implemented.)
There is also a sub-principle, which is: some things are hard, and they are not done yet, but perhaps they won't be necessary for a while.
Principle 1 follows immediately from the meta-principle, and will not be explained further.
Principle 2 is more subtle, and stems from the philosophy that PCR, Cedar, and Mesa are sharing the machine with other programs. Therefore, it is not necessary that every system call be available--one always can execute a regular Unix program (via UnixSysCallExtensions.Spawn) to get at the others. Furthermore, it is undesirable to do things which affect the global Unix system state. System calls which affect or detect a property of a single Unix heavy-weight process are also generally not implemented, because PCR is a long-lived amalgam of multiple Unix processes and does not make sense to probe or alter the state of just one of those.
Finally, principle 3 reflects a bit of the PCR implementation showing through. PCR implemented on Unix reserves some Unix features for its own use (like passing around file descriptors via Unix domain sockets), because if others also try to use them it can get very confused.
Workarounds
For workarounds, the following general rules apply: workarounds for calls excluded by principle 1 are specified in the descriptions below. For calls excluded by principle 2, the workaround is almost always to use UnixSysCallExtensions.Spawn to use a real Unix process. For calls excluded by principle 3, workarounds are very very hard, in some cases impossible, and should not be counted on.
2. Detailed explanation of unimplemented system calls
System calls not implemented because they are obsolete or can be emulated (principle 1)
CREAT - obsolete, see OPEN.
GETDIRENTRIES - obsolete, see GETDENTS.
RECVMSG - most uses can be emulated with RECV or RECVFROM. Use of RECVMSG to send or receive a Unix file descriptor is reserved to PCR itself.
SENDMSG - most uses can be emulated with SEND or SENDTO. Use of RECVMSG to send or receive a Unix file descriptor is reserved to PCR itself..
SELECT - can be emulated with POLL. Furthermore, is hard.
UNAME - can be emulated with gethostname.
System calls not implemented because they are Unixisms (principle 2)
ACCESS - depends on properties of a single Unix heavy-weight process.
ACCT - can only be executed by super user, and affects global Unix state.
ADJTIME - can only be executed by super user, and affects global Unix state.
AUDIT - can only be executed by super user, and affects global Unix state.
AUDITON - can only be executed by super user, and affects global Unix state.
AUDITSVC - can only be executed by super user, and affects global Unix state.
CHDIR - affects the properties of a single Unix heavy-weight process.
CHOWN, FCHOWN - can only be executed by super user.
CHROOT - can only be executed by super user.
GETAUID, SETAUID - can only be executed by super user.
GETPRIORITY, SETPRIORITY - samples and affects the properties of a single Unix heavy-weight process.
GETRLIMIT, SETRLIMIT - samples and affects the properties of a single Unix heavy-weight process.
GETRUSAGE - samples and affects the properties of a single Unix heavy-weight process.
SETGROUPS - can only be executed by super user, affects the properties of a single Unix heavy-weight process.
SETHOSTNAME - can only be executed by super user, affects global Unix state.
SETTIMEOFDAY - can only be executed by super user, affects global Unix state.
MOUNT, UNMOUNT - can only be executed by super user, affects global Unix state.
MSYNC - can only be executed by super user, affects global Unix state.
MSGCTL, MSGGET, MSGOP - these are the System V interprocess communication primitives. They are not needed within PCR tasks, where shared memory, monitors, and condition variables work much better. For communicating with other Unix processes outside PCR, we recommend FIFO files.
PIPE - this is the original Unix interprocess communication primitives. They are not needed within PCR tasks, where shared memory, monitors, and condition variables work much better. For communicating with other Unix processes outside PCR, we recommend FIFO files.
PTRACE - this monitors one Unix heavy-weight process from another.
QUOTACTL - can only be executed by super user, affects global Unix state.
REBOOT - can only be executed by super user, affects global Unix state.
SEMCTL, SEMGET, SEMOP - these are the System V semaphor primitives. They are not needed within PCR tasks, where shared memory, monitors, and condition variables work much better. Furthermore, blocking on a semaphor would block the entire PCR world. For communicating with other Unix processes outside PCR, we recommend FIFO files.
SETPGRP - affects the properties of a single Unix heavy-weight process.
SETREGID, SETREUID - samples and affects the properties of a single Unix heavy-weight process.
SETUSERAUDIT - can only be executed by super user, affects global Unix state.
SIGBLOCK, SIGPAUSE, SIGSETMASK, SIGSTACK, SIGVEC - these sample and control Unix signals, which are nothing like Cedar/Mesa signals. Unix signals make sense only in a single Unix heavy-weight process, and only one without threads.
SWAPON - can only be executed by super user, affects global Unix state.
UMASK - affects the properties of a single Unix heavy-weight process.
VADVISE - affects the virtual memory paging algorithm of a single Unix heavy-weight process.
VHANGUP - this releases a Unix control terminal. This should not have any meaning in PCR, so should not be necessary.
WAIT, WAIT3, WAIT4 - causes one Unix process to hang waiting for, or check the status of, another Unix process. See UnixSysCallExtensions.Spawn for how to do an implicit fork/wait safely from a PCR thread.
System calls not implemented because they will not work with PCR (principle 3)
BRK, SBRK - allocates storage in a single Unix heavy-weight process. All allocation must be via PCR allocation primitives.
DUP, DUP2 - duping a file descriptor can sometimes interfere with PCR's need to use non-blocking I/O, because the duped descriptor sometimes does, and sometimes doesn't, inherit the non-blocking properties.
EXECVE - reads a new executable image on top of an existing Unix heavy-weight process. PCR owns all the heavy-weight processes, cannot permit itself to be overwritten.
EXIT - terminates the current Unix heavy-weight process. PCR owns all the heavy-weight processes, cannot allow one to terminate.
FCNTL - The full properites of FCNTL would permit the user to thwart PCR's control of file descriptor properties which it needs for the IOP implementation. A subset of FCNTL semantics could be permitted, but is not now implemented or planned.
FLOCK - this locks a file for access by a single Unix heavy-weight process. Since PCR is multiple such processes, it could deadlock itself by letting one lock out others.
FORK, VFORK - makes a new Unix heavy-weight process. PCR owns all the heavy-weight processes, cannot permit a new one. However, see UnixSysCallExtensions.Spawn for a way to do the same thing from a light-weight process.
GETITIMER, SETITIMER - PCR uses the interval timer for itself. Process.Pause, and XR←TicksSinceBoot and timeouts on condition variables have a granularity of about 100ms and should be adequate for most uses.
IOCTL - this is in the interface, but use is extremely dangerous, only some uses will work, but no checking is made of those uses. Avoid IOCTL if at all possible, and then only use with permission of the PCR implementors.
MMAP, MUNMAP, MPROTECT - change virtual memory mapping. These affect only a single heavy-weight Unix process, but even worse, PCR uses mapping and unmapping for its own internal purposes, and needs to know who is doing what.
NFSSVC, ASYNCDAEMON - causes the current Unix heavy-weight process to dive forever into the kernel. PCR owns all the heavy-weight processes, doesn not like them diving away forever.
SHMCTL, SHMGET, SHMOP - these are the System V shared memory mapping primitives. These affect only a single heavy-weight Unix process, but even worse, PCR thinks it owns the map.
SOCKETPAIR - this one could be done, but hasn't been.
SYSCALL - this is an escape hatch to all the other calls, so cannot be permitted.