Главная страница Взаимодействие нетривиальных процессов 24 errjoitd. LOGJRR, fmt. ар); 25 va end(ap); 26 exit(l); 27 } 28 /* Фатальная ошибка при системном вызове. 29 * Вывод сообщения, сохранение дампа памяти, завершение работы. */ 30 void 31 err dump(const char *fnit, ...) 32 { 33 vajist ap; 34 va start(ap, fmt); 35 err doit(l, LOGJRR, fmt. ap): 36 va end(ap): 37 abortO; /* сохранение дампа и завершение */ 38 exit(l): /* досюда не должно дойти */ 39 } 40 /* Нефатальная ошибка не при системном вызове. 41 * Вывод сообщения и возврат, */ 42 void 43 err msgtconst char *ffflt, ...) 44 { 45 vajist ap; 46 va start(ap. fmt): 47 err doit(0, LOG INFO, fmt, ap): 48 va end(ap): 49 return; 50 } 51 /* Фатальная ошибка не при системном вызове. 52 * Вывод сообщения и возврат. */ 53 void 54 err quit(const char *fnit, ..,) 55 { 56 vajist ap; 57 va start(ap, fmt); 58 errjoit(0. LOGJRR, fmt, ap): 59 va end(ap); 60 exit(l): 61 } 62 /* Вывод сообщения и возврат. 63 * Вызывающий указывает errnoflag и level . */ 64 static void 65 err doit(int errnoflag, int level, const char *fmt. va list ap) 66 { 67 int errno save, n; 68 char buf[MAXLINE]: продолжение J>- Листинг В.З (продолжение) 69 errno save = еггпо: /* значение может понадобиться вызвавшему */ 70 fifdef HAVE VSNPRINTF 71 vsnprintftbuf. sizeof(buf), fmt. ap): /* защищенный вариант */ 72 #else 73 vsprintf(buf. fmt. ap): /* незащищенный вариант */ 74 #endif 75 n - strlen(buf): 76 if (errnoflag) 77 snprintf(buf+n. sizeofCbuf)-n, : s . strerror(errno save)): 78 strcattbuf, \n ); 79 if (daemon proc) { 80 syslogdevel. buf): 81 } else { 82 fflush(stdout): /* если stdout и stderr одинаковы */ 83 fputs(buf. stderr); 84 fflush(stderr); 85 } 86 return: 87 ) ПРИЛОЖЕНИЕ Г Решения некоторых упражнений Глава 1 1. в обоих процессах нужно лишь указать флаг 0 APPEND при вызове функции open или режим дополнения файла при вызове fopen. Ядро гарантирует, что данные будут дописываться в конец файла. Это самая простая форма синхронизации доступа к файлу. На с. 60-61 [21] об этом рассказывается более подробно. Синхронизация становится проблемой при обновлении имеющихся в файле данных, как это происходит в базах данных. 2. Обычно встречается что-нибудь вроде: #ifdef REENTRANT #define еггпо (* еггпо()) #e1se extern int еггпо: #endif Если определена константа REENTRANT, обращение к еггпо приводит к вызову функции еггпо, возвращающей адрес переменной еггпо вызвавшего потока. Эта переменная, скорее всего, хранится в области собственных данных этого потока (раздел 23.5 [24]). Если константа REENTRANT не определена, переменная еггпо является глобальной. Глава 2 1. Эти два бита могут менять действующий идентификатор пользователя и/или группы выполняющейся программы. Идентификаторы используются в разделе 2.4. 2. Сначала следует указать флаги 0 CREAT 0 EXCL, и если вызов окажется успешным, будет создан новый объект. Если вызов вернет ошибку EEXIST, объект уже существует и программа должна вызвать open еще раз, без флага 0 CREAT или 0 EXCL. Второй вызов должен оказаться успешным, но есть вероятность, что он вернет ошибку ENOENT, если какой-либо другой поток или процесс удалит объект в промежутке между этими двумя вызовами.
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |