title: How to implement a FIFO log file?
body: <p>I am trying to use a FIFO file to store buffered log entries for my application if the network connection is lost. I thought when reading from a FIFO file it would be deleted completely thus it would be "popped" from the log queue. </p>
  
  <p>However, my approach kept logging reading the same text indefinitely. Perhaps it would be easier to read all entries into a buffer and try to log them to the database and write back all entries that couldn't be logged.</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;sys/stat.h&gt;
  
  /**
   * First argument is the filename
   * Second argument is the log message
   * Third argument is the severity
   */
  int main(int argc, char **argv) {
    int err, severity;
    char c;
    char *fifoName = "/tmp/bufferedlog";
    char src[100], msg[100];
    FILE *fp;
  
    /**
     * if the program has exactly three arguments it will push
     * a new log entry to the queue.
     */
    if(argc == 3) {
      fp = fopen(fifoName, "w");
      if(fp == NULL) {
        err = mknod(fifoName, S_IFIFO | 0600, 0);
        if(err &lt; 0){
          fprintf(stderr, "Unable to create fifo: %s\n",fifoName);
          exit(EXIT_FAILURE);
        }
        fp = fopen(fifoName, "w");
        if(fp == NULL) {
          fprintf(stderr, "Unable to open fifo for writing\n");
          exit(EXIT_FAILURE);
        }
      }
      fprintf(fp, "\"%s\" \"%s\" %d ","My Application", argv[1], atoi(argv[2]));
      fflush(fp);
      fclose(fp);
      return 0;
    }
  
    fp = fopen(fifoName, "r");
    if(fp == NULL) {
      fprintf(stderr, "Unable to open fifo for reading\n");
      exit(EXIT_FAILURE);
    }
  
    /**
     * it will now try to read the log entry from the fifo file.
     */
    while(1) {
      if(fscanf(fp,"\"%[^\"]\" \"%[^\"]\" %d", src, msg, &amp;severity) &lt; 0) { // ignore the overflow bugs
        goto finish;
      }
  
      fprintf(stdout, "Do you really want to log \"%s (%d):%s\" to database [y/n]?\n", src, severity, msg);
      scanf(" %c",&amp;c);
      if(c=='y') {
        /* logs to database here */
        /* if it fails to log to database it will break out of this loop */
        fprintf(stdout, "Pushed log entry to database.\n");
      }else {
        goto finish;
      }
    }         
    fclose(fp);
    fp = fopen(fifoName, "w");
  
    /**
     * if the database connection failed it fill put the log entry back into
     * the queue and try again when the program starts next time.
     */
    if(fp == NULL) {
      fprintf(stderr, "Unable to open fifo for writing\n");
      exit(EXIT_FAILURE);
    }
    fprintf(fp, "\"%s\" \"%s\" %d ", src, msg, severity);
    fflush(fp);
    finish:
    fclose(fp);
    return 0;
  }
  </code></pre>
  
  <p>Please ignore the overflow bugs with scanf. My attempt doesn't work, here is the psuedocode of my program.</p>
  
  <pre><code>if argc is equal to three then
    write log entry to fifo file
  end
  while there is data in fifo file do
    read log entry from fifo file and delete it from fifo file
    try logging entry to database
    if failed then
      break out of while loop
    end
  end
  write log entry back to fifo file
  </code></pre>