File: fifo_writer.c | Size: 2,560 bytes | Download file | Back to directory listing | BWPOW's homepage
#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;
}