0

I'm new to C language and today, i am facing a problem while i am trying to close the "Open Stream" created by using the popen function. 1. Is this problem seeing, because of the poll function that i used in this program? 2. Or because of the fcntl function? I will be very happy, if somebody teach me the exact cause of this issue. I am attaching the code sample below, please have a look.

Code Sample:

#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#include <fcntl.h>

char line[1024];
FILE *tfd;

int readData(int *fd)
{
     struct pollfd pfd;
     int pollTime = 10000;
     pfd.events = POLLIN;
     pfd.fd = *fd;
     int ret=1;

     ret = poll(&pfd,1,pollTime);
     printf("\nAfter ret=%d\n.",ret);
     if(ret == -1 || ret ==0)
        {
                printf("Couldn't poll returned : %d\n", ret);
                return 0;
        } else {
                if( fgets(line,sizeof(line),tfd) == NULL )
                {
                        printf("\nReturns nothing.");
                        return 0;
                }
                printf("\nRead Some data.");
        }
        return ret;
}


void main(void)
{
        int ret;
        int fd, flags;
        char filepath[] = "/home/TEST/";
        char filename[] = "log.txt";
        char cmd[100];

        sprintf(cmd,"tail -f %s%s",filepath, filename);
        tfd = popen(cmd, "r");
        fd  = fileno(tfd);

        flags = fcntl(fd, F_GETFL, 0);
        flags |= O_NONBLOCK;
        fcntl(fd, F_SETFL, flags);

        if(tfd==NULL)
        {
                printf("\npopen failed, exiting.\n");
                exit(0);
        }
        while( (ret=readData(&fd)) > 0 )
        {
                printf("\nret2=%d.",ret);
                printf("\nLine : %s",line);
        }
        printf("\n**********DONE****************.\n");
        pclose(tfd);
}

output:

[root@localhost TEST]# ./polltail

After ret=1
.
Read Some data.
ret2=1.
Line : 64 bytes from maa03s05-in-f4.1e100.net (74.125.236.68): icmp_req=31 ttl=52 time=38.4 ms

After ret=0
.Couldn't poll returned : 0

**********DONE****************.

Here i am expecting the prompt to appear at the end of the execution. But, it is not coming.

AusCBloke
  • 18,014
  • 6
  • 40
  • 44
Sougrakpam
  • 83
  • 1
  • 3
  • 11

2 Answers2

1

You're getting a timeout, because tail didn't produce any output for 10 seconds. Then you call pclose() , however, this is what the documentation says about pclose().

The pclose() function waits for the associated process to terminate and returns the exit status of the command as returned by wait4(2).

The tail command is still running, and will continue to do so until someone kills it, so pclose() will block indefinitely. If you need your program to kill the tail command you're running, you'll need another approach than using popen/pclose.

nos
  • 223,662
  • 58
  • 417
  • 506
  • Hi nos, thanks for very quick response. How do I get this tail pid or kill this tail process before closing the stream file. – Sougrakpam Jul 04 '12 at 20:54
  • 1
    You'd need to create and run the child program yourself using fork()/exec() and set up the filedescriptors to communicate with stdin/out/err of the child program using pipe() and dup2() . An book on unix programming would be most suitable as i'll contain examples and explain such concepts. – nos Jul 04 '12 at 20:58
1

The -f option causes tail to not stop when end of file is reached, but rather to wait for additional data to be appended to the input. The -f option is ignored if the standard input is a pipe, but not if it is a FIFO.

The pclose() function waits for the associated process to terminate; it returns the exit status of the command, as returned by wait4(2).

The pclose() function returns -1 if stream is not associated with a "popened" command, if stream already "pclosed", or if wait4(2) returns an error.

Check the return value of pclose().

  • Hi, thanks for very quick response. How do I get this tail pid or kill this tail process before closing the stream file. – Sougrakpam Jul 04 '12 at 20:54