process-waitinstead of using timer to poll every 500 ms (or whatever). So I've implemented it, now you can use like this:
(import (rnrs) (sagittarius process)) (let ((p (call "sh" "sleep_forever.sh"))) ;; wait for 5 seconds. can also be time object. (unless (process-wait p :timeout 5)) ;; it returns #f if timed out. so kill it (process-kill p)))Now, I don't have to make timer to check. Very convenient :)
From here is the description of underlying implementation. This is not something you may be interested in but simply for my memo (and hope that somebody would indicate better solusion).
Sagittarius supports both Windows and POSIX environment. On Windows, the story was very simple, I just needed to call
WaitForSingleObjectwith process handle and timeout millisecond. Hurray done!. I like this abstraction that API can handle almost any kind of handle. (Most of the time it's a headache to support Windows but sometimes it's easier than POSIX.)
On POSIX, on the other hand, it doesn't have
timedwaitpidor something like that. I've asked the teacher, Google, what would be the solution. The first hit was this: Waitpid equivalent with timeout?. Its best answer doesn't seem the best answer since entire process would be affected. Plus, it would always wait for specified timeout amount of time which is not something I want. The most useful pointed one looks nice if POSIX has a portable way to get standard output file descriptor from pid. Though, there seems a way to do it using
reptyr(1)and its source). I haven't looked into its detail but, in my understanding, it opens given pid process with
dup(2)on that process (
ptrace_remote_syscalldoes this black magic I think). It'd be nice to have it if I can do this all platforms Sagittarius supports. However not an easy task to do it without having real environments (e.g. OS X is only on Travis CI).
What I wanted to do is
waitpidwith timeout. So I just need to have a watch dog which alerts either timeout is happened or the target process is finished. Well, the easiest one I could think of was thread with
The idea is pretty much simple. It goes the following steps:
- Create a thread with the thread entry which calls
- If this return
ETIMEDOUT, then send signal to the thread and return
- Otherwise return the return code.
pthread_joincan't be called with detached thread. Though, interestingly, it worked on FreeBSD, why?)
Well, if I can say this is a perfect solution, I'd be super happy but of cource this has an issue (for now only one I'm facing!). Because of the limitation of
waitpid (2), the pid can be waited must be created by the parent process means Sagittarius script. Thus processes created by
pid->processcan't be passed (well this is not only for timeout argument but entire procedure issue, though). If this happens, then
ECHILDis raised (see
I haven't got any problem with it but if would, then I need a better solution (maybe set PPID to running process? but how?). But for now, I'm happy enough and I believe there's very few situation which users want to wait non child processes.
Again, this isn't an issue on Windows. I don't care good or not but I like it.