2016-02-28 4 views
8

Ich habe Programme in C/C++ geschrieben, die die Linux-API nutzen und Systemaufrufe wie fork(), read(), write() usw. machen. Jetzt frage ich mich, ob diese Bibliotheksfunktionen wirklich System sind Aufrufe, oder sind sie eine Art Wrapper-Funktionen.Sind Funktionsaufrufe wie read(), write() tatsächliche Systemaufrufe in Linux?

Was passiert wirklich, wenn ein Programm einen Aufruf von write() aufruft? Wie funktioniert diese Funktion mit dem Kernel? Wenn dies ein Wrapper ist, warum brauchen wir es dann?

+1

Wie wäre es assenbly Code zu lesen, die der Compiler emittiert oder mit einem Debugger zu verfolgen, was Dein Programm? – MikeCAT

+2

Ein schneller Weg, um herauszufinden, welche Anrufe sind einfache System Call Wrapper ist in der Regel zu verwenden "man". Abschnitt 2 enthält Systemaufrufe, so dass "man 2 read" angezeigt wird, ist ein Hinweis darauf, dass das Lesen tatsächlich ein eingehüllter Systemaufruf ist. –

Antwort

6

Alle diese Funktionen sind echte Userspace-Funktionen in libc.so, gegen die Ihre Binärdatei gebunden ist. Aber die meisten von ihnen sind nur kleine Wrapper für syscalls, die die Schnittstelle zwischen dem Userspace und dem Kernel sind (siehe auch syscall(2)).

Beachten Sie, dass Funktionen, die reinen User-Space sind (wie fmod(3)) oder einige Dinge in User-Space zusätzlich zu tun, den Kernel zu fordern (wie execl(3)) 3 ihren manpages im Abschnitt haben, während Funktionen, die (wie read(2)) nur den Kernel anrufen sie im Abschnitt 2.

+0

Es ist umgekehrt. Funktionen, die reine Wrapper sind, sind in Abschnitt 2. Abschnitt 3 ist oder der Rest. Siehe z.B. execl (3) und execve (2). – a3f

+0

@ a3f Das ist, was er gesagt hat. System-Call-Wrapper in Abschnitt 2, reine User-Space-Funktion in Abschnitt 3. – EJP

+2

@EJP Jemand könnte glauben, dass Einträge in Abschnitt 3 den Kernel nicht aufrufen. Wie sonst müssten sie in Abschnitt 2 sein, weil die Antwort derzeit besagt, dass "Funktionen, die den Kernel aufrufen, sie in Abschnitt 2 haben". – a3f

1

diesen einfachen Code:

int main() 
{ 
    int f = open("/tmp/test.txt", O_CREAT | O_RDWR, 0666); 
    write(f, "hello world", 11); 
    close(f); 

    return 0; 
} 

Sie können strace verwenden, um Systemaufrufe verwendet in der Binärdatei zu finden:

gcc test.c -o test 
strace ./test 

das Ergebnis ist so etwas wie dieses:

. 
. 
. 
open("/tmp/test.txt", O_RDWR|O_CREAT, 0666) = 3 
write(3, "hello world", 11)    = 11 
close(3)        = 0 
exit_group(0)       = ? 

wie für fork(), es ist eigentlich ein Wrapper um clone() Systemaufruf

Verwandte Themen