обработка ошибок syscall внутри ядра linux
Я пишу новый syscall внутри ядра linux. Я хочу реализовать систему обработки ошибок, чтобы вернуть пользователю, который использует sycall код, который описывает тип ошибки. Я хотел бы знать, как это делается внутри ядра, так как я хочу следовать стандарту. Я хочу, чтобы пользователь прочитал переменную errno или что-то эквивалентное, чтобы понять ошибку, которая произошла. Спасибо.
P. S. Я, используя последние версии для Linux доступно.
3 ответа:
Большая часть вашей задачи выполняется автоматически libc и низкоуровневым обработчиком ядра syscall (часть, написанная в сборке). Соглашение ядра для обработки кодов ошибок состоит в том, чтобы возвращать отрицательную константу ошибки, что-то вроде
-ENOMEM
. Ноль или положительное число указывает на успех. Это используется во всем ядре.Если вы определили новую точку входа sycall
static asmlinkage long my_new_syscall (int param) {...}
, ей просто нужно вернуть-ENOMEM
(или что-то подобное). Если вы вызвали системный вызов с помощью libcsyscall(nr, param)
, тогда по ошибке он вернет -1 иENOMEM
(в положительном) будет вerrno
.Существует множество кодов ошибок, определенных в
include/asm-generic/{errno,errno-base}.h
, которые можно использовать (например,ENOMEM
). Если ни один из них не соответствует вашей цели, вы можете добавить свой собственный номер ошибки к этим файлам, но имейте в виду, что вам также потребуется изменить заголовки ядра, видимые в пользовательском пространстве, чтобы показать тот же номер, поэтому будет сложнее настроить систему для использования ваших изменений. Не делай этого, если тебе не нужно.
Я обнаружил, что могу просто вернуть номер кода, который я хочу, чтобы errno был установлен, вернув сам код в sycall. Все остальное ядро linux делает автоматически.
У вас есть два варианта: использовать существующие коды ошибок или определить свой собственный. В большинстве случаев я обнаружил, что существующие коды ошибок достаточно близки к тому значению, которое я хочу.
Основные номера ошибок находятся в:
include/asm-generic/errno-base.h
И
include/asm-generic/errno.h
.В системном вызове вы можете вернуть пользователю отрицательное значение существующего значения errno. Например:
return -ENOMEM;