2

I have this c++ program that is doing a simple ping on a specified ip address. I am not into networking so i'm just using the system() command in c++ to execute the ping from a shell and store the results in a file, that's easy.

The problem is that i want some dots to be printed on the screen while the system() command is being executed. i tried with:

while(system(cmd))
{ 
//execute the task here
}

but no success. I think that i should create threads or something.

Can you help me ? What exactly i am supposed to do in order to get this done as i want to ?

dmckee --- ex-moderator kitten
  • 90,531
  • 23
  • 129
  • 225
ggg
  • 867
  • 5
  • 13
  • 15
  • 5
    DANGER. Nice syntax but unfortuantely it doesn't work that way. while() will execute system(cmd) anew *on* *each* *loop*! – Paul Feb 13 '10 at 20:34
  • I just realized it..Well that was just my idea after all. I am looking for some way WHILE the system(cmd) is being executed to be able to do other things. – ggg Feb 13 '10 at 20:37
  • 1
    Can you clarify what OS are you referring to? – t0mm13b Feb 13 '10 at 20:38
  • It's Linux, but putting & is not working, maybe because it's specific string being executed. I've heard of threading with linux which will enable one to manipulate with processes like the way i want. – ggg Feb 13 '10 at 20:41
  • Reading your application (to ping and print dots), a shell script, perl, or python may be more appropriate. I believe perl's system() will return a PID. Also, ping -f prints dots, but that is a flood ping and can create denial-of-service situations. – Paul Feb 13 '10 at 20:50

4 Answers4

8

The problem with system is that it suspends execution until completion. On unix systems you will need to use a sequence of fork, execv, dup2 and pipe. This will allow you to do something more useful. See http://docs.linux.cz/programming/c/unix_examples/execill.html for an example.

doron
  • 24,882
  • 9
  • 58
  • 93
5

You need to create a forked process using fork, like this, and using popen to read the input from the output of the command ping google.com and process it accordingly. There is an interesting guide by Beej on understanding the IPC mechanisms which is included in the code sample below...

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(void)
{
    pid_t pid;
    int rv;
    FILE *ping;
    char buf[2000];
    switch(pid = fork()) {
    case -1:
        perror("fork");  /* something went wrong */
        exit(1);         /* parent exits */

    case 0:
        // We're the child
        ping = popen("ping google.com", "r");
        if (ping != NULL){
            fgets(buf, sizeof(buf), ping);
            pclose(ping);
            rv = 0;
        }else{
            perror("popen failed");
            rv = -1;
        }
        exit(rv);
    default:
        // We're the parent...
        wait(&rv);
    }
    // Now process the buffer
    return 0;
}

Hope this helps, Best regards, Tom.

t0mm13b
  • 32,846
  • 7
  • 71
  • 106
2

Edit On consideration, I believe that popen is the way to go with or without output from cmd.


Older

You are probably looking for something in the wait (2) family of commands plus a fork and exec.

From the manual page

The wait() function suspends execution of its calling process until stat_loc information is available for a terminated child process, or a signal is received. On return from a successful wait() call, the stat_loc area contains termination information about the process that exited as defined below.

Or if cmd returns some progress information you want popen (3) which is discussed in a number of existing SO questions; for instance How can I run an external program from C and parse its output?.

Community
  • 1
  • 1
dmckee --- ex-moderator kitten
  • 90,531
  • 23
  • 129
  • 225
  • To him that may mean he actually doesn't want to call wait(), because it will block until the child process finishes, which he wants to avoid. I seem to remember a non-blocking option or parameter, though. Good answer, anyway. – Paul Feb 13 '10 at 20:56
1

If you are on a unix system, you can start a command with an & to indicate that it runs in the background like this: myscript &

This will start a new process separate from the current program. You need to pick up the process number (hopefully from system, my c posix api knowledge is rusty) and then check up on it probably with a call to something like wait or waitpid with non-blocking turned on.

This is complicated for a beginner -- I'll let someone else post details if still interested.

Paul
  • 23,002
  • 11
  • 77
  • 112