
Learn and use fork(), vfork(), wait() and exec() system calls on Linux - alexellisuk
https://www.linuxtechi.com/learn-use-fork-vfork-wait-exec-system-calls-linux/
======
joosters
_Following is the c-programming example which explains how fork system call
works._

    
    
      shashi@linuxtechi ~}$ vim 1_fork.c
      #include<stdio.h>
      #include<unistd.h>
      Int main(void)
      {
      printf("Before fork\n");
      fork();
      printf("after fork\n");
      }
      shashi@linuxtechi ~}$ 
      shashi@linuxtechi ~}$ cc 1_fork.c
      shashi@linuxtechi ~}$ ./a.out
      Before fork
      After fork
      shashi@linuxtechi ~}$
    

How exactly is that demonstrating how fork() works? The article is completely
missing any explanation - like why 'After fork' was only printed once and not
twice as would be initially expected (It's unclear to me: while stdio
buffering can cause strangeness if you don't flush buffers before a fork(),
surely in this case both processes will exit cleanly and should flush their
post-fork outputs?)

~~~
DSMan195276
It _should_ print `after fork` two times, they just wrote it wrong. They
clearly wrote the whole thing manually, since they used `vim` and not `cat` to
display the contents of the file, and they show it printing `After fork` and
not `after fork`. I think they just forgot to put the line twice. The fact
that they have `Int` and not `int` means their example doesn't actually
compile, so I don't think they tested this one.

------
dooglius
Not a very good article IMHO. In addition to not explaining things well, it
doesn't discuss posix_spawn or clone which are much preferable and more
extensible ways to launch processes.

~~~
inetknght
> _posix_spawn or clone which are much preferable and more extensible ways to
> launch processes._

My understanding is that `fork()` is a nice wrapper around `posix_spawn` and,
in particular, `clone()`. And in some ways you're right: as an experienced
developer I can really appreciate the _extensibility_ of using `clone()`
instead of `fork()`.

Unfortunately if I were to use `clone()` _ever_ then I would be immediately
chastized by the architecture lead. He's not a C dude. I don't think he even
understands the concept of programs sharing an address space (he's also anti-
thread). All of it stems from "make programs simple" in an effort to minimize
maintenance costs down the road. And in many ways _he 's right too_. `clone()`
is anything _but_ simple despite being more extensible and `posix_spawn()` is
just a more complex `fork()` in that regard.

~~~
gpderetta
> My understanding is that `fork()` is a nice wrapper around `posix_spawn` .

Not really, you can't implement fork on top of POSIX spawn, but you can do the
reverse. On linux they are both implemented on top of a lower lower level
primitive (clone).

------
Animats
The fork/exec approach to process launch is a kludge from early PDP-11 UNIX.
It's done that way because it had to work when you didn't have enough memory
for both program images. Fork originally worked by swapping the process out to
disk, then updating the process table so that the in-memory copy and the
swapped out copy became separate processes. Most of the troublesome semantics
of "fork" come from that history.

------
unilynx
vfork is perfectly predictable as long as you follow the basic rule: only
invoke async-signal-safe functions until you call exec. they're explicitly
listed but basically boil down to: any functions that more-or-less map
directly to a system call, and nothing that could possibly modify process
memory or attempt to take a lock (including memory allocation)

it's meant for cases where you want to avoid a bit of the fork overhead or if
you need to spawn a subprocess from an existing memory-heavy process without
getting a KILL from the kernel if overcommit is disabled (as the fork COW
doubles your claim on memory even if you don't actually trigger a copy)

~~~
matheusmoreira
In general signal safety is lost because the C standard library maintains
global and thread-local data. For example, the various I/O functions make use
of global buffers. Using the read and write system calls directly is safe:
when interrupted, they either report their progress or return EINTR.

------
dullgiulio
All these systemcalls (except wait(2)) are just facade for clone(2), which has
a whole bunch of options.

Basically everything from threads to program invocation is just this one
powerful systemcall.

~~~
matheusmoreira
Clone is a great system call, it allows the programmer to specify which
resources are shared with the new task. The problem with clone is the C
standard library maintains global and thread-local state. For example, using
clone is not supported by glibc:

> If you use clone() you're on your own.

[https://sourceware.org/bugzilla/show_bug.cgi?id=10311](https://sourceware.org/bugzilla/show_bug.cgi?id=10311)

Sometimes it feels like the standard library is holding C back. I wonder how
many great Linux-specific features go unused because of it.

~~~
dooglius
This looks like more of a case of glibc not working well with one particular
combination of options. I don't think libc really holds anyone back
considering it does still expose a syscall wrapper.

------
eyberg
I agree with the authors of [https://www.microsoft.com/en-
us/research/uploads/prod/2019/0...](https://www.microsoft.com/en-
us/research/uploads/prod/2019/04/fork-hotos19.pdf) that we should not be
teaching fork and friends to people anymore except out of historical context.
Yes, there is large swaths of software that make extensive use of it but that
software should be re-written in my most humble opinion.

------
cfors
As another resource, I just finished up the chapters of _The Linux Application
Programming Interface_ [0] that described this.

Highly recommend this book, its filled with fun tidbits of Linux-lore.

[0] [https://www.amazon.com/Linux-Programming-Interface-System-
Ha...](https://www.amazon.com/Linux-Programming-Interface-System-
Handbook/dp/1593272200)

------
dogecoinbase
Don't forget unfork()!
[https://github.com/whitequark/unfork](https://github.com/whitequark/unfork)

