Description of CROCOS system calls and conventions

1. Idle and init tasks
2. Process management system calls
getpid
fork
execve
_exit
wait
signal
kill
3. File system operations
stat
open
close
fstat
lseek
read
readdir
4. Memory system calls
5. Special files
/proc file system

CROCOS is a UNIX-like kernel, and thus, tries to follow traditional (but often simplified) UNIX conventions.

This document describes the system calls implemented by the CROCOS kernel as well as useful information and conventions for developing user-space programs run by CROCOS.

1. Idle and init tasks

CROCOS is a multitask operating system. Up to 32 processes can run simultaneously. However, only 30 user processes can run at a given time. Indeed, two special processes (the idle task and the init task) are always running. These processes are launched just after the kernel initialization.

The process 0 is the idle task. It runs whenever no other process can run. In a "real" kernel, the idle process simply waits to be interrupted. While CROCOS is run inside a Linux process, the idle task shuts the system down (stops the kernel process) once it is resumed.

The process 1 is the init task. It creates an other process (process 2) which will run execve on a user-defined function. By convention, this user-defined function is called start_test in the first development phases of CROCOS (because it basically starts a test program). Then, the init task is responsible to adopt any zombie orphan process and run wait system calls to free kernel resources used by those zombies.

If the init task is killed (if an other process sends it a SIGKILL signal for example), the system is shut down.

2. Process management system calls

getpid

Added in phase 2.1

Synopsys:

#include "crocos/syscall.h"

int getpid ();

Return:

Return the pid of the running process.

fork

Added in phase 2.1

Synopsys:

#include "crocos/syscall.h"

int fork ();

Description:

Fork a process (create a new process by duplicating the calling process).

Return:

In the parent, return the child pid or -1 in case of error.

Errors:

• ENOMEM if no more process can be created by the kernel.

execve

Added in phase 2.1

Synopsys:

#include "crocos/syscall.h"

typedef int (*fn_ptr) (int argc, char *const argv[], char *const envp[]);
int execve (fn_ptr func, char *const argv[], char *const envp[]);

Description:

Clean the current execution context and execute a function. Arguments and environment variables are copied into the stack of the process. The function called is equivalent to the "main" function of a program.

Return:

Return -1 in case of error. Nerver return otherwise.

Errors:

• E2BIG if the total size for argv+envp is too big.

_exit

Added in phase 2.1

Synopsys:

#include "crocos/syscall.h"

void _exit (int status);

Description:

Terminate the running process with an exit status (given in parameter).

Return:

Never return.

wait

Added in phase 2.2

Synopsys:

#include "crocos/syscall.h"

int wait (int *status);

Description:

Suspend the running process until one of its children terminates. The status variable is filled with the exit status of the child (see _exit function above). The status can then be checked with the following macros:

• WIFEXITED:

retun true if the process terminated normally.

• WIFSIGNALED:

return true if the process was terminated by a signal.

• WEXITSTATUS:

exit status (valid only if WIFEXITED(status) is true).

• WTERMSIG:

signal which caused the process to terminate (valid only if WIFSIGNALED(status) is true).

Return:

Return the pid of the terminated child or -1 in case of error.

Errors:

• ECHILD if the process doesn’t have any children.

signal

Added in phase 2.3

Synopsys:

#include "crocos/signal.h"
#include "crocos/syscall.h"

typedef void (*sighandler_t) (int signum);
int signal (int signum, sighandler_t handler);

Description:

Set a signal handler for a given signal number. If the handler is SIG_IGN, the signal is ignored. If the handler is SIG_DFL, the default action is associated to the signal. SIGKILL and SIGSTOP cannot be caught or ignored.
The following signals are defined:

• SIGHUP:

hangup detected on controlling terminal or death of controlling process

• SIGINT:

interrupt from keyboard

• SIGQUIT:

quit from keyboard

• SIGILL:

illegal instruction

• SIGABRT:

abort signal

• SIGFPE:

floating point exception

• SIGKILL:

kill signal

• SIGUSR1:

user-defined signal 1

• SIGSEGV:

invalid memory reference

• SIGUSR2:

user-defined signal 2

• SIGPIPE:

broken pipe: write to pipe with no readers

• SIGALRM:

timer signal

• SIGTERM:

termination signal

• SIGCHLD:

child stopped or terminated

• SIGCONT:

continue if stopped

• SIGSTOP:

stop process

• SIGTSTP:

stop typed at tty

• SIGTTIN:

tty input for background process

• SIGTTOU:

tty output for background process

Return:

Return -1 in case of error, 0 otherwise.

Errors:

• EINVAL if the signal number is invalid.

kill

Added in phase 2.3

Synopsys:

#include "crocos/signal.h"
#include "crocos/syscall.h"

int kill (int pid, int signum);

Description:

Send a signal to a given process. If pid is 0, the process sends the signal to itself. If the signal number is 0, no signal is sent but error checking is performed.

Return:

Return -1 in case of error, 0 otherwise.

Errors:

• EINVAL if the signal number is invalid.
• ESRCH if the pid is invalid.

