Zaid Khan
Zaid Khan

Reputation: 826

fork() vs. CreateProcess(). System call vs. API?

Assuming that APIs are generally similar(and in some cases same) to the System Calls they invoke....

Does the fork() we invoke in our user application, a 'API in POSIX' which invokes the actual system call 'fork()'? Or do we directly invoke fork() system call?

And how does it compares to CreateProcess() in Win32 API.

Is CreateProcess() a system call which invokes another system call NTCreateProcess() system call OR Is CreateProcess() a function in the Win32 API which invokes NTCreateProcess() system call?

Upvotes: 2

Views: 2816

Answers (2)

Filipe Gonçalves
Filipe Gonçalves

Reputation: 21223

I can only speak for Linux and UNIX variants, but I imagine Windows is similar.

Does the fork() we invoke in our user application, a 'API in POSIX' which invokes the actual system call 'fork()'? Or do we directly invoke fork() system call?

In Linux, fork(2) is a syscall, but recent Linux versions don't use it in most cases. When you call fork(2) from a C user program, you're calling the glibc wrapper, not the real syscall - as of the latest version, the glibc wrapper invokes clone(2) and passes it the necessary flags to indicate the attributes of the new process. clone(2) is the real syscall (see man 2 clone).

However, even if you call clone(2) directly in a C program, you will be calling the glibc wrapper function. Most raw syscalls have an equivalent wrapper function in glibc because raw syscall invocation is architecture dependent.

Some manpages include the prototype for both, the wrapper and the raw syscall. For example, the manpage for clone(2) shows both variants:

SYNOPSIS
/* Prototype for the glibc wrapper function */

#include <sched.h>

int clone(int (*fn)(void *), void *child_stack,
          int flags, void *arg, ...
          /* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );

/* Prototype for the raw system call */

long clone(unsigned long flags, void *child_stack,
            void *ptid, void *ctid,
            struct pt_regs *regs);

You can usually learn a lot from the manpages. man 2 fork mentions what I said above in the notes section:

NOTES

Under Linux, fork() is implemented using copy-on-write pages, so the only penalty that it incurs is the time and memory required to duplicate the parent's page tables, and to create a unique task structure for the child.

Since version 2.3.3, rather than invoking the kernel's fork() system call, the glibc fork() wrapper that is provided as part of the NPTL threading implementation invokes clone(2) with flags that provide the same effect as the traditional system call. (A call to fork() is equivalent to a call to clone(2) specifying flags as just SIGCHLD.) The glibc wrapper invokes any fork handlers that have been established using pthread_atfork(3).

(If you're wondering, NPTL stands for Native POSIX Threads Library)

TL;DR When you're programming, you never really invoke syscalls directly. You invoke the glibc wrappers that handle the nitty gritty details of raw syscall invocation.

Upvotes: 2

Ross Ridge
Ross Ridge

Reputation: 39631

As Jeffy Coffin pointed, API stands for Application Program Interface, and is a document that describes a set of functions, related types and other language interfaces and features for use by applications. An API can be pretty much anything. For example Stack Exchange has a web API that can be used by anything capable of making HTTP requests over the Internet.

Also, as Jerry Coffin said the term "system call" isn't very well defined. It just means an API function that implements an operating service. You could argue that neither CreateProcess nor NTCreateProcess are system calls. Both are C wrappers around the true system call, which is bit code written in assembly. On the other hand, I'd argue they're both system calls. They both offer access to the operating system's facility for creating new processes with no significant extra added functionality. Either way, it doesn't really matter.

Upvotes: 0

Related Questions