rtomayko / posix-spawn

Ruby process spawning library
Other
520 stars 52 forks source link

Document chdir the behavior of posix-spawn #59

Closed jacobvosmaer closed 10 years ago

jacobvosmaer commented 10 years ago

Not knowing exactly what posix_spawn(2) does and does not do for you, I was a little surprised when I found out that the posix-spawn gem changes the working directory of the calling process. This commit is an attempt to share what I have learned.

rtomayko commented 10 years ago

Yep, definitely worth calling out here. Merging.

I wanted to jot down some notes here after digging around a bit.

The :chdir implementation takes place entirely outside of the system level posix_spawn invocations, which don't support modifying the working directory of the spawned process that I can tell. Relevant parts of the posix-spawn codebase are here:

I'm curious how Ruby's built in Process::spawn compares here. If it's made thread-safe somehow, it'd be interesting to see if we could accomplish the same.

I also verified that omitting the :chdir option causes all working directory modification logic to be bypassed in the posix_spawn and Ruby fork/exec implementation.

rtomayko commented 10 years ago

@jacobvosmaer I'd also be interested to hear about your experience using posix-spawn in a threaded environment in general. GitHub makes heavy use of posix-spawn in a variety of production systems but I can't think of a single one that uses Ruby threads for anything beyond very trivial monitor type situation. Perhaps this should be called out even more heavily in the README.

jacobvosmaer commented 10 years ago

@rtomayko GitLab runs all its background jobs in Sidekiq. I am not aware of any issues caused by the posix-spawn gem. Thanks for creating and maintaining it!

We don't use posix-spawn's chdir much if at all; we considered using it more but after discovering the issue mentioned in this PR we decided not to.

jacobvosmaer commented 10 years ago

About the Ruby Process::spawn implementation: I find the implementation a little hard to read with all the ifdefs going on, but I would expect them to do the equivalent of 'fork { chdir; exec }'.

piki commented 10 years ago

Process::spawn indeed runs chdir between fork and exec. There's a catch-all function rb_execarg_run_options here that deals with the stuff between fork and exec: chdir, uid, gid, fds, and so forth.

rtomayko commented 10 years ago

Great, thanks. I'm cool with leaving the README as is.