Learning about how Unix processes work, and noticed that child processes inherit most of the attributes (including file descriptors) from the parent process. I also just learned about exec and how it replaces the child process attributes with entirely new ones (new memory space, etc.), but keeps the original process ID.

Then I know about sandbox environments in Node.js, in which it provides you an essentially empty slate, and you add variables and "features" to the context of the child process.

What I'm wondering is, what the different kinds of configurations there are for the attributes a child process receives, and why the child process in Unix "defaults" to inheriting all the parent attributes. Wondering why it wouldn't instead have its own memory space and whatnot.

Also wondering if there are alternative "child process attribute configurations" to these 2 cases (inherit all parent attributes, or inherit none). Maybe it would want to inherit half of the parent address space, or use some address space from a sibling process, or use a few file descriptors from the parent as well as some of its own, etc. Maybe you say it can access a few device drivers and others not, etc.

Would be interested to know if there is a way to pass in such "configuration features" when creating a child process, either on Unix or on any other operating system. For example, "create child process, using half of parent address space, 1/4th of sibling 2's address space, 1/8th of sibling 1's address space, and the remaining 1/8th use my own local address space. Also, provide access to a, b, and c device drivers, and otherwise allow no network access." Something arbitrary, where it is basically configuring the "feature set" of the child process to a fine-level of detail.

Wondering if anything like that occurs in Unix or other operating systems, and if not, why not. I don't understand why the decision was made to just have these 2 cases of permissioning/regulating processes.

It seems this somehow overlaps with the protection ring concept. You prevent userland processes (child processes) from accessing certain features. Wondering why it's not more configurable than this, at a high level.

  • Child processes get their own (COW) memory space, and threads share. The "feature set" of a child is configured by the parent process after fork() and before exec..(). – dsstorefile1 Aug 22 '18 at 4:21
  • 1
    Are you asking about Unix processes, about Linux processes, about FreeBSD processes...? There is a huge gap between traditional Unix fork/vfork and e.g. Linux clone/unshare, or FreeBSD rfork. – grawity Aug 22 '18 at 5:13
  • 1
    The problem with this question—which the answer here addresses—is it assumes that “parent” and “child” are just universal in a system and that a Node.js “child” process is similar to an OS-level “child” process. It isn’t. Node.js is simply a programming language that exists on an OS and works within it’s own process structure. OS items are a whole different beast. Also, this question somewhat sniffs a bit like an “XY problem” so I encourage the original poster to clarify if needed what the real issue is. – JakeGould Aug 22 '18 at 17:48

You're mixing apples and oranges and grapefruits here.

  • "node.js," for instance, is the JavaScript high-level language, which has nothing to do with operating-system processes. (All of JavaScript runs within a process or thread furnished by its host.)

  • "Rings," or more generally "CPU privilege levels," are physical features of the microprocessor chip, used to determine what CPU instructions a program is allowed to issue and what resources it can access.

  • The Unix/Linux software architecture, which is quite-specific to these operating systems, is closely tied to the notion of "forking," which looks like this:

    if (pid = fork()) {
        ... you are the parent, and 'pid' is the child's process-id ...
    } else {
        ... 'pid' is zero, so you are the child ...

In order for this neat-idea to work, most of the context of the parent must be copied to the child.

The exec() system call can be used (by a child) to replace its entire context with that of some new process, causing all "inheritance" from the parent to be severed.

  • 1
    exec() doesn't remove all inheritance. It mostly just replaces the process memory, but other resources are retained. E.g. file desriptors are preserved unless they have the close-on-exec flag set; this allows the shell to perform I/O redirection before exec'ing an external program. – Barmar Aug 24 '18 at 18:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy