LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Help...!!! Popen() hang issue (https://www.linuxquestions.org/questions/linux-newbie-8/help-popen-hang-issue-871614/)

shankar.489 03-29-2011 12:24 AM

Help...!!! Popen() hang issue
 
hi,

iam excuting a scripts in multi-threaded environment

iam using popen()to run my script in a thread and iam waiting for my popen() to exit gracefully (using pclose())

in the script i entered a invalid command the script exited my printing some message in stderr
but my pclose() is still waiting to take script exit status...!
how can solve this issue..?!

here is my code
scriptt3.sh
exit 5 5 //invalid command

int mythread3(void*p)
{
FILE *Fp;
int status;
Fp=popen("./script3.sh","r");
status=pclose(Fp); //hanging here
printf("done\n");

if (WIFEXITED(status))
{
printf("t3exited, status=%d\n", WEXITSTATUS(status));
}
else if (WIFSIGNALED(status))
{
printf("t3killed by signal %d\n", WTERMSIG(status));
}
else if (WIFSTOPPED(status))
{
printf("t3stopped by signal %d\n", WSTOPSIG(status));
}
return 0;
}

what i can do to make it work fine..? i have to catch that exit status of script (although it is terminated by shell)

if you have any suggestion please share with me

thanks in adv

~shankar

tronayne 03-30-2011 10:35 AM

You really need to read in a loop. popen() simply opens a pipe as a file descriptor.

So,
Code:

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

int    main    (void)
{
        int    c;
        FILE    *in;

        /*      open the input pipe                    */
        if ((in = popen ("cat script3.sh", "r")) == (FILE *) NULL) {
                (void) fprintf (stderr, "popen failed\n");
                exit (EXIT_FAILURE);
        }
        while ((c = getc (in)) != EOF) {
                /*
                *      do something with what you just read
                *      here, we're just going to write to stdout
                */
                putc (c, stdout);
        }
        /*      close the input pipe                    */
        (void) pclose (in);
        exit (EXIT_SUCCESS);
}

This will read a byte at a time from the input pipe and write it on stdout (your terminal). When you run out of input, the while will exit and the pipe will be closed.

Hope this helps some.

shankar.489 03-30-2011 11:38 PM

hi tronayne,

thanks for you reply

it helped me a lot

may i know the reason why it is hanging..?!

thank you
~shankar

tronayne 03-31-2011 07:51 AM

Keep in mind the purpose of a pipe, whether in the world or in software. A pipe just sits there doing nothing until something is put into it. So, Fp=popen("./script3.sh","r"); just opens but doesn't do anything.

The purpose of popen() is to give a command line to the shell for execution, connecting its input or output to the program; thus you want to "cat filename" rather than just "filename."

If you have a large compressed data file (compressed with gzip, bzip2 or even zip), you do not need to uncompress the file to be able to do something with the data. You can simply
Code:

        /*      open the input pipe                    */
        if ((in = popen ("zcat filename.gz", "r")) == (FILE *) NULL) {
                (void) fprintf (stderr, "popen failed\n");
                exit (EXIT_FAILURE);
        }

and that will work just fine.

You may want to adopt the method shown so that your program will fail gracefully if "filename" does not exist, is not readable or some other problem exists. Better to know there's a problem before wasting a lot of time and resources trying to process something that doesn't exist, eh?

Hope this helps some.

shankar.489 04-06-2011 01:32 AM

Quote:

Originally Posted by tronayne (Post 4309574)
Keep in mind the purpose of a pipe, whether in the world or in software. A pipe just sits there doing nothing until something is put into it. So, Fp=popen("./script3.sh","r"); just opens but doesn't do anything.

The purpose of popen() is to give a command line to the shell for execution, connecting its input or output to the program; thus you want to "cat filename" rather than just "filename."

If you have a large compressed data file (compressed with gzip, bzip2 or even zip), you do not need to uncompress the file to be able to do something with the data. You can simply
Code:

        /*      open the input pipe                    */
        if ((in = popen ("zcat filename.gz", "r")) == (FILE *) NULL) {
                (void) fprintf (stderr, "popen failed\n");
                exit (EXIT_FAILURE);
        }

and that will work just fine.

You may want to adopt the method shown so that your program will fail gracefully if "filename" does not exist, is not readable or some other problem exists. Better to know there's a problem before wasting a lot of time and resources trying to process something that doesn't exist, eh?

Hope this helps some.

thanks for your info.


All times are GMT -5. The time now is 11:43 PM.