Книга: UNIX: взаимодействие процессов

Функция px_ipc_name

Функция px_ipc_name

Существует и другое решение упомянутой проблемы с переносимостью. Можно определить нашу собственную функцию px_ipc_name, которая добавляет требуемый каталог в качестве префикса к имени Posix IPC.

#include "unpipc.h"
char *px_ipc_name(const char *name);
/* Возвращает указатель при успешном завершении, NULL при возникновении ошибки */

ПРИМЕЧАНИЕ

Так выглядят листинги наших собственных функций, то есть функций, не являющихся стандартными системными. Обычно включается заголовочный файл unpipc.h (листинг B.1).

Аргумент пате (имя) не должен содержать слэшей. Тогда, например, при вызове px_ipc_name("test1") будет возвращен указатель на строку /test1 в Solaris 2.6 или на строку /tmp/test1 в Digital Unix 4.0B. Память для возвращаемой строки выделяется динамически и освобождается вызовом free. Можно установить произвольное значение переменной окружения PX_IPC_NAME, чтобы задать другой каталог по умолчанию.

В листинге 2.1[1] приведен наш вариант реализации этой функции.

ПРИМЕЧАНИЕ

Возможно, в этом листинге вы в первый раз встретитесь с функцией snprintf. Значительная часть существующих программ используют вместо нее функцию sprintf, однако последняя не производит проверки переполнения приемного буфера. В отличие от нее snprintf получает в качестве второго аргумента размер приемного буфера и впоследствии предотвращает его переполнение. Умышленное переполнение буфера программы, использующей sprintf, в течение многих лет использовалось хакерами для взлома систем.

Функция snprintf еще не является частью стандарта ANSI С, но планируется ее включение в обновленный стандарт, называющийся С9Х. Тем не менее многие производители включают ее в стандартную библиотеку С. Везде в тексте мы используем функцию snprintf в нашем собственном варианте, обеспечивающем вызов sprintf, если в системной библиотеке функция snprinft отсутствует. 

Листинг 2.1. Функция px_ipc_name в нашей реализации.

//lib/px_ipc_name.c
1  #include "unpipc.h"
2  char *
3  px_ipc_name(const char *name)
4  {
5   char *dir, *dst, *slash;
6   if ((dst = malloc(РАТН_МАХ)) == NULL)
7    return(NULL);
8   /* есть возможность задать другое имя каталога с помощью переменной окружения */
9   if ((dir = getenv("PX IPC_NAME")) == NULL) {
10 #ifdef POSIX_IPC_PREFIX
11   dir = POSIX_IPC_PREFIX; /* из "config.h" */
12 #else
13   dir = "/tmp/"; /* по умолчанию */
14 #endif
15  }
16  /* имя каталога должно заканчиваться символом '/' */
17  slash = (dir[strlen(dir) – 1] == '/') ? "" : "/";
18  snprintf(dst, PATH_MAX, "%s%s%s", dir, slash, name);
19  return(dst); /* для освобождения этого указателя можно вызвать free() */
20 }

Оглавление книги

Оглавление статьи/книги

Генерация: 1.088. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз