1. NOM

syscall - appel système indirect

2. SYNOPSIS

 
Sélectionnez
#define _GNU_SOURCE         /* Consultez feature_test_macros(7) */
#include <unistd.h>
#include <sys/syscall.h>   /* Pour les définitions de SYS_xxx */
int syscall(int numéro, ...);

3. DESCRIPTION

syscall() est une petite fonction de bibliothèque qui invoque l'appel système dont l'interface en assembleur a le numéro indiqué avec les arguments donnés. L'utilisation de syscall() est pratique, par exemple, pour invoquer un appel système qui n'a pas de fonction autour de cet appel système dans la bibliothèque C. syscall() sauve les registres du processeur avant de faire l'appel système, restaure les registres au retour de l'appel système et stocke tous les codes d'erreur renvoyés par l'appel système dans errno(3) en cas d'erreur. Les constantes symboliques correspondant aux appels système sont dans le fichier d'en-tête <sys/syscall.h>.

4. VALEUR RENVOYÉE

La valeur de retour est définie par l'appel système invoqué. En général, une valeur de retour nulle indique une réussite. Une valeur de retour de -1 indique une erreur, et un code d'erreur est fourni dans errno.

5. NOTES

syscall() est apparu dans BSD 4.

5.1. Exigences dépendantes de l'architecture

L'ABI de chaque architecture possède ses propres exigences sur la façon dont les paramètres des appels système sont passés au noyau. Pour les appels système qui ont une fonction d'enrobage de la glibc (comme par exemple la plupart des appels système), glibc s'occupe des détails pour copier les arguments dans les bons registres d'une manière adaptée à chaque architecture. Cependant, en utilisant syscall() pour effectuer un appel système, l'appelant peut avoir besoin de gérer certains détails dépendants de l'architecture ; cette exigence est en particulier rencontrée sur certaines architectures 32 bits. Par exemple, pour l'Embedded ABI (EABI) de l'architecture ARM, une valeur 64 bits (c'est-à-dire un long long) doit être alignée sur une paire de registres paire. Ainsi, en appelant syscall() au lieu de la fonction d'enrobage fournie par la glibc, l'appel système readahead() devrait être effectué ainsi sur l'architecture ARM avec l'EABI :

 
Sélectionnez
syscall(SYS_readahead, fd, 0,
        (unsigned int) (offset >> 32),
        (unsigned int) (offset & 0xFFFFFFFF),
        count);

Comme le paramètre offset est 64 bits, et le premier argument (fd) est passé dans r0, l'appelant doit manuellement découper et aligner la valeur 64 bits afin de la passer dans la paire de registres r2/r3. Ceci implique de passer une valeur fantôme dans r1 (le second argument, qui vaut 0). Des problèmes similaires peuvent survenir sur MIPS avec l'ABI O32, sur PowerPC avec l'ABI 32 bits, et sur Xtensa. Les appels système concernés sont fadvise64_64(2), ftruncate64(2), posix_fadvise(2), pread64(2), pwrite64(2), readahead(2), sync_file_range(2) et truncate64(2).

5.2. Conventions d'appel par architecture

Chaque architecture possède sa façon propre d'invoquer et de passer des paramètres au noyau. Les détails pour diverses architectures sont donnés dans les deux tableaux ci-dessous. Le premier tableau donne l'instruction utilisée pour passer en mode noyau (qui n'est pas forcément la méthode la meilleure ou la plus rapide, vous devriez consulter le VDSO), le registre utilisé pour indiquer le numéro de l'appel système, et le registre utilisé comme code de retour de l'appel système.

\

l l1 l l1 l.
arch/ABI instruction appel syst. val. ret. Notes
_
arm/OABI swi NR - a1 T{
NR : numéro d'appel syst.
T}
arm/EABI swi 0x0 r7 r1
blackfin excpt 0x0 P0 R0
i386 int $0x80 eax eax
ia64 break 0x100000 r15 r10/r8
parisc ble 0x100(%sr2, %r0) r20 r28
s390 svc 0 r1 r2 NR peut être passé directement :
s390x svc 0 r1 r2 "svc NR" si NR inférieur à 256
sparc/32 t 0x10 g1 o0
sparc/64 t 0x6d g1 o0
x86_64 syscall rax rax

\

Le second tableau montre les registres utilisés pour passer les paramètres de l'appel système.

\

arch/ABI par1 par2 par3 par4 par5 par6 par7
_
arm/OABI a1 a2 a3 a4 v1 v2 v3
arm/EABI r1 r2 r3 r4 r5 r6 r7
blackfin R0 R1 R2 R3 R4 R5 -
i386 ebx ecx edx esi edi ebp -
ia64 r11 r9 r10 r14 r15 r13 -
parisc r26 r25 r24 r23 r22 r21 -
s390 r2 r3 r4 r5 r6 r7 -
s390x r2 r3 r4 r5 r6 r7 -
sparc/32 o0 o1 o2 o3 o4 o5 -
sparc/64 o0 o1 o2 o3 o4 o5 -
x86_64 rdi rsi rdx r10 r8 r9 -

\

Notez que ces tableaux ne couvrent pas l'ensemble des conventions d'appel système, certaines architectures peuvent écraser d'autres registres non listés ici.

6. EXEMPLE

 
Sélectionnez
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
int
main(int argc, char *argv[])
{
    pid_t tid;
    tid = syscall(SYS_gettid);
    tid = syscall(SYS_tgkill, getpid(), tid);
}

7. VOIR AUSSI

_syscall(2), intro(2), syscalls(2)

8. COLOPHON

Cette page fait partie de la publication 3.52 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies peuvent être trouvées à l'adresse http://www.kernel.org/doc/man-pages/.

9. TRADUCTION

Depuis 2010, cette traduction est maintenue à l'aide de l'outil po4a <http://po4a.alioth.debian.org/> par l'équipe de traduction francophone au sein du projet perkamon <http://perkamon.alioth.debian.org/>.

Thierry Vignaud (2002), Alain Portal <http://manpagesfr.free.fr/> (2006). Julien Cristau et l'équipe francophone de traduction de Debian (2006-2009).

Veuillez signaler toute erreur de traduction en écrivant à <>.

Vous pouvez toujours avoir accès à la version anglaise de ce document en utilisant la commande « LC_ALL=C man <section> <page_de_man> ».