3. File system operations

stat

Added in phase 3.1

Synopsys:

#include "crocos/stat.h"
#include "crocos/syscall.h"
#include "crocos/types.h"

int stat (const char *path, struct stat *buf);

Description:

Return information about a file by filling the stat structure, defined as follow:

struct stat {
    dev_t     st_dev;     /* ID of device containing file */
    ino_t     st_ino;     /* inode number */
    mode_t    st_mode;    /* protection */
    nlink_t   st_nlink;   /* number of hard links */
    uid_t     st_uid;     /* user ID of owner */
    gid_t     st_gid;     /* group ID of owner */
    dev_t     st_rdev;    /* device ID (if special file) */
    off_t     st_size;    /* total size, in bytes */
    blksize_t st_blksize; /* blocksize for file system I/O */
    blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
    time_t    st_atime;   /* time of last access */
    time_t    st_mtime;   /* time of last modification */
    time_t    st_ctime;   /* time of last status change */
};

Return:

Return -1 in case of error, 0 otherwise.

Errors:

• EACCES if search permission is denied for one of the directories.
• EIO if a low-level I/O error occured.
• ENAMETOOLONG if the path is too long.
• ENOENT if a component in the path is not found.
• ENOTDIR if a component in the path is not a directory.

open

Added in phase 3.2

Synopsys:

#include "crocos/syscall.h"

int open (const char *path, int flags);

Description:

Open a file. flags is one of the following access modes: O_RDONLY, O_WRONLY or O_RDWR.

Return:

Return the opened file descriptor or -1 in case of error.

Errors:

• EACCES if the requested access is not allowed or if search permission is denied for one of the directories.
• EISDIR if write access is requested on a directory.
• EIO if a low-level I/O error occured.
• EMFILE if the process reached the maximum number of files opened.
• ENAMETOOLONG if the path is too long.
• ENFILE if the system reached the maximum number of files opened.
• ENOENT if a component in the path is not found.
• ENOTDIR if a component in the path is not a directory.

close

Added in phase 3.2

Synopsys:

#include "crocos/syscall.h"

int close (int fd);

Description:

Close an opened file.

Return:

Return -1 in case of error, 0 otherwise.

Errors:

• EBADF if fd isn’t a valid file descriptor.

fstat

Added in phase 3.2

Synopsys:

#include "crocos/stat.h"
#include "crocos/syscall.h"
#include "crocos/types.h"

int fstat (int fd, struct stat *buf);

Description:

Like the stat system call (see above), except that it works on a file descriptor.

Return:

Return -1 in case of error, 0 otherwise.

Errors:

• EBADF if fd isn’t a valid file descriptor.

lseek

Added in phase 3.3

Synopsys:

#include "crocos/syscall.h"
#include "crocos/types.h"

off_t lseek (int fd, off_t offset, int whence);

Description:

Reposition the offset of an opened file according to the whence directive:
• SEEK_SET: offset set to offset bytes.
• SEEK_CUR: offset set to the current location plus offset bytes.
• SEEK_END: offset set to the size of the file plus offset bytes.

Return:

Return the resulting offset location (in bytes from the beginning of the file).

Errors:

• EBADF if fd isn’t a valid file descriptor.
• EINVAL if whence is not SEEK_SET, SEEK_CUR or SEEK_END.
• EPIPE if fd is associated with a pipe, socket or FIFO.

read

Added in phase 3.3

Synopsys:

#include "crocos/syscall.h"
#include "crocos/types.h"

ssize_t read (int fd, void *buf, size_t count);

Description:

Read up to count bytes from a file descriptor into a buffer.

Return:

Return the number of bytes read (zero indicates end of file), and advance the file position by this number. Return -1 in case of error.

Errors:

• EBADF if fd isn’t a valid file descriptor.
• EFBIG if the file is too large for the implementation.
• EINVAL if fd is an object which can’t be read.
• EISDIR if fd refers to a directory.
• EIO if a low-level I/O error occured.

readdir

Added in phase 3.4

Synopsys:

#include "crocos/direntry.h"
#include "crocos/syscall.h"

int readdir (int fd, struct direntry *dir);

Description:

Read one directory from an opened directory. The direntry structure is defined as follow:

struct direntry {
    uint32_t inode;    /* inode number */
    uint32_t name_len; /* name length */
    char name [256];   /* name */
};

Return:

Return -1 in case of error, 0 otherwise.

Errors:

• EBADF if fd isn’t a valid file descriptor.
• ENOTDIR if fd doesn’t refer to a directory.

4. Memory system calls

Nothing for the moment.

5. Special files

/proc file system

Files in the /proc file system can only be read. /proc contains one directory per allocated process in the kernel, named with the process pid.

/proc/xxx/cmd:

Command line of the process with pid=xxx.

/proc/xxx/pid:

pid of the process with pid=xxx.

/proc/xxx/ppid:

Parent pid line of the process with pid=xxx.

/proc/xxx/state:

State of the process with pid=xxx:
• R: running
• S: interruptible sleep
• T: stopped
• Z: zombie