• Uncategorized

About c : Applications-of-system-function-in-launching-and-waiting-for-a-new-process

Question Detail

I am currently learning System Programming and came across the usage of int system(const char* command) in the chapter Process Management. They say that if a process is spawning a child, only to immediately wait for its temination, it is better to use system(const char* command).

What does it mean by the sentence “The command parameter is suffixed to the arguments /bin/sh -c.

And how are fork(), exec(),waitpid() system calls associated with this?

Question Answer

See the manpages for these calls:

From man 2 fork: https://man7.org/linux/man-pages/man2/fork.2.html

fork() creates a new process by duplicating the calling process.
The new process is referred to as the child process. The calling
process is referred to as the parent process.

From man 3 exec: https://man7.org/linux/man-pages/man3/exec.3.html

The exec() family of functions replaces the current process image
with a new process image.

From man 3 system: https://man7.org/linux/man-pages/man3/system.3.html

The system() library function uses fork(2) to create a child
process that executes the shell command specified in command
using execl(3) as follows:

      execl("/bin/sh", "sh", "-c", command, (char *) NULL);

system() returns after the command has been completed.

So system() is a fast way to run a command on a shell which itself will use fork() and exec() to execute the given command.

Whereby fast only applies to programming effort. Using fork() and exec() directly is much faster in runtime.

What does it mean by the sentence “The command parameter is suffixed to the arguments /bin/sh -c. “

That means that the entire string used with system() will be passed to
and executed by /bin/sh which really can be anything but in majority
of cases it’s some variant of POSIX-compliant shell such as Dash on
Ubuntu, Bash on Slackware, busybox ash on embedded Linux distros or
tcsh on FreeBSD. Since command is executed by shell you can use
commands in $PATH, shell builtins and shell constructs such as |,
&&, loops, redirections, command substitutions and so on. For
example you can do:

system("echo Date now: $(date) > /tmp/NOW");

just like you would do in your terminal emulator. Notice that system()
starts non-interactive shell so you cannot use aliases and other
features such as Bash history expansions that work only in interactive
shells. Also notice that you have to get quoting right because the
string you pass to system() will be first parsed by the C compiler and
then by shell.

And how are fork(), exec(),waitpid() system calls associated with

system() can be considered an easy-to-use wrapper over fork(), exec()
and waitpid(). You can write a simple main.c program:

#include <stdio.h>
#include <stdlib.h>

int main(void)
  system("echo Date now: $(date) > /tmp/NOW");

  return EXIT_SUCCESS;

Compile it:

gcc main.c -o main -Wall -Wextra -pedantic

And run in under strace:

strace -f ./main

You’ll see that ./main firsts forks the new process using clone()
syscall (you’ll not find fork() here):

clone(child_stack=0x7f7ed4a58ff0, flags=CLONE_VM|CLONE_VFORK|SIGCHLDstrace: Process 31782 attached

Then execs /bin/sh with specified arguments:

[pid 31782] execve("/bin/sh", ["sh", "-c", "echo Date now: $(date) > /tmp/NO"...], 0x7ffd91f10418 /* 61 vars */ <unfinished ...>

and then waits for it:

[pid 31781] wait4(31782,  <unfinished ...>

If you feel fluent in C you can read libc source code to see how are
wrappers such as system() implemented but Glibc that you most probably
use on your Linux distro can be very hard to read and understand so
oftentimes it’s better to read musl libc source
https://git.musl-libc.org/cgit/musl/tree/src/process/system.c (of
course implementation between Glibc and other C libraries can differ
but reading musl source code should give a generic understanding about
how the given system can be implemented in Glibc).

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.