Search code examples
windowspipecrt

Detecting death of spawned process using Window CRT


Executive summary: I need a way to determine whether a Windows process I've spawned via _spawnl and am communicating with using FDs from _pipe has died.

Details:

I'm using the low-level CRT function in Windows (_eof, _read) to communicate with a process that was spawned via a call to _spawnl (with the P_NOWAIT) flag. I'm using _pipe to create file descriptors to communicate with this spawned process and passing those descriptors (the FD #) to it on the command line.

It is worth mentioning that I don't control the spawned process. It's a black box to me.

It turns out that the process we are spawning occasionally crashes. I'm trying to make my code robust to this by detecting the crash. Unfortunately, I can't see a way to do this. It seems reasonable to me to expect that a call to _eof or _read on one of those descriptors would return an error status (-1) if the process had died.

Unfortunately, that isn't the case. It appears that the descriptors have a life of their own independent of the spawned process. So even though the process on the other end is dead, I get no error status on the file descriptor I'm using to communicate with it.

I've got the PID for the nested process (returned from the _spanwnl call) but I don't see anything I can do with that. My code works really well except for one thing. I can't detect whether the spawned process is simply busy computing me an answer or has died.

If I can use the information from _pipe and _spawnl to determine if the spawned process is dead, I'll be golden.

Suggestions very welcome.

Thanks in advance.

UPDATE: I found a fairly simple solution and added it as the selected answer.


Solution

  • See How to know child process status and resource usage on windows?

    You can just use WaitForSingleObject on the handle returned from spawnl; it's working fine for me. It sounds like you might have already tried this, but maybe I'm misunderstanding your responses.

    Sample code that spawns a process and waits for it to finish without using _P_WAIT:

    HANDLE hProcess = (HANDLE) _spawnl(_P_NOWAIT, "slave.exe", "slave.exe", NULL);
    while(1)
    {
      Sleep(100);
      if (WaitForSingleObject(hProcess, 0) == WAIT_OBJECT_0)
      {
        break;
      }
    }