Прототипы:
#include <unistd.h>
#include <stdlib.h>
void _exit(int exit_code);
void exit(int status);
int atexit(void(*func)(void));
Выполнение системного вызова _exit приводит к освобождению сегмента данных, сегмента стека и закрытию всех открытых дескрипторов файлов для процесса, который вызвал _exit;
Но запись в таблице процессов, в которой был зарегистрирован этот процесс, не удаляется, т.е. она ещё не может быть занята другим процессом. Процесс переходит в состояние “зомби”, т.к. его дальнейшее выполнение не планируется. Удалить запись может только родительский процесс с помощью вызова wait и waitpid.
Если процесс порождает сына и заканчивается раньше, чем процесс-сын, то системный процесс init становится управляющим для процесса-сына, и после его завершения удаляет запись о нём в таблице процессов.
Аргумент _exit - код завершения процесса, причём родителю передаются только 8 младших бит. Нулевое значение свидетельствует об успешном завершении, ненулевое - о завершении процесса с ошибкой или по причине какой-либо ситуации.
|
|
Библиотечная функция exit является надстройкой над системным вызовом _exit. Она дополнительно очищает буфер и закрывает все открытые потоки для вызывающего процесса. Затем она вызывает все функции, которые были зарегистрируемы с помощью функции atexit. После этого вызывается системный вызов _exit.
Помимо exit программа может завершать свою работу обычным образом, при этом компилятор сам подставляет _exit перед завершением.
Завершение работы программы может быть инициировано оператором возврата return. В этом случае компилятор так же автоматически подставляет _exit.
Хорошим стилем программирования считается явное использование функции _exit.
При завершении процесса-сына ядро ОС посылает специальный сигнал SIGCHLD процессу-предку. По умолчанию этот сигнал игнорируется, но в процессе можно написат функцию-обработчик данного сигнала.
Ошибки
Все системные вызовы в случае ошибок возвращают -1. Введена внешняя переменная extern errno, которая в этом случае содержит код ошибки. Она не обнуляется успешно завершенными вызовами.
Код | Значение |
EAGAIN | Ресурс временно недоступен (переполнена системная таблица) |
EBADF | Недопустимый дескриптор файла |
ECHILD | Нет доченрых процессов |
EEXIST | Файл уже существует |
EINVAL | Недопустимый аргумент |
EIO | Ошибка ввода-вывода |
EMFILE | Процессом открыто слишком много файлов |
ENFILE | Переполнение в таблице открытых файлов |
EINTR | Системный вызов прерван сигналом |
Прототипы:
include <string.h>
#include <errno.h>
#include <stdio.h>
char *strerror(int errnum);
void perror(const char *s);
Функция strerror принимает код ошибки и возвращает указатель на строку, в которой находится сообщение об ошибке.
|
|
Пример:
#include <errno.h>
#include <stdio.h>
main(int argc,char *argv[])
{
fpritf(stderr,”ENOMEM:%s\n”,strerror(ENOMEM);
errno=ENOEXEC;
perror(argv[0]);
}