0

I have a program, where part of it is supposed to show the uptime every 5 seconds but right now it's just showing it one time than telling the program to exit. Why is this child process only going one time and than going to the parent for program exit?

  • 4:10pm up 171 day(s), 8:03, 13 users, load average: 0.89, 1.29, 1.46
  • Program Exits Now
  • > Time is 16:10:10
  • Timer 0:10
  • Time is 16:10:11
  • Timer 0:9
  • Time is 16:10:12
  • Timer 0:8
  • Time is 16:10:13
  • Timer 0:7
  • Time is 16:10:14
  • Timer 0:6
  • Time is 16:10:15
  • Timer 0:5
  • Time is 16:10:16
  • Timer 0:4
  • Time is 16:10:17
  • Timer 0:3
  • Timer 0:2
  • Time is 16:10:18
  • Timer 0:1
  • Time is 16:10:19

My code is this:

#include "time.h"

void showClock(){
    time_t timeNow;
    struct tm *locTime;
    while(Timer>0){
        timeNow=time(NULL);
        locTime=localtime(&timeNow);
        cout<<"Time is "<<locTime->tm_hour<<":"<<locTime->tm_min<<":"<<locTime->tm_sec<<"\n";
        Timer--;
        sleep(1);
    }
    exit(0);
}

void showUpTime(){
    char buffer[30] = "/usr/bin/uptime";
    char* const args[] = {buffer, (char*) 0};
    while(Timer>0){
        cout<<"Uptime :"<<execv(buffer, args)<<"\n";
        Timer-=5;
        sleep(5);
    }
    exit(0);
}

void countDown(){
    int min;int sec;
    while(Timer>0){
       min=Timer/60;
       sec=Timer%60;
       cout<<"Timer "<<min<<":"<<sec<<"\n";
       Timer--;
       sleep(1);
    }
    exit(0);
}

int main(int argc,char *argv[]){
    if(argc<2)
        Timer=10;
    else
        Timer=atoi(argv[1]);

    pid_t pid;
    int N=3,i;
    int status;
    if(!fork())showClock();
    if(!fork())showUpTime();
    if(!fork())countDown();
    wait(&status);//parent waits;
    cout<<"Program Exits  Now\n";
    return 0;
}
yuyang
  • 1,511
  • 2
  • 15
  • 40
user3339703
  • 73
  • 1
  • 10
  • _'What is wrong?'_ actually is too narrow for a valid question here. **NOTE:** Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: [How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve). – πάντα ῥεῖ Jun 28 '14 at 23:41

2 Answers2

1

The problem is in the showUpTime() function. In that function, execv(...) is called to execute uptime. When execv(...) is executed, the current process continues by loading the uptime executable over the previously running program, and exits after uptime program finishes its execution. As wait(&status) waits for any child process to exit, you observed that the main process exited, and the two other child processes were still executing.

The following is the modified code for showUpTime().It should fix the problem:

void showUpTime(){
    char buffer[30] = "/usr/bin/uptime";
    char* const args[] = {buffer, (char*) 0};
    while(Timer>0){
        pid_t pid = fork();
        if (pid == 0)
            cout<<"Uptime :"<< execv(buffer, args)<<"\n";

        Timer-=5;
        sleep(5);
    }
    exit(0);
}
yuyang
  • 1,511
  • 2
  • 15
  • 40
  • +1 that's the problem, but "When execv is executed, the current process exited immediately" is misleading - the current process continues by loading the `uptime` executable over the previously running program (the C++ code in the question), then that process exits when the `uptime` code terminates. It is difficult to describe clearly and concisely! :D – Tony Delroy Jun 29 '14 at 04:20
0

I don't see where "Timer" is actually defined, meaning your cut-n-paste code is fundamentally broken.

Also, your "wait" is waiting on an Uninitialized variable (you never initialize Status), so behavior is undefined.

Yeraze
  • 3,269
  • 4
  • 28
  • 42