
Hi, I just noticed this in my process list: │ ├─xmonad-x86_64-l │ │ └─sh -c gnome-terminal │ │ └─gnome-terminal and the reason is here, in Core.hs: -- | Like 'spawn', but returns the 'ProcessID' of the launched application spawnPID :: MonadIO m => String -> m ProcessID spawnPID x = io . forkProcess . finally nullStdin $ do uninstallSignalHandlers createSession executeFile "/bin/sh" False ["-c", x] Nothing where nullStdin = do fd <- openFd "/dev/null" ReadOnly Nothing defaultFileFlags dupTo fd stdInput closeFd fd Generally, this is of course useful. But I bet that most commands passed to spawn are simple program names without arguments or any fancy shell-related stuff. Executing a shell here seems overkill. Not much, but still avoidable. How about checking whether the argument x contains only alphanumerical characters and, if that is the case, executing the program directly? Such short-circuit logic is for example also used by perl’s sytem(), see perldoc -f system: If there is only one scalar argument, the argument is checked for shell metacharacters, and if there are any, the entire argument is passed to the system's command shell for parsing (this is "/bin/sh -c" on Unix platforms, but varies on other platforms). If there are no shell metacharacters in the argument, it is split into words and passed directly to "execvp", which is more efficient. Greetings, Joachim -- Joachim "nomeata" Breitner mail: mail@joachim-breitner.de | ICQ# 74513189 | GPG-Key: 4743206C JID: nomeata@joachim-breitner.de | http://www.joachim-breitner.de/ Debian Developer: nomeata@debian.org

On 21 September 2010 06:06, Joachim Breitner
Hi,
I just noticed this in my process list:
│ ├─xmonad-x86_64-l │ │ └─sh -c gnome-terminal │ │ └─gnome-terminal
and the reason is here, in Core.hs:
-- | Like 'spawn', but returns the 'ProcessID' of the launched application spawnPID :: MonadIO m => String -> m ProcessID spawnPID x = io . forkProcess . finally nullStdin $ do uninstallSignalHandlers createSession executeFile "/bin/sh" False ["-c", x] Nothing where nullStdin = do fd <- openFd "/dev/null" ReadOnly Nothing defaultFileFlags dupTo fd stdInput closeFd fd
Generally, this is of course useful. But I bet that most commands passed to spawn are simple program names without arguments or any fancy shell-related stuff. Executing a shell here seems overkill. Not much, but still avoidable.
I believe the reason here is to do a double fork, such that when xmonad restarts the program you launched via xmonad isn't killed. -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

Joachim Breitner writes:
I just noticed this in my process list:
│ ├─xmonad-x86_64-l │ │ └─sh -c gnome-terminal │ │ └─gnome-terminal ... How about checking whether the argument x contains only alphanumerical characters and, if that is the case, executing the program directly?
I like that idea. I guess it would be as simple as splitting on whitespace and counting the number of arguments, as I doubt anyone's spawning anything with globs in the first word... I wonder if there's a way you could do the split at compile time, given that the arguments to spawn are almost always constants.

Joachim Breitner
-- | Like 'spawn', but returns the 'ProcessID' of the launched application spawnPID :: MonadIO m => String -> m ProcessID spawnPID x = io . forkProcess . finally nullStdin $ do uninstallSignalHandlers createSession executeFile "/bin/sh" False ["-c", x] Nothing
Generally, this is of course useful. But I bet that most commands passed to spawn are simple program names without arguments or any fancy shell-related stuff. Executing a shell here seems overkill. Not much, but still avoidable.
How about checking whether the argument x contains only alphanumerical characters and, if that is the case, executing the program directly? Such short-circuit logic is for example also used by perl’s sytem(), see perldoc -f system:
I'm not a big fan of perl's all-implicit behaviour. I'd rather rename spawn(PID) to spawnShell(PID) x = spawn(PID) "/bin/sh" ["-c", x] and make the shell invocation explicit. If such incompatible change is impossible, then make it spawn(PID) x = execute(PID) "/bin/sh" ["-c", x] or similar. Meanwhile, use exec to get rid of the shell process. :) -- Regards, Feri.
participants (4)
-
Ferenc Wagner
-
Ivan Lazar Miljenovic
-
Joachim Breitner
-
Justin Bogner