Hacker News new | ask | show | jobs
by dllthomas 2122 days ago
On the one hand, on Linux with the clone system call, you actually can have a "thread" that shares memory, file descriptor table, etc, but not working directory (or chroot):

        If  CLONE_FS  is  not  set,  the  child  process  works on a copy of
        the filesystem information of the calling process at the time of the
        clone() call.  Calls to chroot(2), chdir(2), or umask(2) performed later
        by one of the processes do not affect the other process.
On the other hand: what you say is true of posix threads, code built atop clone is unlikely to be portable, etc, etc.

More generally, it's very much the case that the process-global nature of the working directory makes some things tricky. On the other hand, there are ways around that.

If the only pieces that need to reference the working directory are processes you're spawning, the answer is simple - carry a description of the intended working directory through your computation, and actually chdir between the fork and the exec.

If the only pieces that need to reference the working directory are things you will be writing as a part of the current project, you can use "at variants" (openat, fstatat, unlinkat, etc).

You can stitch these two together as needed.

What's awkward is if you need to use library code that references the current working directory and does not use "at variants". In that case, you could play some awkward game with a mutex, setting the cwd only for the duration of individual operations and restoring it afterward (although that does require knowing when these operations may be performed).

Or you could fork your process along the lines you need to draw. Splitting your view of memory raises questions of IPC. In particular, if you want to pass language-specified data structures that gets complicated - particularly if they may contain references. If you can get away with treating everything as passing streams of bytes over actual pipes, it's pretty straightforward. To my mind, this is probably most of what's meant by "shell-script like", and while you're recreating part of a shell, it's actually not very much of a shell, it should be well contained in the library, and you have room for a much better story around things like error handling. I don't have a sense of whether any of the particular libraries discussed here are actually addressing exactly this issue or whether they actually do a good job of any of it.