обладаете хоть каким-нибудь опытом программирования в Linux, то наверняка неоднократно получали это сообщение.
Если для процесса установлен лимит на размер файла дампа, равный 0 (рассматривался ранее в этой главе), то никакой дамп ядра не выгружается.
10.5. Простые дочерние процессы
Хотя функции fork(), exec() и wait() позволяют программам в полной мере использовать модель процессов Linux, многим приложениям не нужен такой контроль дочерних процессов. Существуют две библиотечных функции, которые упрощают создание дочерних процессов: system() и popen().
10.5.1. Запуск и ожидание с помощью system()
Программам часто требуется запускать другие программы и ожидать их завершения, прежде чем продолжать свою работу. Функция system() позволяет это делать достаточно просто.
int system (const char* cmd);
system() порождает дочерний процесс, который выполняет exec() для /bin/sh, который, в свою очередь, запускает cmd. Исходный процесс ожидает завершения дочерней оболочки и возвращает тот же код, что wait()[28]. Если вам не нужно оставлять в памяти оболочку (что случается редко), cmd должна включать предшествующее слово 'exec', которое заставляет оболочку вызывать exec() вместо запуска cmd как подпроцесса.
Поскольку cmd запускается из оболочки /bin/sh, то здесь применимы все обычные правила расширения команд. Ниже показан пример вызова system(), который отображает исходные тексты С из текущего каталога.
#include <stdlib.h>
#include <sys/wait.h>
int main() {
int result;
result = system('exec ls *.c');
if (!WIFEXITED(result))
printf('(аварийный выход)
');
exit(0);
}
Команда system() должна применяться с большой осторожностью в программах, которые запускаются со специальными полномочиями. Поскольку системная оболочка предоставляет множество мощных средств и сильно зависит от переменных окружения, system() является уязвимым местом в плане безопасности, которым могут воспользоваться злоумышленники для проникновения в систему. Однако до тех пор, пока приложение не является демоном или программой setuid/setgid, вызов system() совершенно безопасен.
10.5.2. Чтение и запись из процесса
Хотя system() отображает результат работы команды на устройство стандартного вывода и позволяет дочерним программам читать стандартный ввод, это не всегда идеально. Часто процесс желает читать вывод другого процесса либо отправлять текст на стандартный ввод. popen() облегчает процессам решение этой задачи[29].
FILE * popen(const char *cmd, const char *mode);
cmd выполняется через оболочку, как и в system(). Параметр mode должен быть 'r', если родительский процесс желает читать командный вывод, и 'w' — для записи в стандартный ввод дочернего процесса. Следует отметить, что с помощью popen() делать одновременно чтение и запись нельзя.
Два процесса, которые читают и пишут друг в друга, достаточно сложны[30] и выходят за рамки возможностей popen()[31].
popen() возвращает FILE* (как это определено в стандартной библиотеке ввода-вывода ANSI/ISO), который может быть прочитан и записан подобно любому другому потоку stdio[32], либо NULL, если операция не удается. Когда завершается родительский процесс, он может воспользоваться pclose() для закрытия потока и прерывания дочернего процесса, если он все еще выполняется. Подобно system(), pclose() возвращает состояние дочернего процесса из wait4().
int pclose(FILE *stream);
Ниже приведен пример простой программы-калькулятора, которая использует программу bc для выполнения всей реальной работы. Важно сбрасывать поток, полученный от popen(), после записи в него, чтобы предотвратить буферизацию stdio от задержки вывода (подробности о буферизации стандартных функций библиотеки stdio можно найти в [15]).
1: /*calc.c*/
2:
3: /* Это очень простой калькулятор, который использует внешнюю команду bc
4: для выполнения всей работы. Открывает канал к bc, читает команду,
5: передает ее bc и завершается. */
6: #include <stdio.h>
7: #include <sys/wait.h>
8: #include <unistd.h>
9:
10: int main(void) {
11: char buf[1024];
12: FILE *bc;
13: int result;
14:
15: /* открыть канал на bc и выйти в случае неудачи */
16: bc = popen('bc', 'w');
17: if (!bc) {
18: perror('popen');
19: return 1;
20: }
21:
