Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
шпора UNIX.doc
Скачиваний:
29
Добавлен:
15.06.2014
Размер:
530.43 Кб
Скачать

Обработка ошибок

external int errno;

#include <string.h>

char *strerror (int enum);

#include <errno.h>

#include <stdio.h>

void perror (char *s);

main (int argc, char *argv[ ])

{ fprintf(stderr, “ENOMEM:%s\n”, strerror (ENOMEM));

errno = ENOEXEC;

perror (argv[0]); }

Обработке ошибок уделяется большое значение в UNIX, так как написание надежных и устойчивых программ, особенно для многопользовательских систем, является неотъемлемым процессом.

Обычно в случае возникновения ошибки системные вызовы возвращают –1 и устанавливают значение переменной errno, указывающее возникновение ошибки. Библиотечные функции как правило значение errno не устанавливают, а код возврата различен для различных функций. Переменная errno не обнуляется следующим нормально завершившимся системным вызовом, значит эту переменную следует анализировать сразу же после системного вызова, который завершился с ошибкой.

Имеются также две функции, помогающие сообщить причину ошибочной ситуации.

Функция strerror принимает в качестве аргумента номер ошибки и возвращает указатель на строку, содержащую сообщение о причине ошибочной ситуации.

Функция perror выводит в стандартный поток сообщений об ошибках информацию об ошибочной ситуации, основываясь на значении переменной errno. Строка s, передаваемая функции в качестве аргумента, предваряет сообщение об ошибке и может содержать дополнительную информацию, например название функции, в которой произошла ошибка.

Имеется условное обозначение большого числа ошибочных ситуаций, при которых они могут обнаруживаться и обрабатываться.

Заголовки в программах

Использование системных функций требует включения в текст программы файлов заголовков, содержащих определение функций, типы аргументов и возвращаемые значения.

Файлы заголовков включаются в программу с помощью директивы include.

Ограничения для процессов

Так как ОС UNIX является многозадачной системой, то в ходе работы несколько процессов могут конкурировать между собой за доступ к различным ресурсам. Для справедливого распределения ресурсов (память, дисковое пространство) каждому из процессов устанавливается индивидуальный набор ограничений.

Для получения информации о текущих ограничениях используются системные вызовы:

#include <sys/times.h>

#include <sys/resource.h>

int getrlimit (int resource, struct rlimit *rlp);

int setrlimit (int resource, struct rlimit *rlp);

struct rlimit

{ rlim_t rlim_cur;

rlim_t rlim_max; }

Параметр resource определяет вид ресурса, для которого нужно узнать или изменить ограничения. Параметр rlim_cur определяет изменяемое ограничение, т.е. текущее ограничение процесса на данный ресурс. Параметр rlim_max определяет жесткое ограничение, т.е. максимально возможный значение для данного ресурса.

Любой процесс может изменить текущее значение ограничения ресурса до максимально возможного значения. Жесткое ограничение может быть изменено в сторону увеличения только процессом с привилегиями супер-пользователя. Обычные процессы могут только уменьшать его. Обычно ограничения устанавливаются при инициализации системы и затем наследуются порожденными процессами, хотя они могут изменяться и потом. Максимально возможный предел потребления ресурса может иметь значение, определяемое физическим ограничением системы. В этом случае в поле rlim_max должно быть установлено значение RLIM_INFINITY.

В системе определены следующие ограничения:

  • RLIMIT_CORE  максимальный размер создаваемого файла core, содержащего в памяти образ процесса. Если значение установлен в 0, то файл создаваться не будет.

  • RLIMIT_CPU  максимальное время использования процессора в секундах. При превышении промежутка времени процессу посылается сигнал SIGXCPU.

  • RLIMIT_DATA  максимальный размер сегмента данных процесса в байтах. При достижении этого предела последующие вызовы функций распределения памяти завершаются ошибкой ENOMEM.

  • RLIMIT_FSIZE  максимальный размер файла, который может создать процесс. Если установить в 0, то процесс не может создавать файлы. При достижении файлом заданного предела посылается сигнал SIGXFSZ.

  • RLIMIT_NOFILE  максимальное количество назначенных файловых дескрипторов процесса (т.е. максимальное число файлов, которые могут быть открыты процессом одновременно). Если процесс попытается получить больше дескрипторов, чем задано, то ему возвращается ошибка EMFILE.

  • RLIMIT_STACK  максимальный размер стека процесса. При попытке выхода за предел процессу отправляется сигнал SIGSEGV.

  • RLIMIT_VMEM  максимальный размер отображаемой памяти процесса в байтах. При превышении этого предела, использование функций распределения памяти возвращают ошибку ENOMEM.

  • RLIMIT_NPROC  максимальное число процессов с одним реальным UID. Если достигнут предел, то вызов fork завершится с ошибкой EAGAIN.

  • RLIMIT_RSS  максимальный размер в байтах резидентной части процесса. Определяет максимальный размер выделяемый процессу физической памяти. Если система ощущает нехватку оперативной памяти, то она освободит память за счет процессов превышавших свой ресурс.

  • RLIMIT_MEMLOCK  максимальный размер в байтах физической памяти, которую процесс может заблокировать с помощью системного вызова mlock. При превышении размера mlock завершается с ошибкой EAGAIN.

#include <stdio.h>

#include <sys/time.h>

#include <sys/resource.h>

void disp_limit(int resource, char *rname)

{ struct rlimit rlm;

getrlimit(resource, &rlm);

printf("%-13s", rname);

if (rlm.rlim_cur == RLIM_INFINITY) printf("INFINITY\n");

else printf("\n%10ld ", rlm.rlim_cur);

if (rlm.rlim_max == RLIM_INFINITY) printf("INFINITY\n");

else printf("\n%10ld ", rlm.rlim_max); }

main(void)

{ disp_limit(RLIMIT_NOFILE,"RLIMIT_CORE");

disp_limit(RLIMIT_NOFILE,"RLIMIT_FSIZE"); }