// Ritorna il fd, o -1 on error. Flags: O_RDONLY, O_WRONLY, O_RDWR
int open(char *path, int flags);
int close(int fd);
// Ritorna il numero di byte letti/scritti, o 0 se EOF, o -1 on error
int read(int fd, void *buf, size_t nbytes);
int write(int fd, boid *buf, size_t nbytes);
// Whence = SEEK_SET/SEEK_CUR/SEEK/END (inizio/pos. attuale/fine)
off_t lseek(int fd, off_t offset, int whence);
// Get current working directory
char *getcwd(char *buf, int size);
// Change working directory
int chdir(char *path);
int mkdir(char *path, mode_t mode);
int rmdir(char *path);
// Open dir for reading
DIR *opendir(char *filename);
int closedir(DIR *dp);
// Read directory
struct dirent *readdir(DIR *dp);
int stat(char *path, struct stat *sb); // Da un path
int fstat(int fd, struct stat *sb); // Da un fd
#define S_ISREG(sb.st_mode)
#define S_ISDIR(sb.st_mode)
pid_t getpid(); // Own pid
pid_t getppid(); // Parent pid
// Create child process. Returns child PID in parent, 0 in child PID
pid_t fork();
Quando un processo termina il kernel manda SIGCHLD
al parent. Posso gestire i children:
SIGCHLD
wait()
/waitpid()
Se un child termina senza che il parent abbia chiamato wait()
è uno zombie: continua a esistere.
Se un parent termina prima del child, il child viene ereditato da init
.
// Blocca fino a che *almeno un* child termina, poi ritorna il suo exit code
pid_t wait(int *exit_code);
pid_t waitpid(pid_t pid, int *exit_code);
// Execute new process and replace current process image with that one
int execve(char *path, char *argv[], char *envp[]);
// Fork a shell, run the command and return the exit code
int system(char *cmd);
Massimo un segnale in attesa (sent but not delivered) per tipo.
// Register signal handler
signal(int sig, (int -> void) handler);
// Send signal to process
int kill(pid_t pid, int sig);
// Wait for any signal
int pause();
// Receive SIGALRM after some time
uint alarm(uint seconds);
Half-duplex (P1 -> P2 o P2 -> P1 ma non entrambi contemporaneamente) basato su fd (-> read()/write()).
// Scrivo su fd[1], leggo su fd[0]
int pipe(int fd[2]);
Di norma un processo crea un pipe, forka, e usa fd[1] nel parent per scrivere al child e fd[0] nel child per leggere dal parent. Ciascuno legge il lato che non usa (il parent fa close(fd[0])
, il child fa close(fd[1])
).
pipe
+system
=popen
: crea un pipe, forka, e nel child process esegue una shell con un pipe collegato.
// type = "r" se voglio leggere stdout, "w" se voglio scrivere in stdin
FILE *popen(char *cmd, char *type);
FILE *pclose(FILE *fp);
Comunicazione tra processi arbitrari tramite un file. Una volta aperto da entrambi i lati posso usare read()
e write()
.
int mkfifo(char *path, mode_t mode);
Passo dati strutturati, a differenza dei FIFO che sono stream non strutturati.
Serve una key che identifica la message queue:
// Il path deve esistere; l'id è arbitrario
key_t ftok(char *path, int id);
// Create queue or use existing; returns message queue identifier "msqid"
int msgget(key_t key, int flag);
// cmd values: IPC_STAT = fetch msqid_ds for this structure
// IPC_SET = set uid, gid, mode, qbytes from msqid_ds
// IPC_RMID = remove mq
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
// Send nbytes data starting at ptr
int msgsnd(int msqid, void *ptr, size_t nbytes, int flag);
// Receive nbytes data at ptr
int msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag);
Richiede di sincronizzare l'accesso tra processi (es. con semafori). Identificata da un key_t
.
// Alloca size bytes di shm e ne ritorna l'identifier (non il puntatore!)
int shmget(key_t key, size_t size, int flag);
// Vedi msgctl
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
// Aggiunge la shm all'address space del processo e ritorna il puntatore
// Con addr posso opzionalmente scegliere l'indirizzo dove aggiungerla, in alternativa sceglie il kernel
void *shmat(int shmid, void *addr, int flag);
// Detach shm
int shmdt(void *addr);
int pthread_create(pthread_t *tid, NULL, (void* -> void*) start, void *arg);
void pthread_exit(void *ptr); // Exit the current thread
int pthread_cancel(pthread_t tid); // Terminate the target thread
pthread_t pthread_self();
int pthread_join(pthread_t tid, void **ptr);
int pthread_detach(pthread_t tid); // Declare tid as detached