Для новичков как вообще в Linux, так и в конкретной теме, к которой относится вопрос.
Модератор: Bizdelnick
жучара
Сообщения: 1194
ОС: Debian 12
Сообщение
жучара » 12.11.2026 02:51
Друзья! Вот код, в нём системный вызов делается напрямую из кода приложения.
Shell
$ cat foo.c
/*foo.c*/
#include <unistd.h>
#include <sys/syscall.h>
int main(int argc, char** argv) {
char message[20] = "Hello World!\n";
syscall (__NR_write, 1, message, 13);
return 0;
}
$
$
$ gcc foo.c
$
$
$ ./a.out
Hello World!
$
Вот как определить номер системного вызова
__NR_write ? Я бы так сделал:
Shell
$ grep "__NR_write " $(sudo find / -name unistd.h 2>/dev/null) | column -t
/usr/include/asm-generic/unistd.h:#define __NR_write 64
/usr/src/linux-headers-6.1.0-35-common/include/uapi/asm-generic/unistd.h:#define __NR_write 64
$
То есть номер
64 . Да, но посмотрим на работу препроцессора:
Shell
$ gcc -E foo.c | tail -n 10
# 6 "foo.c"
int main(int argc, char** argv) {
char message[20] = "Hello World!\n";
syscall (
# 8 "foo.c" 3 4
1
# 8 "foo.c"
, 1, message, 13);
return 0;
}
$
Кроме того:
Shell
$ strace -n ./a.out 2>&1 | grep write
[ 1] write(1, "Hello World!\n", 13Hello World!
$
Вот сижу, думаю. Там номер
64 , а тут номер
1 . Собсно, сабж.
Debian 12 , система нулёвая. Спасибо, кто откликнется.
Я просто читаю маны.
math
Сообщения: 328
Статус: Ъ участник
ОС: LMDE
Сообщение
math » 12.11.2026 12:14
Номера зависят от архитектуры. На x86 одни, на x86_64 другие, на arm третьи и т. д. Так что проще всего и надёжнее написать простую программу, чтобы она их печатала. А конкретно, если интересно, для x86_64 они прописаны в /usr/include/x86_64-linux-gnu/asm/unistd_64.h
Bizdelnick
Модератор
Сообщения: 21584
Статус: nulla salus bello
ОС: Debian GNU/Linux
Сообщение
Bizdelnick » 12.11.2026 14:36
Так надо не рандомный файл из файловой системы смотреть, а те, которые подключаются при данной конкретной сборке данного конкретного исходника.
Shell
% gcc -E foo.c | sed -nE 's/# [[:digit:]]+ "([^"]+)".*/\1/p' | sort -u
<built-in>
<command-line>
foo.c
/usr/include/features.h
/usr/include/features-time64.h
/usr/include/stdc-predef.h
/usr/include/unistd.h
/usr/include/x86_64-linux-gnu/bits/confname.h
/usr/include/x86_64-linux-gnu/bits/environments.h
/usr/include/x86_64-linux-gnu/bits/getopt_core.h
/usr/include/x86_64-linux-gnu/bits/getopt_posix.h
/usr/include/x86_64-linux-gnu/bits/long-double.h
/usr/include/x86_64-linux-gnu/bits/posix_opt.h
/usr/include/x86_64-linux-gnu/bits/syscall.h
/usr/include/x86_64-linux-gnu/bits/time64.h
/usr/include/x86_64-linux-gnu/bits/timesize.h
/usr/include/x86_64-linux-gnu/bits/types.h
/usr/include/x86_64-linux-gnu/bits/typesizes.h
/usr/include/x86_64-linux-gnu/bits/unistd_ext.h
/usr/include/x86_64-linux-gnu/bits/wordsize.h
/usr/include/x86_64-linux-gnu/gnu/stubs-64.h
/usr/include/x86_64-linux-gnu/gnu/stubs.h
/usr/include/x86_64-linux-gnu/sys/cdefs.h
/usr/include/x86_64-linux-gnu/sys/syscall.h
/usr/lib/gcc/x86_64-linux-gnu/14/include/stddef.h
/usr/lib/linux/uapi/x86/asm/unistd_64.h
/usr/lib/linux/uapi/x86/asm/unistd.h
Добавлено (14:40):
Shell
% grep '\<__NR_write\>' $(gcc -E foo.c | sed -nE 's/# [[:digit:]]+ "([^<"][^"]*)".*/\1/p' | sort -u)
foo.c: syscall (__NR_write, 1, message, 13);
/usr/include/x86_64-linux-gnu/bits/syscall.h:#ifdef __NR_write
/usr/include/x86_64-linux-gnu/bits/syscall.h:# define SYS_write __NR_write
/usr/lib/linux/uapi/x86/asm/unistd_64.h:#define __NR_write 1
Пишите правильно:
в консоли
вк у́пе (с чем-либо)
в о бщем
воо бще в течение (часа)
новичо к
ню анс
по у молчанию приемле мо
проблем а
пробо вать
траф ик
pingvinСoffe
Сообщения: 9
ОС: Linux
Сообщение
pingvinСoffe » 12.11.2026 14:49
Если нужен именно тот номер, который подставит препроцессор, проще спросить его самого:
Код: Выделить всё
echo '#include <sys/syscall.h>' | gcc -E -dM - | grep -w __NR_write
На x86_64 выведет #define __NR_write 1. А 64 из asm-generic — это общая таблица для новых архитектур вроде arm64 и riscv, x86_64 её не использует.