Системный вызов, это требование к ОС (ядру) произвести аппаратно/системно
специфическую или привилегированную операцию. В Linux-1.2 были определены 140
системных вызовов. Такие вызовы, как close() реализованы в Linux libc. Эта
реализация часто включает в себя макрос, который в конце концов вызывает
syscall(). Параметры, передаваемые syscall, это номер системного вызова,
перед которым ставятся требуемые аргументы. Номера системных вызовов можно
найти в , а обновленные вместе с новой версией libc в
. Если появились новые системные вызовы, но их до сих
пор нет в libc, вы можете использовать syscall(). Как пример, рассмотрим
закрытие файла при помощи syscall (не советуем, однако):
#include <syscall.h>
extern int syscall(int, ...);
int my_close(int filedescriptor)
{
return syscall(SYS_close, filedescriptor);
}
На i386 системные вызовы ограничены 5-ю аргументами кроме номера
вызова из-за аппаратного числа регистров. На другой архитектуре вы
можете поискать макрос _syscall в и там посмотреть
сколько аргументов поддерживается у вас или $how many developers chose
to support$. Макросами _syscall можно пользоваться вместо syscall(),
но это не рекомендуется, поскольку макрос может развернуться в
функцию, которая уже существует в библиотеке. Поэтому только ядреные
хакеры имеют право поиграться с _syscall :). Для демонстрации
посмотрим на пример close(), использующий макрос _syscall.
_syscall1 раскрывается в функцию close(), и мы получаем твикс: один
close() в libc и один в нашей программе. Возвращаемое syscall() (или
_syscall) значение есть -1, если вызов неудачен и 0 или больше в случае
успеха. В случае неудачи ошибку можно определить по глобальной переменной
errno.
Приведем системные вызовы, возможные в BSD и SYS V, но не допустимые в
LINUX: audit(), audition(), fchroot(), getauid(), getdents(), getmsg(),
mincore(), poll(), putmsg(), setaudit(), setauid().