Chapter 20
POSIX Interface Library: liboskit_posix.a

20.1 Introduction

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.

20.2 Modified Functions

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.

20.2.1 getdtablesize: get descriptor table size

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.

20.2.2 mmap, munmap, mprotect: map files into memory

The default mmap implementation is extremely limited in its capabilities. Anonymous memory requests are satisfied using malloc. The combination of MAP_PRIVATE and PROT_WRITE is not supported. Beyond that, the underlying file or device must provide the oskit_openfile COM interface. A secondary mmap implementation is provided when the Simple Virtual Memory module is linked in. Anonymous memory requests are satisfied with svm_alloc and mprotect chains to svm_protect. See Section 27 for more details.

20.2.3 getpid: get process id

getpid always returns zero since there is no concept of “process” in a standalone OSKit application.

20.2.4 gettimeofday: get current time

Timing functions such as gettimeofday are mapped to the (currently undocumented) oskit_clock COM interface. In essence, this interface is a very natural adaptation of the POSIX.1 real-time extensions.

20.3 POSIX Message Queue and Semaphore


#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.

20.4 POSIX Signals

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).

20.5 Client Operating System Dependencies

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:

20.5.1 _exit

The _exit call, which terminates the calling process in Unix, indirects through the oskit_libcenv_t COM object to the client OS defined reboot mechansim. While the exit status code is passed along, it is generally ignored.

20.5.2 Console Stream

The console stream satisfies reads and writes (among others) to and from the three lowest numbered file descriptors, which are typically the application’s stdin, stdout, and stderr descriptors. The client OS needs to provide a console stream COM object in order for the application to interact with the console.

20.5.3 Filesystem Namespace

As described above, access to the filesystem namespace is is provided by the client OS. The POSIX library uses the namespace COM object to translate multi component pathnames (paths with ’/’ in them) into oskit_file and oskit_dir references. The namespace object also provides symbolic link translation and mountpoint traversal (see Section 23).

20.5.4 System Clock

The “system clock” is an oskit_clock COM object that provides time of day functions and periodic timer support, such as required by gettimeofday, setitimer and select.

20.5.5 Socket Factory

The socket and socketpair calls require the oskit_socket_factory_t COM interface to create sockets and socketpairs. The socketfactory is created when the clientos initializes the network stack during system initialization.

20.6 Extended API functions

20.6.1 fs_mount, fs_unmount: Compose file system name spaces


#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).

A valid pathname in the current file system space where the file system should be added or removed.
The root of the file system to be added. A reference to subtree is acquired.

Returns zero on success, or an appropriate error code.