:
I spawn my subprocess with subprocess : https://docs.racket-lang.org/reference/subprocess.htmlAnd for the sake of completeness I want to know when suprocess failed (because the users tampered with the exe, because there's an ACL issue, whatever).The function doesn't have a return value for failure and it doesn't raise an exception when I do stuff like(subprocess "no exe here")or
(subprocess "nice picture of an aardvark.png")It only returns a seemingly valid value.
Can someone help me ? Is it an API defect and a special value should be returned ? Should an exception be raised ? The doc doesn't say much about this.
#lang racket
(define sub #f)
(let [
(name "C:\\WINDOWS\\system32\\notepad.exe")
(in #f)(out #f)(err #f)
]
(set!-values (sub out in err) (subprocess #f #f #f name))
)
(subprocess-status sub)
(subprocess-pid sub)
(subprocess-wait sub)
;; close subprogram here
(subprocess-status sub)
(subprocess-pid sub)
I don't really care about the OS-level cause of the failure but I need to know if it failed.I didn't test on my Linux box for consistency.
By the way, subprocess-pid returns 0 on such a "never spawned" process, and I think it should be an error case too.
The 1st value returned by (subprocess) is an opaque reference to the executing process. If you pass the reference to (subprocess-status) it will return 'running if the process currently is executing, or the exit/error value.
No actual process can have pid 0 ... that value is reserved (on Unix/Linux and Windows).
Racket doesn't support fork (because Windows doesn't), but recall that when you fork in Unix/Linux, the child process receives the illegal pid value 0 so that it knows it is the child, while the parent receives the real pid value for the child.
Also note that (subprocess-pid) will be valid only if the process started successfully.
Hope this helps,
George
The 1st value returned by (subprocess) is an opaque reference to the executing process. If you pass the reference to (subprocess-status) it will return 'running if the process currently is executing, or the exit/error value.
"exit/error value" is the issue there.
(subprocess-status ps) will return 'running if the process is running.
If it doesn't, either the process has never ran, either it has finished with a exit code.
No way (that I see) to disambiguate.
(orshould do the trick.
(eq? 'running (subprocess-status ps))
(not (= 0 (subprocess-pid ps)))
)
(subprocess-pid) is only valid when (subprocess-status) is 'running but testing the status then requesting the pid is not atomic, therefore subprocess-pid should return #f or raise. Or return pid 0 but it should be documented :)
By the way there is a process with pid 0 on Linux, it's "sched". And on Windows, its "idle". Of course it could never be the result of (subprocess ...) but I don't want to rely on incidental behaviour from an API :=
Hope this helps,
George
I'm not sure I completely understand the problem. You're correct that there's no way to tell whether the value is an exit code from the program or an error from the operating system ... but there also is no way to tell that starting the program from the shell IF you rely solely on the exit code.
But if the idea is to tell whether the program started correctly - even if it since has ended - then something like:
(orshould do the trick.
(eq? 'running (subprocess-status ps))
(not (= 0 (subprocess-pid ps)))
)
(subprocess-pid) is only valid when (subprocess-status) is 'running but testing the status then requesting the pid is not atomic, therefore subprocess-pid should return #f or raise. Or return pid 0 but it should be documented :)
It does return 0 if the program never started.
I won't argue about documentation, but I will note that the Racket "process" object retains the assigned pid value even after the process terminates ... so testing whether it is running before retrieving the pid does not seem to be a real burden. Do you have a use case where this matters?
By the way there is a process with pid 0 on Linux, it's "sched". And on Windows, its "idle". Of course it could never be the result of (subprocess ...) but I don't want to rely on incidental behaviour from an API :=
Those are not processes - they are kernel functions called when no actual process is ready to run. They consume time and CPU cycles, so they are included in the process listing, but they really are just system overhead. When the OS is in one of these functions it is sleeping waiting for either a timer tick or an I/O completion.
And pid 0 will never be assigned to a real process.
Currently, if fork() fails on Unix (e.g., because there are too many
processes), then `subprocess` will raise an exception. But if fork()
succeeds, then there's normally no way to communicate an error from
exec() except through the exit code, since exec() is in the child
process.[*] So, that's why there's no way to distinguish "program
couldn't start" from "program exited with a non-0 status" on Unix.
You're right that `subprocess` could make a distinction on Windows with
CreateProcess(). Currently, `subprocess` doesn't make a distinction,
mostly because not doing so makes the behavior somewhat more consistent
with conventional Unix behavior.
--
You received this message because you are subscribed to the Google Groups "Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to racket-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/5e3ee899.1c69fb81.a3dd4.306bSMTPIN_ADDED_MISSING%40gmr-mx.google.com.