table of contents
| syscall(2) | System Calls Manual | syscall(2) |
NAVN¶
syscall - indirekte systemkald
BIBLIOTEK¶
C-standardbibliotek (libc, -lc)
SYNOPSIS¶
#include <sys/syscall.h> /* Definition af SYS_* konstanter */ #include <unistd.h>
long syscall(long nummer, ...);
syscall():
Siden glibc 2.19:
_DEFAULT_SOURCE
Før glibc 2.19:
_BSD_SOURCE || _SVID_SOURCE
BESKRIVELSE¶
syscall() er en lille biblioteksfunktion, der igangsætter systemkaldet hvis assembly-sproggrænseflade har det angivne nummer med de angivne argumenter. Anvendelse af syscall() er nyttig, for eksempel, når et systemkald igangsættes uden en omslagsfunktion i C-biblioteket.
syscall() gemmer cpu-registre før der laves systemkald, gendanner registrerne ved returnering fra systemkaldet og lagrer eventuelle fejl returneret af systemkaldet i errno(3).
Symbolske konstanter for systemkaldnumre kan findes i teksthovedfilen <sys/syscall.h>.
RETURVÆRDI¶
Returværdien er defineret af systemkaldet der igangsættes. Generelt indikerer en 0 returværdi succes. En returværdi på -1 indikerer en fejl og et fejlnummer lagres i errno.
FEJL¶
- ENOSYS
- Det anmodet systemkaldnummer er ikke implementeret.
Andre fejl er specifikke for det igangsatte systemkald.
HISTORIK¶
syscall() kom først i 4BSD.
NOTER¶
Arkitekturspecifikke krav¶
Hver arkitektur-ABI har sine egne krav til hvordan systemkaldargumenter sendes til kernen. For systemkald der har et glibc-omslag (f.eks. de fleste systemkald), så håndterer glibc detaljerne ved at kopiere argumenter til de korrekte registre på en måde egnet for arkitekturen. Når syscall() bruges til at lave et systemkald, så skal kalderen måske håndtere detaljer, der afhænger af arkitekturen; dette krav ses oftest på bestemte 32-bit arkitekturer.
For eksempel på den ARM architecture Embedded ABI (EABI) skal en 64-bit værdi (f.eks. long long) være justeret til et lige registerpar. Brug af syscall() i stedet for omslaget tilbudt af glibc, vil gøre at systemkaldet readahead(2) bliver igangsat som vist efterfølgende på ARM-arkitekturen med EABI i little endian-tilstand:
syscall(SYS_readahead, fd, 0,
(unsigned int) (offset & 0xFFFFFFFF),
(unsigned int) (offset >> 32),
count);
Da forskydningsargumentet er 64 bit og det første argument (fd) sendes i r0, skal kalderen manuelt opdele og justere 64-bit værdien, så den sendes i registerparret r2/r3. Det betyder indsættelse af en erstatningsværdi i r1 (det andet argument for 0). Der skal tages speciel hensyn til at opdelingen følger endian-konventionerne (jævnfør C ABI'en for platformen).
Lignende problemstillinger kan opstå på MIPS med 032 ABI'en, på PowerPC og parisc med 32-bit ABI*en og på Xtensa.
Bemærk at mens parisc C-ABI'en også bruger justerede registerpar, så bruges et shim-lag til at skjule problemstillingen fra brugerummet.
De påvirkede systemkald er fadvise64_64(2), ftruncate64(2), posix_fadvise(2), pread64(2), pwrite64(2), readahead(2), sync_file_range(2) og truncate64(2).
Dette påvirker ikke systemkald, der manuelt opdeler og samler 64-bit værdier såsom _llseek(2), preadv(2), preadv2(2), pwritev(2) og pwritev2(2). Velkommen til den vidunderlige verden med historisk bagage.
Arkitekturkaldende konventioner¶
Hver arkitektur har sin egen måde at igangsætte og sende argumenter til kernen. Detaljerne for de forskellige arkitekturer er vistn i de to tabeller nedenfor.
Den første tabel viser instruktionen brugt til overgangen til kernetilstand (som måske ikke er den hurtigste eller bedste måde at lave overgang til kernen, så du skal måske referere til vdso(7)), registret brugt til at indikere systemkaldnummeret, registrene brugt til at returnere systemkaldresultatet, og registret brugt til at signalere en fejl.
| Arch/ABI | Instruktion | System | Ret | Ret | Fejl | Noter |
| kald # | val | val2 | ||||
| alpha | callsys | v0 | v0 | a4 | a3 | 1, 6 |
| arc | trap0 | r8 | r0 | - | - | |
| arm/OABI | swi NR | - | r0 | - | - | 2 |
| arm/EABI | swi 0x0 | r7 | r0 | r1 | - | |
| arm64 | svc #0 | w8 | x0 | x1 | - | |
| blackfin | excpt 0x0 | P0 | R0 | - | - | |
| i386 | int $0x80 | eax | eax | edx | - | |
| ia64 | break 0x100000 | r15 | r8 | r9 | r10 | 1, 6 |
| loongarch | syscall 0 | a7 | a0 | - | - | |
| m68k | trap #0 | d0 | d0 | - | - | |
| microblaze | brki r14,8 | r12 | r3 | - | - | |
| mips | syscall | v0 | v0 | v1 | a3 | 1, 6 |
| nios2 | trap | r2 | r2 | - | r7 | |
| parisc | ble 0x100(%sr2, %r0) | r20 | r28 | - | - | |
| powerpc | sc | r0 | r3 | - | r0 | 1 |
| powerpc64 | sc | r0 | r3 | - | cr0.SO | 1 |
| riscv | ecall | a7 | a0 | a1 | - | |
| s390 | svc 0 | r1 | r2 | r3 | - | 3 |
| s390x | svc 0 | r1 | r2 | r3 | - | 3 |
| superh | trapa #31 | r3 | r0 | r1 | - | 4, 6 |
| sparc/32 | t 0x10 | g1 | o0 | o1 | psr/csr | 1, 6 |
| sparc/64 | t 0x6d | g1 | o0 | o1 | psr/csr | 1, 6 |
| tile | swint1 | R10 | R00 | - | R01 | 1 |
| x86-64 | syscall | eax | rax | rdx | - | 5 |
| x32 | syscall | eax | rax | rdx | - | 5 |
| xtensa | syscall | a2 | a2 | - | - |
Noter:
- [1]
- På nogle få arkitekturer bruges et register som en boolesk fejl (0 indikerer fejl og -1 indikerer en fejl) til at signalere at systemkaldet fejlede. Den faktiske fejlværdi er stadig indeholdet i returregistret. På sparc bruges den bærende del (csr) i processorstatusregistret (psr) i stedet for et fuldt register. På powerpc64 bruges den summerende overflydende del (SO) i felt 0 for betingelsesregistret (cr0).
- [2]
- NR er systemkaldets nummer.
- [3]
- For s390 og s390x kan NR (systemkaldnummeret) sendes direkte med svc NR hvis det er mindre end 256.
- [4]
- På SuperH er yderligere trap-numre understøttet af historiske årsager, men trapa#31 er den anbefalede »forenet« ABI.
- [5]
- x32-ABI'en deler systemkaldtabel med x86-64-ABI'en, men der er nogle nuancer:
- •
- For at indikere at et systemkald kaldes under x32-ABI'en bliver en yderligere del, __X32_SYSCALL_BIT, stykvis ORed med systemkaldnummeret. ABI'en brugt af en proces der påvirker nogle procesopførelser, inklusive signalhåndtering eller genstart af systemkald.
- •
- Da x32 for forskellige størrelser for long og pegertyper, er layout for nogle (men ikke alle; struct timeval eller struct rlimit er f.eks. 64-bit) strukturer forskellige. For at kunne håndtere dette tilføjes yderligere systemkald til systemkaldtabellen, startende fra nummer 512 (uden __X32_SYSCALL_BIT). For eksempel er __NR_readv defineret som 19 for x86-64-ABI og som __X32_SYSCALL_BIT | 515 for x32-ABI'en. De fleste af disse yderligere systemkald er faktisk identiske med systemkaldene brugt til at tilbyde i386 compat. Der er dog nogle bemærkelsesværdige undtagelser såsom preadv2(2), der bruger struct iovec-entiteter med 4-byte pegere og størrelser (»compat_iovec« i kernetermer), men sender et 8-byte pos-argument i et enkelt register og ikke to, som det gøres i enhver anden ABI.
- [6]
- Nogle arkitekturer (navnlig, Alpha, IA-64, MIPS, SuperH, sparc/32 og sparc/64) bruger et yderligere register (»Retval2« i den ovenstående tabel) til at sende en anden returværdi fra systemkaldet pipe(2); Alpha bruger også denne teknik i de for arkitekturen specifikke systemkald getxpid(2), getxuid(2) og getxgid(2). Andre arkitekturer bruger ikke det andet returværdiregistrer i systemkaldgrænsefladen, selv om den er defineret i System V ABI'en.
Den anden tabel viser registrene brugt til at sende systemkaldargumenterne.
| Arch/ABI | arg1 | arg2 | arg3 | arg4 | arg5 | arg6 | arg7 | Noter |
| alpha | a0 | a1 | a2 | a3 | a4 | a5 | - | |
| arc | r0 | r1 | r2 | r3 | r4 | r5 | - | |
| arm/OABI | r0 | r1 | r2 | r3 | r4 | r5 | r7 | |
| arm/EABI | r0 | r1 | r2 | r3 | r4 | r5 | r7 | |
| arm64 | x0 | x1 | x2 | x3 | x4 | x5 | - | |
| blackfin | R0 | R1 | R2 | R3 | R4 | R5 | - | |
| i386 | ebx | ecx | edx | esi | edi | ebp | - | |
| ia64 | out0 | out1 | out2 | out3 | out4 | out5 | - | |
| loongarch | a0 | a1 | a2 | a3 | a4 | a5 | a6 | |
| m68k | d1 | d2 | d3 | d4 | d5 | a0 | - | |
| microblaze | r5 | r7 | r7 | r8 | r9 | r10 | - | |
| mips/o32 | a0 | a1 | a2 | a3 | - | - | - | 1 |
| mips/n32,64 | a0 | a1 | a2 | a3 | a4 | a5 | - | |
| nios2 | r4 | r5 | r7 | r7 | r8 | r9 | - | |
| parisc | r26 | r25 | r24 | r23 | r22 | r21 | - | |
| powerpc | r3 | r4 | r5 | r7 | r7 | r8 | r9 | |
| powerpc64 | r3 | r4 | r5 | r7 | r7 | r8 | - | |
| riscv | a0 | a1 | a2 | a3 | a4 | a5 | - | |
| s390 | r2 | r3 | r4 | r5 | r7 | r7 | - | |
| s390x | r2 | r3 | r4 | r5 | r7 | r7 | - | |
| superh | r4 | r5 | r7 | r7 | r0 | r1 | r2 | |
| sparc/32 | o0 | o1 | o2 | o3 | o4 | o5 | - | |
| sparc/64 | o0 | o1 | o2 | o3 | o4 | o5 | - | |
| tile | R00 | R01 | R02 | R03 | R04 | R05 | - | |
| x86-64 | rdi | rsi | rdx | r10 | r8 | r9 | - | |
| x32 | rdi | rsi | rdx | r10 | r8 | r9 | - | |
| xtensa | a6 | a3 | a4 | a5 | a8 | a9 | - |
Noter:
- [1]
- Mips/o32-systemkaldkonventionen sender argumenterne 5 til 8 på brugerstakken.
Bemærk at disse tabeller ikke dækker hele den kaldende konvention—nogle arkitekturer kan vilkårligt også ramme andre registre hårdt, der ikke er anført her.
EKSEMPLER¶
#define _GNU_SOURCE
#include <signal.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
int
main(void)
{
pid_t tid;
tid = syscall(SYS_gettid);
syscall(SYS_tgkill, getpid(), tid, SIGHUP);
}
SE OGSŶ
OVERSÆTTELSE¶
Oversættere af denne manual til dansk Joe Hansen <joedalton2@yahoo.dk>
Denne oversættelse er gratis dokumentation; læs GNU General Public License version 3 eller nyere for ophavsretbetingelser. Der er INGEN ANSVAR.
Hvis du støder på fejl i oversættelsen af denne vejledning, skal du sende en besked til debian-l10n-danish@lists.debian.org.
| 2. februar 2026 | Linux man-pages (ej udgivet) |