Re: [racket-users] subprocess failure (Windows-specific ?)
Of course ! Inter-OS APIs are such a pain. I think you do the right thing by explicitating the differences regarding various OSes on the scribbled doc page. Maybe just documenting that: * subprocess-pid retains the pid forever after the child has stopped running * subprocess-pid returns 0 (or invalid-pid) on Windows and BSD and Linux and OSX (who knows the bright future of Racket ? :) ) if the process spawning failed would be sufficient to write production code with defined behaviour. I'd certainly be satisfied. Cheers, Bertrand Le sam. 8 févr. 2020 à 17:58, Matthew Flatt a écrit : > At Sat, 8 Feb 2020 17:46:06 +0100, Bertrand Augereau wrote: > > You're right, but wouldn't using the posix_spawn family have better > > semantics, better performance, and would allow to unify between POSIX and > > Windows behaviours nicely ? :) > > It's the usual problem: posix_spawn() doesn't quite support all of the > things Racket does between fork() and exec(). > > -- > 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+unsubscr...@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 > . > -- 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+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/CAHV%3D05q8k-YhRLFQXkiOK3EPVP4Wi-1CFyvzzMBSSK6RAvF%2BtA%40mail.gmail.com.
Re: [racket-users] subprocess failure (Windows-specific ?)
At Sat, 8 Feb 2020 17:46:06 +0100, Bertrand Augereau wrote: > You're right, but wouldn't using the posix_spawn family have better > semantics, better performance, and would allow to unify between POSIX and > Windows behaviours nicely ? :) It's the usual problem: posix_spawn() doesn't quite support all of the things Racket does between fork() and exec(). -- 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+unsubscr...@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.
Re: [racket-users] subprocess failure (Windows-specific ?)
Hi Matthew, > 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're right, but wouldn't using the posix_spawn family have better semantics, better performance, and would allow to unify between POSIX and Windows behaviours nicely ? :) Cheers, Bertrand -- 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+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/CAHV%3D05pMUvd2ASObfV_jrbJ0496PP0cZQcc31qyvFo47GwSQ%2Bg%40mail.gmail.com.
Re: [racket-users] subprocess failure (Windows-specific ?)
At Sat, 8 Feb 2020 17:08:18 +0100, Bertrand Augereau wrote: > > 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. > > > > That's why CreateProcess and fork/exec return code. 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. [*] It seems possible to set up an extra channel of communication to report whether exec() succeeds. I think that would be tricky at best, though, because it's not clear how to clean up the channel if exec() does succeed. > > But if the idea is to tell whether the program started correctly - even if > > it since has ended - then something like: > > > > (or > > (eq? 'running (subprocess-status ps)) > > (not (= 0 (subprocess-pid ps))) > > ) > > > > should do the trick. > > > > Yes in practice, it might be good enough. I agree that this is not a good choice. For compatibility while also exposing the result of CreateProcess() on Windows, a new `subprocess-...` operation is probably best. I'll look into adding that. -- 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+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/5e3ee1d3.1c69fb81.fc262.2f8aSMTPIN_ADDED_MISSING%40gmr-mx.google.com.
Re: [racket-users] subprocess failure (Windows-specific ?)
> 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. > That's why CreateProcess and fork/exec return code. If I was coding this in C, I would have no issue, so I think the problem should be clearly addressed in Racket too. I don't see what the shell's got to do with it :) > > But if the idea is to tell whether the program started correctly - even if > it since has ended - then something like: > > (or > (eq? 'running (subprocess-status ps)) > (not (= 0 (subprocess-pid ps))) > ) > > should do the trick. > Yes in practice, it might be good enough. > > > (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? > You're using undocumented behaviour there, Plausible one though. But it's subject to change in the future so I'd prefer to address it and have the documentation changed by the Racket team so that my code is robust in the long run :) > 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. > Indeed, but if 0 is a magic number of sorts for subprocess-pid, it should be documented too. IMO, it would be cleaner to have subprocess returns #f or raise an exception if spawning the process fails. It would solve my initial problem and mimic what the C APIs do. The subprocess-pid would not need any further consideration then :) -- 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+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/CAHV%3D05otrEn%3DW1auy01870JVtVZrCpMsxCqypQxE0WY5q-Kz8g%40mail.gmail.com.
Re: [racket-users] subprocess failure (Windows-specific ?)
On 2/8/2020 8:58 AM, Bertrand Augereau wrote: 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. 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: (or (eq? 'running (subprocess-status ps)) (not (= 0 (subprocess-pid ps))) ) should do the trick. (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. Hope this helps, George -- 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+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/8e8fa61b-92b4-b58a-5601-d7197a04ba84%40comcast.net.
Re: [racket-users] subprocess failure (Windows-specific ?)
> 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. > 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. > > (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 > Thanks for contributing, it's much appreciated, Bertrand -- 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+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/f91e532a-182f-454e-8495-496a9c088e9f%40googlegroups.com.
Re: [racket-users] subprocess failure (Windows-specific ?)
On 2/8/2020 3:37 AM, Bertrand Augereau wrote: : I spawn my subprocess with subprocess : https://docs.racket-lang.org/reference/subprocess.html And 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. 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. 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. A special value is returned - the opaque reference. Perhaps the docs could use a simple example of how to use the functions effectively. Try playing a bit with the following: #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. 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 -- 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+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/447df58e-66ba-49aa-8151-7a8abd943090%40comcast.net.