The POSIX library adds support for what a POSIX conformant system would typically implement as system calls. These POSIX operations are mapped to the corresponding OSKit COM interfaces. Both the minimal C library (Section 14) and the FreeBSD C library (Section 21) rely on the POSIX library to provide the necessary system level operations. For example, fopen in the C library will chain to open in the POSIX library, which in turn will chain to the appropriate oskit_dir and oskit_file COM operations. All of the pathname operations, file descriptor bookkeeping, locking, and other details normally carried out in a “kernel” implementation of a system call interface, are handled by the POSIX library. Alternatively, the POSIX library bridges differences between the COM interfaces and the functions as defined by POSIX.
Since almost all of the functions and definitions provided by the POSIX library implement well-known, well-defined ANSI and POSIX C library interfaces which are amply documented elsewhere, we do not attempt to describe the purpose and behavior of each function in this chapter. Instead, only specfic peculiarities, such as implementation interdependencies and side effects, are described here.
The following set of functions are implemented, and correspond to their POSIX.1 equivalents: accept, access, bind, chdir, chmod, chown, chroot, close, connect, creat, dup, dup2, fchdir, fchmod, fchown, fcntl, fpathconf, fstat, fsync, ftruncate, getpagesize, getpeername, getsockname, getsockopt, gettimeofday, getumask, ioctl, lchown, link, listen, lseek, lstat, mkdir, mkfifo, mknod, mq_close, mq_getattr, mq_notify, mq_open, mq_receive, mq_send, mq_setattr, mq_unlink, open, pathconf, pipe, read, readlink, readv, recv, recvfrom, rename, rmdir, select, sem_close, sem_destroy, sem_getvalue, sem_init, sem_open, sem_post, sem_trywait, sem_unlink, sem_wait, send, sendto, setitimer, setsockopt, shutdown, sigaction, socket, socketpair, stat, symlink, truncate, umask, unlink, uname, utime, utimes, write, and writev.
These functions are not fully implemented, and return an error condition if called: adjtime, getdirentries, sbrk, and flock.
These functions are trivially implemented, and are primarily intended to satisfy linktime dependencies (for example, getuid always returns zero): geteuid, getuid, seteuid, setuid, getgid, and setgid.
A small number of functions have default implementations that call panic if they are executed. They are provided in order to saitisfy linktime dependencies, but should not actually be called. This is sometimes useful when converting Unix applications into OSKit kernels. They are execve, fork, vfork, wait4, and waitpid.
The getdtablesize function returns a constant value, even though there is no limit on the number of open file descriptors. This function is provided for backwards comptability with older BSD system call interfaces.
#include <oskit/c/mqueue.h>
mqd_t mq_open(const char *name, int oflag, ...);
int mq_send(mqd_t mqdes, const char *msg_ptr, oskit_size_t msg_len, unsigned int
msg_prio);
int mq_receive(mqd_t mqdes, char *msg_ptr, oskit_size_t msg_len, unsigned int
*msg_prio);
int mq_close(mqd_t mqdes);
int mq_unlink(const char *name);
int mq_setattr(mqd_t mqdes, const struct mq_attr *mqstat, struct mq_attr *omqstat);
int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat);
int mq_notify(mqd_t mqdes, const struct sigevent *notification);
The implementation of POSIX message queue depends on the pthread library and cannot be used in single threaded environment.
The message queue name space is dependent of file system name space and semaphore name space. Message queue descriptors are not related with file descriptors.
The mq_send() and mq_receive() are cancellation point.
mq_open()’s 3rd argument (mode_t) is ignored.
#include <oskit/c/semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_destroy(sem_t *sem);
sem_t *sem_open(const char *name, int oflag, ...);
int sem_close(sem_t *sem);
int sem_unlink(const char *name);
int sem_getvalue(sem_t *sem, int *sval);
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_post(sem_t *sem);
The implementation of POSIX semaphore depends on the pthread library and cannot be used in single threaded environment.
The semaphore name space is dependent of file system name space and message queue name space.
The POSIX signal interface has been implemented as best as possible, given the limitations of the OSKit environment. In fact, the multi threaded version of the POSIX/FreeBSD library provides much better functionality than the single threaded version. As described in Section 21.4, application programs can make use of some of the signal handling mechanisms contained in POSIX.1 specification. The functions that are implemented are signal, sigaction, sigprocmask, raise, kill (which just calls raise), as well as the compatibilty functions sigblock and sigsetmask. Additionally, the multi threaded version of the library implements sigwait, sigwaitinfo, and sigtimedwait. The pthread specific functions pthread_kill and pthread_sigmask are implemented in the pthreads library (see Section 29).
The POSIX library (and by extension the C library) derive a number of its external interfaces from the client OS (see Section 13). Rather than relying on linktime dependencies for these interfaces, the POSIX library uses a services database (see Section 5.1) that was provided to the C library when it was initialized. This services database is pre-loaded (by the client OS when the kernel boots) with certain COM objects that make the POSIX library functional. One such interface object is the oskit_libcenv_t COM interface, which provides hooks that are very specific to the POSIX and C libraries. This, and other interfaces, are looked up in the database as required. For example, the filesytem namespace object is provided by the oskit_libcenv_t COM object. The first file access will result in a lookup in the services database for the oskit_libcenv_t object, and then a call to oskit_libcenv_getfsnamespace to get the filesystem namespace COM object (see Section 23). If the kernel has been constructed with a filesystem, and the appropriate client OS initialization done, the call to getfsnamespace will return sucessfully. Otherwise, getfsnamespace will fail and all subsequent file operations will fail.
The intent of this “indirection” is to reduce (eventually to zero) the number of linktime dependencies between the C/Posix library and the rest of the OSKit libraries. Not only does this simplify the process of constructing an oskit kernel, but also makes it possible to do other interesting things such dynamic composition of services.
The POSIX library depends on the client OS for a number of interfaces. They are:
#include <oskit/c/fs.h>
oskit_error_t fs_mount(const char *path, oskit_file_t *subtree);
oskit_error_t fs_unmount(const char *path);
BSD-like mount and unmount functions which the client can use to build its file system namespace out of multiple file systems.
Note that the underlying oskit_dir COM interface doesn’t support mount points, so crossing mount points while traversing the file system space is implemented in the filesystem namespace COM object (see Section 23).
Returns zero on success, or an appropriate error code.