Posix

File IO

// 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);

Directory IO

// 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);

Metadata IO

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)

Processi

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:

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

Segnali

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

IPC

Pipes

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

FIFO/named pipes

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

Message queues

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

Shared memory

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

Threads

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