C: Secure logging of threads to a file

I am trying to write a thread-safe C logging function and am having serious problems with the IO file. So basically, I start with an interesting call fopenthat allows me to open the log in binary update mode:

FILE *log, *start;
int timeout = 0, error;

//make file (fails if file exists)
log = fopen(LOG_FILE, "wx");

//Close the file if a new one was created
if(log)
   fclose(log);

//Open file in update mode (it must exist for this)
log = fopen(LOG_FILE, "rb+");

Then I lock the file, including the timeout, if another thread blocks it for too long:

//Init other file pointer
start = log;

//Lock file (with timeout)
rewind(start);
error = lockf(fileno(start), F_TLOCK, 0);
while( error == EACCES || error == EAGAIN)
{
  //sleep for a bit
  usleep(LOCKED_FILE_RETRY_TIME);

  //Incremement timeout
  timeout += LOCKED_FILE_RETRY_TIME;

  //Check for time out
  if(timeout > LOCKED_FILE_TIMEOUT)
  {
     return;
  }

  //Retry the lock operation
  error = lockf(fileno(start), F_TLOCK, 0);
}

And finally, I will add the necessary message to the end of the file, unlock it and close the file:

//Print log entry
fseek(log, 0, SEEK_END);
fwrite((const void*) log_msg, 1, strlen(log_msg), log);

//Unlock the block
rewind(start);
lockf(fileno(start), F_ULOCK, 0);

//Close file
fclose(log);

However, it seems that most messages are overwritten in the log, and are not added in much the same way as if they fopentook a “snapshot” of the file, waited for it to unlock, and wrote where the end of the file would have been if another process had not been added to it. Does anyone know how I can solve this problem?

, , , , , fseek R/W.

. !

+5
1

fflush() . , stdio, fclose(), , .

, fflush(log) fclose(log) .

+5

All Articles