На Linux, /sbin/nologin
прибывает из проекта util-linux, в то время как /bin/false
часть GNU Coreutils. Они выполняют различные роли, и nologin имеет опцию печати сообщения для людей, у которых есть он как их оболочка, кто входит в систему. Команды Linux прибывают из BSD, где у них, кажется, есть долгая история того, чтобы быть отличающимся. FreeBSD false
просто возвраты 1, в то время как nologin
проверки для проверки это работает на TTY и отправляет сообщение в системный журнал во время попыток входа в систему. Версии Linux немного более сложны (false
делая все виды забавного материала с интернационализацией для вывода - справка, я принимаю), но по существу выполните тот же путь.
Системные вызовы не обрабатываются как вызовы регулярной функции. Это берет специальный код для создания перехода от пространства пользователя до пространства ядра, в основном немного кода встроенного ассемблерного кода введенный в программу на сайте вызова. Код стороны ядра, который "ловит" системный вызов, является также материалом низкого уровня, который Вы, вероятно, не должны понимать глубоко по крайней мере сначала.
В include/linux/syscalls.h
в соответствии с Вашим исходным каталогом ядра, Вы находите это:
asmlinkage long sys_mkdir(const char __user *pathname, int mode);
Затем в /usr/include/asm*/unistd.h
, Вы находите это:
#define __NR_mkdir 83
__SYSCALL(__NR_mkdir, sys_mkdir)
В этом коде говорится mkdir(2)
системный вызов № 83. То есть системные вызовы называет число, не адресом как с нормальным вызовом функции в рамках Вашей собственной программы или к функции в библиотеке, связанной с Вашей программой. Связующее звено встроенного ассемблерного кода кодирует, я упомянул выше использования это для создания перехода от пользователя к пространству ядра, беря параметры наряду с ним.
Другой бит доказательства, что вещи являются немного странными здесь, - то, что существует не всегда строгий список параметров для системных вызовов: open(2)
, например, может взять или 2 или 3 параметра. Это означает open(2)
перегружается, функция C++, не C, все же интерфейс syscall является C-compatible. (Это не то же самое как функция C varargs, которая позволяет единственной функции брать переменное количество аргументов.)
Для ответа на первый вопрос нет никакого единственного файла где mkdir()
существует. Linux поддерживает много различных файловых систем, и у каждого есть его собственная реализация "mkdir" операции. Уровень абстракции, который позволяет ядру скрыть все, что позади вызова единой системы называют VFS. Так, Вы, вероятно, хотите начать закапывать fs/namei.c
, с vfs_mkdir()
. Фактическая реализация кода изменения файловой системы низкого уровня в другом месте. Например, ext4 реализацию называют ext4_mkdir()
, определенный в fs/ext4/namei.c
.
Что касается Вашего второго вопроса, да существуют шаблоны ко всему этому, но ни одно правило. То, в чем Вы на самом деле нуждаетесь, является довольно широким пониманием того, как ядро работает для выяснения, где необходимо искать какой-то конкретный системный вызов. Не все системные вызовы включают VFS, таким образом, их цепочки вызовов стороны ядра выполняют не, все запускают fs/namei.c
. mmap(2)
, например, запускается в mm/mmap.c
, потому что это - часть управления памятью ("мм") подсистема ядра.
Я рекомендую получить копию "Понимания Ядра Linux" Bovet и Cesati.
Это, вероятно, не отвечает на Ваш вопрос непосредственно, но я нашел strace
быть действительно прохладным при попытке понять базовые системные вызовы, в действии, которые сделаны даже для самых простых команд оболочки. например.
strace -o trace.txt mkdir mynewdir
Системные вызовы команды mkdir mynewdir
будет выведен к trace.txt для Вашего удовольствия просмотра.
Хорошее место для чтения источника ядра Linux является перекрестной ссылкой Linux (LXR) ¹. Возврат поисков ввел соответствия (прототипы функций, объявления переменной, и т.д.) в дополнение к свободным текстовым результатам поиска, таким образом, это более удобно, чем простой grep (и быстрее также).
LXR не разворачивает определения препроцессора. Системным вызовам исказил их имя препроцессор повсеместно. Однако большинство (все?) системные вызовы определяются с одним из SYSCALL_DEFINEx
семейства макросов. С тех пор mkdir
берет два аргумента, поиск SYSCALL_DEFINE2(mkdir
приводит к объявлению mkdir
syscall:
SYSCALL_DEFINE2(mkdir, const char __user *, pathname, int, mode)
{
return sys_mkdirat(AT_FDCWD, pathname, mode);
}
хорошо, sys_mkdirat
средства это mkdirat
syscall, таким образом нажимая на него только приводит Вас к объявлению в include/linux/syscalls.h
, но определение чуть выше.
Основное задание mkdirat
должен звонить vfs_mkdir
(VFS является универсальным слоем файловой системы). Cliking на этом показывает два результата поиска: объявление в include/linux/fs.h
, и определение несколько строк выше. Основное задание vfs_mkdir
должен назвать определенную для файловой системы реализацию: dir->i_op->mkdir
. Чтобы найти, как это реализовано, необходимо обратиться к реализации отдельной файловой системы, и нет никакого твердого правила — это мог даже быть модуль вне дерева ядра.
¹ LXR является программой индексации. Существует несколько веб-сайтов, которые предоставляют интерфейс LXR с немного отличающимися наборами известных версий и немного отличающимися веб-интерфейсами. Они склонны приходить и уходить, поэтому если тот, к которому Вы привыкли, не доступен, сделайте веб-поиск “перекрестной ссылки Linux” для нахождения другого.
Системные вызовы обычно переносятся в SYSCALL_DEFINEx()
макрос, который является почему простое grep
не находит их:
fs/namei.c:SYSCALL_DEFINE2(mkdir, const char __user *, pathname, int, mode)
Заключительное имя функции после макроса расширено, заканчивает тем, что был sys_mkdir
. SYSCALL_DEFINEx()
макрос добавляет шаблонные вещи как трассировка кода, который должно иметь каждое syscall определение.
Примечание:.h файл не определяет функцию. Это объявляется в этом.h файлом и определяется (реализованное) в другом месте. Это позволяет компилятору включать информацию о подписи функции (прототип), чтобы позволить проверку типа аргументов и соответствовать типам возврата к любым контекстам вызова в Вашем коде.
В общем.h (заголовок) регистрируют в C, используются, чтобы объявить функции и определить макросы.
mkdir
в особенности системный вызов. Может быть GNU libc, обертка вокруг того системного вызова (почти наверняка, на самом деле). Истинная реализация ядра mkdir
может быть найден путем поиска источников ядра и системных вызовов в частности.
Обратите внимание, что также будет какая-то реализация кода создания каталога для каждой файловой системы. VFS (виртуальная файловая система), которую слой обеспечивает общему API, в который может звонить слой системного вызова. Каждая файловая система должна зарегистрировать функции для уровня VFS для вызова в. Это позволяет различным файловым системам реализовывать свою собственную семантику для того, как каталоги структурированы (например, если они хранятся с помощью своего рода плана хеширования сделать поиск определенных записей более эффективным). Я упоминаю это, потому что Вы, вероятно, споткнетесь за них файловая система определенные функции создания каталога при поиске исходного дерева ядра Linux.
Ни одна из реализаций, Вы нашли соответствия прототипом в sys/stat.h, Возможно, ищущем включать оператор с этим заголовочным файлом, не будет более успешной?
Вот пара действительно больших сообщений в блоге, описывающих различные методы для выслеживания исходного кода ядра низкого уровня.
Documentation
подкаталог исходного дерева для ядра я работаю с. – Warren Young 14.05.2013, 20:28...
в нем как любая функция varargs. Конечно, это реализовано на libc уровне. Это может передать или 0 или значение мусора к ядру ABI, когда третий параметр не используется. – Random832 19.01.2017, 18:48