Reputation: 21
I'm coding a program in which a parent is executing function and needs to write the results of these function to a pipe. The child has to read the pipe and put everything in a logging file. I forked the parent (which uses the function fifomanager_write(), see below) and the child uses the function fifomanager_write() (see below). I opened a fifo using mkfifo (using FIFO_NAME). I close the fifo file everytime I exit the function but valgrind still mentiones that there are file desriptors open after exiting the programme (see below). Can somebody explain based on my code if I'm missing something?
void fifomanager_read()
{
int sequencenumber = 1;
char recv_buf[MAX];
FILE*fp;
fp = fopen(FIFO_NAME, "r");
CHECK_FIFOOPEN(fp);
FILE*logfile;
logfile = fopen(FIFO_LOG, "a");
CHECK_FIFOOPEN(logfile);
fprintf(logfile, "start of new log\n");
do
{
fp = fopen(FIFO_NAME, "r");
CHECK_FIFOOPEN(fp);
if ( fgets(recv_buf, MAX, fp) != NULL )
{
#ifdef DEBUG
printf("Message received: %s", recv_buf);
#endif
//print to log file
fprintf(logfile,"%d %ld %s",sequencenumber, time(NULL), recv_buf);
sequencenumber++;
}
} while(strcmp(recv_buf, "End of logging process\n")!=0);
int result = fclose( logfile );
CHECK_FIFOCLOSED(result);
result = fclose( fp );
CHECK_FIFOCLOSED(result);
#ifdef DEBUG
printf("both files closed \n");
#endif
}
void fifomanager_write(char*recv_buf)
{
FILE*fp;
fp = fopen(FIFO_NAME, "w");
CHECK_FIFOOPEN(fp);
//put a lock as you are putting values in the fifo
pthread_mutex_lock(&fifolock);
if ( fputs( recv_buf, fp ) == EOF )
{
fprintf( stderr, "Error writing data to fifo\n");
exit( EXIT_FAILURE );
}
FFLUSH_ERROR(fflush(fp));
#ifdef DEBUG
printf("Message send: %s", recv_buf);
#endif
//close fifo
int result = fclose(fp);
CHECK_FIFOCLOSED(result);
pthread_mutex_unlock(&fifolock);
}
************* RESULT ************
FILE DESCRIPTORS: 13 open at exit.
==3503== Open file descriptor 13: MYFIFO
==3503== at 0x4AC5EAB: open (open64.c:48)
==3503== by 0x4A48195: _IO_file_open (fileops.c:189)
==3503== by 0x4A48459: _IO_file_fopen@@GLIBC_2.2.5 (fileops.c:281)
==3503== by 0x4A3AB0D: __fopen_internal (iofopen.c:75)
==3503== by 0x4A3AB0D: fopen@@GLIBC_2.2.5 (iofopen.c:86)
==3503== by 0x10AF08: fifomanager_read (in /home/rikvandevelde/labfinal/Lab8/sensor_gateway)
==3503== by 0x10AADB: run_child (in /home/rikvandevelde/labfinal/Lab8/sensor_gateway)
==3503== by 0x10AA87: main (in /home/rikvandevelde/labfinal/Lab8/sensor_gateway)
==3503==
==3503== Open file descriptor 12: MYFIFO
==3503== at 0x4AC5EAB: open (open64.c:48)
==3503== by 0x4A48195: _IO_file_open (fileops.c:189)
==3503== by 0x4A48459: _IO_file_fopen@@GLIBC_2.2.5 (fileops.c:281)
==3503== by 0x4A3AB0D: __fopen_internal (iofopen.c:75)
==3503== by 0x4A3AB0D: fopen@@GLIBC_2.2.5 (iofopen.c:86)
==3503== by 0x10AF08: fifomanager_read (in /home/rikvandevelde/labfinal/Lab8/sensor_gateway)
==3503== by 0x10AADB: run_child (in /home/rikvandevelde/labfinal/Lab8/sensor_gateway)
==3503== by 0x10AA87: main (in /home/rikvandevelde/labfinal/Lab8/sensor_gateway)
Upvotes: 2
Views: 1313
Reputation: 5502
fp = fopen(FIFO_NAME, "r");
...
do
{
fp = fopen(FIFO_NAME, "r");
...
} while (strcmp(recv_buf, "End of logging process\n") != 0);
...
result = fclose(fp);
You are not closing the fp
s you fopen
throughout your do-while
loop - only the last one - and you are overriding the first fp
you opened.
For future reference: when compiling with -g
, valgrind can output very useful debugging information - such as a stacktrace with line numbers that can show where leaked memory was allocated. This can help you find the source of memory leaks very quickly.
Upvotes: 5