10

I have the code below that I refer the thread on here to use the popen function

int main(int argc,char *argv[]){    
    FILE* file = popen("ntpdate", "r");
    char buffer[100];
    fscanf(file, "%100s", buffer);
    pclose(file);
    printf("buffer is :%s\n", buffer);
    return 0;
}

It outputs:

21 Apr 03:03:03 ntpdate[4393]: no server can be used, exiting
buffer is:

why printf does not output anything? If I use ls as a command, then printf outputs the ls output. what am I doing wrong ntpdate executing?

If I execute the code below (referring the webpage)

#define COMMAND_LEN 8
#define DATA_SIZE 512

int main(int argc,char *argv[]){


    FILE *pf;
       char command[COMMAND_LEN];
       char data[DATA_SIZE];

       // Execute a process listing
       sprintf(command, "ntpdate");

       // Setup our pipe for reading and execute our command.
       pf = popen(command,"r");

       if(!pf){
         fprintf(stderr, "Could not open pipe for output.\n");
         return;
       }

       // Grab data from process execution
       fgets(data, DATA_SIZE , pf);

       // Print grabbed data to the screen.
       fprintf(stdout, "-%s-\n",data);

       if (pclose(pf) != 0)
           fprintf(stderr," Error: Failed to close command stream \n");

       return 0;
}

I get

21 Apr 03:15:45 ntpdate[5334]: no servers can be used, exiting
-�2}�����"|�4#|�-
 Error: Failed to close command stream 

what are wrongs on the codes above?

4

2 回答 2

19

Since the output is going to stderr you need to redirect stderr like so:

FILE* file = popen("ntpdate 2>&1", "r");

this will redirect stderr to stdout and so you will see output from both. Second issue fscanf will stop at the first space so you can replace with fgets:

fgets(buffer, 100, file);
于 2013-04-21T01:37:42.923 回答
2

As Shafik Yaghmour correctly diagnosed, the output you see from ntpdate is written (correctly) to its standard error, which is the same as your programs standard error.

To get the error messages sent down the pipe, use:

FILE *file = popen("ntpdate 2>&1", "r");

That sends the standard error output from ntpdate to the standard output of the command, which is the pipe you're reading from.

Of course, it looks like using ntpdate isn't going to work well until you've configured something.

于 2013-04-21T01:36:42.053 回答