Thread: Checking if a process has terminated?

  1. #16
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    I guess that makes sense. it still doesn't make any sense why the signals wouldn't get passed when you kill the child, versus when the child terminates normally. I suspect it has to do with something you're doing in the handle_command() function, but I can't imagine what that might be.

  2. #17
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Well, I can post more code. I just have to make you all aware that I am seeking help elsewhere (otherwise I would have been more noisy here).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #18
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    OK, now I am confused. It seems I do not fully understand how signals work. Consider the example:
    Code:
    #include <stdio.h>
    #include <signal.h>
    #include <unistd.h>
    
    void child_status_change_handler(int signum)
    {
    	fprintf(stderr, "Signal recieved!\n");
    }
    
    int main()
    {
    	signal(SIGCHLD, &child_status_change_handler);
    	if (fork() == 0)
    		execlp("./idler", "idler", "5", NULL);
    	if (fork() == 0)
    		execlp("./idler", "idler", "10", NULL);
    
    	char buf[1024];
    	fprintf(stderr, "Press any key to quit...\n");
    	while (fgets(buf, sizeof(buf), stdin) == NULL);
    	printf("Terminating...\n");
    }
    I will receive only ONE signal. The other signal is lost in the void. Why?

    Source for idler:
    Code:
    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    int main(int argc, char** argv)
    {
    	fprintf(stderr, "Idler will idle for %s seconds...\n", argv[1]);
    	sleep(strtol(argv[1], NULL, 10));
    	fprintf(stderr, "Idler terminating...\n");
    }
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #19
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    is it possible that one of the fork() calls is failing? you can check this by testing its return value < 0.

  5. #20
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    No, I get the output:

    Press any key to quit...
    Idler will idle for 5 seconds...
    Idler will idle for 10 seconds...
    Idler terminating...
    Signal recieved!
    Idler terminating...
    gg
    Terminating...
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #21
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    I think the received signal is canceling your request for console input. this is normal behavior for unix/linux systems. if you use sigaction() instead of signal(), you can specify that blocking system calls like that should resume instead of returning.

  7. #22
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Imagine that!
    Using sigaction instead of signal, the code now mysteriously works.
    I simply changed

    signal(SIGCHLD, &child_status_change_handler);

    to

    Code:
    	typedef struct sigaction sigaction_t;
    	sigaction_t sigdata;
    	memset(&sigdata, sizeof(sigdata), 0);
    	sigdata.sa_handler = &child_status_change_handler;
    	sigdata.sa_flags = SA_NOCLDSTOP | SA_RESTART;
    
    	sigaction(SIGCHLD, &sigdata, NULL);
    What is even better is that fgets is resumed (or restarted?) after the signal, hence it keeps blocking.

    I will now have to incorporate that into the main program and see what happens.

    EDIT:
    Wow! I couldn't ask for it to work more perfectly!

    You may not have produced the solution, but you did tread me down on the right path. This saves me a lot of frustration! So thanks a million.
    The ability to resume sys calls is also extremely useful!
    Last edited by Elysia; 11-22-2011 at 11:11 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #23
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    the SA_RESTART flag means to restart any system calls in progress, which is more or less exactly what I told you :P

  9. #24
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yeah, which is one of the reasons I tried using it.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #25
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    well I'm glad I could help. did it have the desired effect when you put it in your main program?

  11. #26
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yeah, it did. Hence my edit.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #27
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Auto-restart of syscalls is only useful in some very specific situations... Normally, you want a signal to abort any blocking syscall you might be inside, so that you can actually respond in some way to the signal. It's difficult to safely do very much inside a signal handler -- most functions are not async signal safe, and even for those that are, you need to remember that you are executing in an asynchronous context and must therefore interlock with the main execution. Signal handlers should ideally just set a flag and then return -- the main program does the heavy lifting. For this to work, the syscall MUST be interrupted by the signal, otherwise you'll just sit there blocked when you actually have something you should be responding to.

    It's sort of a pain in the ass, but wrapper like the following can be helpful:

    Code:
    // auto-restarting wrapper around the 'foobar()' system call
    int foobar_wrapper(int arg)
    {
        int ret = foobar(arg);
        while (ret < 0)
        {
            if (errno == EINTR)
                HandlePendingSignals(); // take care of anything queued up by the sighandlers
            else
                break;
        }
        return ret;
    }
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Process Terminated with status -1073741510
    By Varethien in forum C Programming
    Replies: 5
    Last Post: 08-09-2011, 04:16 AM
  2. Process terminated with status -1073741819
    By smithx in forum C Programming
    Replies: 5
    Last Post: 11-01-2010, 11:13 PM
  3. Checking for child process errors?
    By Blasz in forum C Programming
    Replies: 11
    Last Post: 05-19-2010, 07:41 AM
  4. un-terminated stream
    By WDT in forum Networking/Device Communication
    Replies: 1
    Last Post: 04-01-2005, 07:08 PM
  5. Replies: 5
    Last Post: 03-21-2004, 03:18 PM