Thread: background & with a report

  1. #1
    Registered User
    Join Date
    May 2009
    Posts
    43

    background & with a report

    So right now my shell does everything fine, and this function runs in the background fine. However, I was wondering if there's a way for me to get a report printed to my screen shell when the background job is done.

    So if I say:
    myshell> sleep 10 &

    then 10 seconds later:

    myshell> job[blah] finished

    Is there a simple way to code this?

    Code:
    int runInBackground(Command* command, int givenPath)
    {
            int pid;
            char *commandName = command->name;
            int status;
            if(givenPath == 0)
            {
                    commandName = getCommandPath(command->name);
            }
    
            if(commandName == NULL)
            {
                    printf("Command not found.\n");
                    return 1;
            }
    
            pid = fork();
    
            if(pid < 0) //Checks for error
            {
                    printf("Error in the fork process.\n");
                    return 1;
            }
            else if (pid == 0) //Child
            {
                    execv(commandName, command->argv);
                    return 1;
            }
            else
            {
    //              waitpid(pid, &status, WNOHANG);
            }
    }

  2. #2
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    You could run a simple script like
    ./myProg
    ./echo "Done"
    If you only want to be notified when the program done.
    Maybe even this works
    ./myProt & && echo "Done"

    You can also you the >> operator to put the output in a file. I have no idea if echo can print a file, put
    ./myProg & >> log
    ./echo log

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Set a signal handler for SIGCHLD
    signal(2): ANSI C signal handling - Linux man page

    Use select() to monitor fd 0 (stdin), and periodically timeout so you can call waitpid(pid, &status, WNOHANG); to see if any processes have ended recently.
    select(2): synchronous I/O multiplexing - Linux man page
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    May 2009
    Posts
    43
    Quote Originally Posted by Salem View Post
    Set a signal handler for SIGCHLD
    signal(2): ANSI C signal handling - Linux man page

    Use select() to monitor fd 0 (stdin), and periodically timeout so you can call waitpid(pid, &status, WNOHANG); to see if any processes have ended recently.
    select(2): synchronous I/O multiplexing - Linux man page
    Great thanks. I got the signal handler to run, and if I type sleep 5 &, it works and prints out when finished. However, if I type sleep 5 &, and then type in another command like ls or ps after it, the shell hangs and it prints out that it's finished when it clearly has not finished.


    Code:
    void handler(int sig)
    {
            int pid;
            int status;
            pid = wait(NULL);
            printf("Pid %d exited.\n", pid);
    }
    
    
    
    int runInBackground(Command* command, int givenPath)
    {
            int pid;
            int status;
            char *commandName = command->name;
            if(givenPath == 0)
            {
                    commandName = getCommandPath(command->name);
            }
    
            if(commandName == NULL)
            {
                    printf("Command not found.\n");
                    return 1;
            }
    
            pid = fork();
    
            if(pid < 0) //Checks for error
            {
            }
    
            if(commandName == NULL)
            {
                    printf("Command not found.\n");
                    return 1;
            }
    
            pid = fork();
    
            if(pid < 0) //Checks for error
            {
                    printf("Error in the fork process.\n");
                    return 1;
            }
            else if (pid == 0) //Child
            {
                    execv(commandName, command->argv);
                    return 1;
            }
            else
            {
                    signal(SIGCHLD, handler);
            }
    }
    OUTPUT:
    Code:
    <project3> sleep 5 &
    <project3>
    <project3>
    <project3> Pid 399 exited.
    <project3>
    <project3> sleep 5 &
    <project3> ls
    bob                 project1.c  hey                 proj1               proj1.c
    Pid 402 exited.
    I pressed enter a few times the first time I ran sleep 5 in the background, then after 5 seconds, it printed out the pid perfectly! But notice what happens when I ran sleep 5 in the background and then ran ls following it right afterwards. System printed out my files/folders but posted the pid and got hung.
    Last edited by hansel13; 06-04-2010 at 11:05 PM.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    What does your run_in_foreground code do?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    May 2009
    Posts
    43
    Quote Originally Posted by Salem View Post
    What does your run_in_foreground code do?
    It depends if I'm giving the path name in the shell, or given just the command executable. Also, if there is piping or redirection, I call a different function.

    But I'll just show you the one for running with a given path:

    Code:
    int runByGivenPath(Command* command)
    {
            int pid;
            int status;
            char * commandName = command->name;
    
            if(commandName == NULL)
            {
                    printf("Command not found.\n");
                    return 1;
            }
    
            pid = fork();
    
            if(pid < 0) //Checks for error
            {
                    printf("Error in the fork process.\n");
                    return 1;
            }
            else if(pid == 0) //Child
            {
                    if(execv(commandName, command->argv) == -1)
                            printf("Pathname is invalid\n");
                    return 1;
            }
            else //Parent
            {
                    while(wait(&status) != pid);
                    return 1;
            }
    }

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    I think your wait() should wait for a specific PID (the one you just ran).
    It will also "reap" your background thread when it exists as well.

    Try waitpid()
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Report from Some Text Boxes ??
    By _root in forum C# Programming
    Replies: 1
    Last Post: 05-22-2009, 03:59 AM
  2. Replies: 2
    Last Post: 05-13-2009, 12:57 PM
  3. Moving Average Question
    By GCNDoug in forum C Programming
    Replies: 4
    Last Post: 04-23-2007, 11:05 PM
  4. Debug Error Really Quick Question
    By GCNDoug in forum C Programming
    Replies: 1
    Last Post: 04-23-2007, 12:05 PM