# Lista 5
###### tags: `SO`
## Zadanie 1
**Co robi operacja read(2) i write(2), jeśli bufor rury jest odpowiednio pusty albo pełny?**
Pusty:
- read : blokuje się
Pełny:
- write : blokuje się
**Jakie gwarancje daje nam
operacja write na rurze, do której pisze wiele procesów – każdy z nich wiersze tekstu nie dłuższe niż
«PIPE_BUF»?**
Gwarancję zapisu atomowego.
A i B -> AB lub BA, nigdy A1B1A2B2
**Czemu wszystkie procesy należące do potoku zakończą się bez interwencji powłoki, jeśli co najmniej jeden z nich umrze??**
Czytające procesy dostają EOF. (zwijanie w prawo)
Procesy piszące dostają SIGPIPE. (zwijanie w lewo)
**Kiedy operacje read i write na rurze zwracają „short count”?**
Tylko wtedy, kiedy nie ma więcej danych.
(potok piszący został zamknięty)
**Jak można połączyć rodzica i dziecko rurą, która została utworzona po uruchomieniu dziecka?**
```c=
#include "csapp.h"
int main(int argc, char *argv[]) {
char * myfifo = "/tmp/myfifo";
pid_t pid = Fork();
mkfifo(myfifo, 0666);
char buf[10];
int fd;
if(pid){
fd = open(myfifo, O_RDONLY);
read(fd, buf, 10);
buf[9] = '\0';
printf("READ: %s\n", buf);
} else{
fd = open(myfifo, O_WRONLY);
write(fd,"012345678",9);
}
close(fd);
return EXIT_SUCCESS;
}
```
## Zadanie 2
## Zadanie 3

Usuwanie - powiększenie entry size
Dodanie - znalezienie luki odpowiedniego rozmiaru
Kompaktowanie wykonywane jest po osiągnięciu krytycznej ilości nieużytków.
## Zadanie 4
## Zadanie 5
## Zadanie 6
```c=
static noreturn void filter_chain(pipe_t in) {
long prime;
/* TODO: Something is missing here! */
if (!ReadNum(in, &prime)) {
CloseReadEnd(in);
exit(EXIT_SUCCESS);
}
printf("%ld\n", prime);
pipe_t gen_pipe = MakePipe();
if(Fork()) { /* Parent */
CloseReadEnd(gen_pipe);
filter(in, gen_pipe, prime);
CloseWriteEnd(gen_pipe);
Wait(NULL);
}
else { /* Child */
CloseWriteEnd(gen_pipe);
filter_chain(gen_pipe);
}
CloseReadEnd(in);
exit(EXIT_SUCCESS);
}
```
lsof | grep "prime"
## Zadanie 7
```c=
static void Sort(int parent_fd) {
int nelem = ReadNum(parent_fd);
if (nelem < 2) {
WriteNum(parent_fd, ReadNum(parent_fd));
Close(parent_fd);
return;
}
sockpair_t left = MakeSocketPair();
/* TODO: Spawn left child. */
int left_elem = nelem / 2;
if(Fork()) { /* Parent */
Close(left.child_fd);
}
else { /* Child*/
Close(left.parent_fd);
Sort(left.child_fd);
return;
}
sockpair_t right = MakeSocketPair();
/* TODO: Spawn right child. */
int right_elem = nelem - left_elem;
if(Fork()) { /* Parent */
Close(right.child_fd);
}
else { /* Child*/
Close(right.parent_fd);
Sort(right.child_fd);
return;
}
/* TODO: Send elements to children and merge returned values afterwards. */
SendElem(parent_fd, left.parent_fd, left_elem);
SendElem(parent_fd, right.parent_fd, right_elem);
Merge(left.parent_fd, right.parent_fd, parent_fd);
/* Wait for both children. */
Wait(NULL);
Wait(NULL);
}
```
```c=
sockpair_t left = MakeSocketPair();
/* TODO: Spawn left child. */
if(!Fork()){
Close(left.parent_fd);
Sort(left.child_fd);
return;
}
sockpair_t right = MakeSocketPair();
/* TODO: Spawn right child. */
if(!Fork()){
Close(right.parent_fd);
Sort(right.child_fd);
return;
}
int nLeft = nelem / 2;
int nRight= nelem - nLeft;
Close(left.child_fd);
Close(right.child_fd);
SendElem(parent_fd,left.parent_fd, nLeft);
SendElem(parent_fd,right.parent_fd, nRight);
Merge(left.parent_fd,right.parent_fd,parent_fd);
```