syscalls -
системные
вызовы Linux
Системные вызовы Linux.
Системный
вызов — это
основной
интерфейс
между
приложением
и ядром Linux.
Обычно,
системные
вызовы не
вызываются
напрямую,
это
делается
через
обёрточную
функцию из
glibc (или
другой
библиотеки).
Подробней
о
непосредственном
вызове
системного
вызова,
смотрите
intro(2). Часто, но
не всегда,
имя
обёрточной
функции
совпадает
с именем
системного
вызова,
который
она
вызывает.
Например, в
glibc есть
функция
chdir(),
которая
вызывает
делающий
всё работу
системный
вызов «chdir».
Часто,
обёрточная
функция glibc
очень
маленькая,
она просто
копирует
аргументы
в нужные
регистры
перед
запуском
системного
вызова, а
затем
присваивает
переменной
errno значение,
которое
было
возвращено
системным
вызовом.
(Эти те же
шаги
выполняет
syscall(2), её можно
использовать
для
осуществления
системных
вызовов,
для
которых
нет
обёрточных
функций.)
Замечание:
системные
вызовы
указывают,
что
произошла
ошибка
возвращая
отрицательное
целое
число
вызывающей
стороне
(если в
архитектуре
нет
отдельного
регистра/флага
ошибки,
смотрите
syscall(2)); когда
это
происходит,
обёрточная
функция
меняет
знак у
возвращённого
значения
(на
положительный),
копирует
его в
errno и
возвращает
-1 вызвавшей
обёртку
функции.
Иногда,
однако,
обёрточная
функция
производит
дополнительную
работу до
осуществления
системного
вызова.
Например, в
настоящее
время
существует
(по
причинам,
описанным
далее) два
похожих
системных
вызова —
truncate(2)
и
truncate64(2);
обёрточная
функция glibc
truncate()
проверяет
какой из
системных
вызовов
предоставляет
ядро и
решает
какой
нужно
задействовать.
Далее
приведён
список
список
системных
вызовов Linux. В
колонке
Ядро
указана
версия
ядра для
системных
вызовов,
которые
появились
в Linux 2.2, и с какой
именно
версии.
Также
заметим
следующее:
- •
- Where no kernel version is indicated, the system call
appeared in Linux 1.0 or earlier.
- •
- Where a system call is marked "1.2" this means
the system call probably appeared in a Linux 1.1.x kernel version, and
first appeared in a stable kernel with 1.2. (Development of the 1.2 kernel
was initiated from a branch of kernel 1.0.6 via the 1.1.x unstable kernel
series.)
- •
- Where a system call is marked "2.0" this means
the system call probably appeared in a Linux 1.3.x kernel version, and
first appeared in a stable kernel with Linux 2.0. (Development of the
Linux 2.0 kernel was initiated from a branch of Linux 1.2.x, somewhere
around Linux 1.2.10, via the Linux 1.3.x unstable kernel series.)
- •
- Where a system call is marked "2.2" this means
the system call probably appeared in a Linux 2.1.x kernel version, and
first appeared in a stable kernel with Linux 2.2.0. (Development of the
Linux 2.2 kernel was initiated from a branch of kernel Linux 2.0.21 via
the Linux 2.1.x unstable kernel series.)
- •
- Where a system call is marked "2.4" this means
the system call probably appeared in a Linux 2.3.x kernel version, and
first appeared in a stable kernel with Linux 2.4.0. (Development of the
Linux 2.4 kernel was initiated from a branch of Linux 2.2.8 via the Linux
2.3.x unstable kernel series.)
- •
- Where a system call is marked "2.6" this means
the system call probably appeared in a Linux 2.5.x kernel version, and
first appeared in a stable kernel with Linux 2.6.0. (Development of Linux
2.6 was initiated from a branch of Linux 2.4.15 via the Linux 2.5.x
unstable kernel series.)
- •
- Starting with Linux 2.6.0, the development model changed,
and new system calls may appear in each Linux 2.6.x release. In this case,
the exact version number where the system call appeared is shown. This
convention continues with the Linux 3.x kernel series, which followed on
from Linux 2.6.39; and the Linux 4.x kernel series, which followed on from
Linux 3.19; and the Linux 5.x kernel series, which followed on from Linux
4.20.
- •
- In some cases, a system call was added to a stable kernel
series after it branched from the previous stable kernel series, and then
backported into the earlier stable kernel series. For example some system
calls that appeared in Linux 2.6.x were also backported into a Linux 2.4.x
release after Linux 2.4.15. When this is so, the version where the system
call appeared in both of the major kernel series is listed.
The list of system calls that are available as at Linux 5.14 (or in a few cases
only on older kernels) is as follows:
Для многих
платформ,
включая x86-32,
все
сокетные
вызовы
мультиплексируются
(с помощью
обёрточных
функций glibc)
через
socketcall(2), а
подобные IPC
вызовы System V
мультиплексируются
через
ipc(2).
Although slots are reserved for them in the system call table, the following
system calls are not implemented in the standard kernel:
afs_syscall(2),
break(2),
ftime(2),
getpmsg(2),
gtty(2),
idle(2),
lock(2),
madvise1(2),
mpx(2),
phys(2),
prof(2),
profil(2),
putpmsg(2),
security(2),
stty(2),
tuxcall(2),
ulimit(2), and
vserver(2) (see also
unimplemented(2)).
However,
ftime(3),
profil(3), and
ulimit(3) exist as
library routines. The slot for
phys(2) is in use since Linux 2.1.116
for
umount(2);
phys(2) will never be implemented. The
getpmsg(2) and
putpmsg(2) calls are for kernels patched to
support STREAMS, and may never be in the standard kernel.
There was briefly
set_zone_reclaim(2), added in Linux 2.6.13, and removed
in Linux 2.6.16; this system call was never available to user space.
Some system calls only ever existed on Linux architectures that have since been
removed from the kernel:
- AVR32 (port removed in Linux 4.12)
- Blackfin (port removed in Linux 4.17)
- Metag (port removed in Linux 4.17)
- Tile (port removed in Linux 4.17)
Чаще всего,
код
системного
вызова с
номером __NR_xxx,
определённого
в
/usr/include/asm/unistdh,
можно
найти в
исходном
коде ядра Linux
в функции
sys_xxx(). Есть
много
исключений
из этого
правила, в
основном
из-за того,
что
большинство
старых
системных
вызовов
заменена
на новые,
при чём без
всякой
системы. На
платформах
с
эмуляцией
собственнических
ОС, таких
как sparc, sparc64 и alpha,
существует
много
дополнительных
системных
вызовов;
для mips64 также
есть
полный
набор
32-битных
системных
вызовов.
С течением
времени
при
необходимости
происходили
изменения
в
интерфейсе
некоторых
системных
вызовов.
Одной из
причин
таких
изменений
была
необходимость
увеличения
размера
структур
или
скалярных
значений
передаваемых
системному
вызову.
Из-за этих
изменений
на
некоторых
архитектурах
(а именно на
старых
32-битных i386)
появились
различные
группы
похожих
системных
вызовов
(например,
truncate(2) и
truncate64(2)),
которые
выполняют
одинаковые
задачи, но
отличаются
размером
своих
аргументов.
(Как уже
отмечалось,
на
приложения
это не
влияет:
обёрточные
функции glibc
выполняют
некоторые
действия
по запуску
правильного
системного
вызова, и
это
обеспечивает
совместимость
по ABI для
старых
двоичных
файлов.)
Примеры
системных
вызовов, у
которых
есть
несколько
версий:
- •
- В
настоящее
время есть
три
различные
версии stat(2):
sys_stat() (место
__NR_oldstat), sys_newstat()
(место __NR_stat) и
sys_stat64() (место
__NR_stat64),
последняя
используется
в в данный
момент.
Похожая
ситуация с
lstat(2) и fstat(2).
- •
- Похожим
образом
определены
__NR_oldolduname, __NR_olduname и __NR_uname
для
вызовов
sys_olduname(), sys_uname() и
sys_newuname().
- •
- В Linux 2.0
появилась
новая
версия vm86(2),
новая и
старая
версии
ядерных
процедур
называются
sys_vm86old() и sys_vm86().
- •
- В Linux 2.4
появилась
новая
версия getrlimit(2)
новая и
старая
версии
ядерных
процедур
называются
sys_old_getrlimit() (место
__NR_getrlimit) и sys_getrlimit()
(место __NR_ugetrlimit).
- •
- В Linux 2.4
увеличено
размер
поля ID
пользователей
и групп с 16
до 32 бит. Для
поддержки
этого
изменения
добавлено
несколько
системных
вызовов
(например,
chown32(2), getuid32(2), getgroups32(2),
setresuid32(2)),
упраздняющих
ранние
вызовы с
теми же
именами, но
без
суффикса
"32".
- •
- В Linux 2.4
добавлена
поддержка
доступа к
большим
файлам (у
которых
размеры и
смещения
не
умещаются
в 32 бита) в
приложениях
на 32-битных
архитектурах.
Для этого
потребовалось
внести
изменения
в
системные
вызовы,
работающие
с
размерами
и
смещениями
по файлам.
Были
добавлены
следующие
системные
вызовы: fcntl64(2),
getdents64(2), stat64(2), statfs64(2),
truncate64(2) и их
аналоги,
которые
обрабатывают
файловые
дескрипторы
или
символьные
ссылки. Эти
системные
вызовы
упраздняют
старые
системные
вызовы,
которые, за
исключением
вызовов
«stat»,
называются
также, но
не имеют
суффикса
«64».
- На новых
платформах,
имеющих
только
64-битный
доступ к
файлам и
32-битные UID/GID
(например, alpha,
ia64, s390x, x86-64), есть
только
одна
версия
системных
вызовов
для UID/GID и
файлового
доступа. На
платформах
(обычно это
32-битные
платформы)
где
имеются *64 и *32
вызовы,
другие
версии
устарели.
- •
- The rt_sig* calls were added in Linux 2.2 to support
the addition of real-time signals (see signal(7)). These system
calls supersede the older system calls of the same name without the
"rt_" prefix.
- •
- В
системных
вызовах select(2)
и mmap(2)
используется
пять или
более
аргументов,
что
вызывало
проблемы
определения
способа
передачи
аргументов
на i386(). В
следствии
этого,
тогда как
на других
архитектурах
вызовы sys_select()
и sys_mmap()
соответствуют
__NR_select и __NR_mmap, на i386
они
соответствуют
old_select() и old_mmap()
(процедуры,
использующие
указатель
на блок
аргументов).
В
настоящее
время
больше нет
проблемы с
передачей
более пяти
аргументов
и есть __NR__newselect,
который
соответствует
именно sys_select()
и тоже
самое с __NR_mmap2.
На s390x только
64-битная
архитектура
имеет old_mmap.
-
getxgid(2)
- returns a pair of GID and effective GID via registers
r0 and r20; it is provided instead of getgid(2) and
getegid(2).
-
getxpid(2)
- returns a pair of PID and parent PID via registers
r0 and r20; it is provided instead of getpid(2) and
getppid(2).
-
old_adjtimex(2)
- is a variant of adjtimex(2) that uses struct
timeval32, for compatibility with OSF/1.
-
getxuid(2)
- returns a pair of GID and effective GID via registers
r0 and r20; it is provided instead of getuid(2) and
geteuid(2).
-
sethae(2)
- is used for configuring the Host Address Extension register
on low-cost Alphas in order to access address space beyond first 27
bits.
ausyscall(1),
intro(2),
syscall(2),
unimplemented(2),
errno(3),
libc(7),
vdso(7)
Русский
перевод
этой
страницы
руководства
был сделан
Alexander Golubev <
[email protected]>, Azamat Hackimov
<
[email protected]>, Hotellook, Nikita
<
[email protected]>, Spiros Georgaras <
[email protected]>, Vladislav
<
[email protected]>, Yuri Kozlov <
[email protected]>
и Иван
Павлов <
[email protected]>
Этот
перевод
является
бесплатной
документацией;
прочитайте
Стандартную
общественную
лицензию GNU
версии 3
или более
позднюю,
чтобы
узнать об
условиях
авторского
права. Мы не
несем
НИКАКОЙ
ОТВЕТСТВЕННОСТИ.
Если вы
обнаружите
ошибки в
переводе
этой
страницы
руководства,
пожалуйста,
отправьте
электронное
письмо на
[email protected]