#include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <signal.h> #include <limits.h> #define FIFO_FNAME "/tmp/moje.fifo" #define MAX_BUF 1023 volatile int koniec=0; void signal_sigpipe_handler(int signum) { printf("Prisiel prikaz SIGPIPE (signum = %d), takze ruru asi zatvoril prijimac\n",signum); } void signal_end_handler(int signum) { printf("Prisiel signal na ukoncenie (signum = %d)\n",signum); koniec=1; } int main(void) { int fd,num,num2=0; char buf[MAX_BUF+1]; // nastavime chytac na SIGPIPE, ktore nastane, ak sa pocas zapisovania zatvori rura na druhej strane signal(SIGPIPE,signal_sigpipe_handler); signal(SIGINT,signal_end_handler); signal(SIGTERM,signal_end_handler); umask(0777); if(mkfifo(FIFO_FNAME,0666)==-1){ if(errno!=EEXIST){ perror("Nepodarilo sa mi vytvorit ruru"); exit(1); } } // Otvorime ruru na zapis a zaroven ako neblokujucu. // Tu nastane -1 aj v pripade, ze prijimatel este nezacal citat z rury (nema ju nikto otvorenu ako O_RDONLY). // To je teda rozdielne chovanie oproti blokovaciemu pristupu. fd=open(FIFO_FNAME,O_WRONLY|O_NONBLOCK); if(fd<0){ perror("Nepodarilo sa mi otvorit ruru na zapis"); exit(2); } while(!koniec){ // naplnime string snprintf(buf,MAX_BUF,"< PID = %d, sprava = %d >",getpid(),num2+1); // Ideme poslat num+1 znakov. // Ak je pocet znakov mensi ako PIPE_BUF, tak by to malo byt atomicke (nemal by sa medzi to zamiesat ziaden dalsi odosielatel). // Navyse, ak nie je prave dost miesta v rure na celu spravu, tak nebude zapisane nic, vrati sa hodnota -1 a errno==EAGAIN. // Ak druha strana medzitym zavrie ruru, tak sa vrati -1 a errno==EPIPE. // Pri uspechu by to malo vratit pocet zapisanych bytov, teda v pripade, ze je vyziadana velkost mensia ako PIPE_BUF, tak // presne pocet vyziadanych bytov. printf("Posielam spravu \"%s\" (dlzka = %d bytov, PIPE_BUF = %d bytov)\n",buf,strlen(buf),PIPE_BUF); num=write(fd,buf,strlen(buf)); printf("write vratil hodnotu %d\n",num); if(num<=0){ if(errno==EAGAIN||errno==EWOULDBLOCK){ printf("Nie je dost volneho miesta v rure. Skusime neskor.\n"); if(koniec) break; sleep(1); continue; } else{ break; } } num2++; if(koniec) break; sleep(1); if(num2>=10) break; } printf("Pre istotu zatvarame ruru z nasej strany a koncime.\n"); close(fd); return 0; }