c57a7841

Запуск новой программы


Если бы можно было выполнять только программу fork (или __clone), можно было бы только снова и снова создавать копии одного и того же процесса— система Linux могла бы запускать копии первого когда-либо созданного в ней процесса пользователя — init. Этот процесс полезен, но не настолько, желательно иметь возможность делать и что-нибудь еще.

После появления нового процесса он становится тем, что называется exec, (exec — это не одна функция, а скорее общий термин, относящийся к семейству функций, которые все по существу выполняют одно и то же, но принимают несколько различные аргументы.)

Таким образом, создание «действительно» нового процесса, который из родительской программы запускает образ другой программы, состоит из двух этапов: одного для fork и второго — для exec, приводя к следующей знакомой структуре кода С:

/* Возможность возникновения ошибки в следующих строках программы игнорируется. */ if (fork()) { /* Я - родительская программа; продолжаю обычную работу. */ } else { /* Я - дочерняя программа */ /* Становлюсь /some/other/program. */ execl("/some/other/program", "/some/other/program") }

(execl — одна из нескольких функций семейства exec.)

Основополагающей функцией ядра, реализующей все функции в семействе exec является do_execve, определенная в строках с по . Функция do_execve выполняет три задачи:

  • Считывает некоторую основную информацию из выполняемого файла в память. (do_execve перепоручает эту задачу функции prepare_binprm.)
  • Готовит новые аргументы и среду — т.е. то, что приложения С будут видеть как переменные argc, argv и envp.
  • Выделяет обработчик двоичных файлов, готовый анализировать исполняемый файл, и предоставляет ему выполнить остальную часть работы по изменению структур данных ядра.
  • Помня об этих задачах, давайте начнем подробное рассмотрение функции do_execve.



    Содержание раздела