Текст книги "Основы программирования в Linux"
Автор книги: Нейл Мэтью
Соавторы: Ричард Стоунс
Жанры:
Программирование
,сообщить о нарушении
Текущая страница: 16 (всего у книги 67 страниц)
Временные файлы
Зачастую программы нуждаются в возможности использования временного хранилища в виде файлов. В них могут храниться промежуточные результаты вычислений, или резервные копии файлов, сделанные перед выполнением критических операций. Например, приложение для работы с базой данных может применять временный файл при удалении записей. В файле собираются элементы базы данных, нуждающиеся в сохранении, и затем в конце процесса временный файл становится новой базой данных, а исходная база данных удаляется.
У столь популярных временных файлов есть скрытый недостаток. Вы должны следить за тем, чтобы приложения выбирали уникальное имя для временного файла. Если это условие не соблюдается, могут возникнуть проблемы. Поскольку ОС Linux – многозадачная система, другая программа может выбрать то же самое имя, и обе будут мешать друг другу.
Уникальное имя файла генерируется с помощью функции tmpnam
:
#include
char *tmpnam(char *s);
Функция tmpnam
возвращает допустимое имя файла, не совпадающее с именем любого из существующих файлов. Если строка s
не равна NULL
, в нее будет записано имя файла. Последующие вызовы функции tmpnam будут перезаписывать статическую память, используемую для возвращаемых значений, поэтому важно применять строковый параметр, если функция должна вызываться многократно. Длина строки полагается равной, как минимум, L_tmpnam
(обычно около 20) символам. Функция tmpnam
может вызываться в одной программе до TMP_MAX
(не менее нескольких тысяч) раз, и каждый раз она будет генерировать уникальное имя файла.
Если, временный файл предполагается использовать немедленно, вы можете одновременно назвать его и открыть с помощью функции tmpfile
. Это важно, т.к. другая программа может создать файл с именем таким же, как значение, возвращенное функцией tmpnam
. Функция tmpfile
устраняет эту проблему полностью.
#include
FILE* tmpfile(void);
Функция tmpfile возвращает указатель потока, ссылающийся на уникальный временный файл. Файл открыт для чтения и записи (с помощью fopen
с флагом w+
) и будет автоматически удален, когда закроются все ссылки на него.
В случае возникновения ошибки tmpfile
вернет указатель NULL
и задаст значение переменной errno
.
Давайте посмотрим эти две функции в действии:
#include
#include
int main() {
char tmpname[L_tmpnam];
char* filename;
FILE *tmpfp;
filename = tmpnam(tmpname);
printf(«Temporary file name is: %sn», filename);
tmpfp = tmpfile();
if (tmpfp) printf(«Opened a temporary file OKn»);
else perror(«tmpfile»);
exit(0);
}
Когда вы откомпилируете и выполните программу tmpnam.с, то увидите уникальное имя файла, сгенерированное функцией tmpnam
:
$ ./tmpnam
Temporary file name is: /tmp/file2S64zc
Opened a temporary file OK
Как это работает
Программа вызывает функцию tmpnam
для генерации уникального имени временного файла. Если вы хотите его использовать, нужно быстро его открыть, чтобы минимизировать риск того, что другая программа откроет файл с тем же именем. Вызов функции tmpfile
одновременно создает и открывает временный файл, тем самым устраняя этот риск. При компиляции программы, использующей функцию tmpnam
, компилятор GNU С может вывести предупреждение о применении этой функции.
В некоторых версиях UNIX предлагается другой способ генерации имен временных файлов – с помощью функций mktemp
и mkstemp
. Они поддерживаются и ОС Linux и аналогичны функции tmpnam
за исключением того, что вы должны задать шаблон имени временного файла, который предоставляет некоторые дополнительные возможности управления местом хранения и именем файла.
#include
char *mktemp(char *template);
int mkstemp(char *template);
Функция mktemp создает уникальное имя файла на основе заданного шаблона template
. Аргумент template
должен быть строкой с шестью завершающими символами Х
. mktemp
заменяет эти символы Х
уникальной комбинацией символов, допустимых в именах файлов. Она возвращает указатель на сгенерированную строку или NULL
при невозможности сформировать уникальное имя.
Функция mkstemp
аналогична функции tmpfile
: она создает и открывает временный файл. Имя файла генерируется так же, как в функции mktemp
, но возвращенный результат – открытый низкоуровневый дескриптор файла.
Примечание
В ваших собственных программах следует всегда применять функции «создать и открыть»
tmpfile
иmkstemp
вместо функцийtmpnam
иmktemp
.
Информация о пользователе
Все программы в ОС Linux за исключением программы init, запускаются другими программами или пользователями. В главе 11 вы узнаете больше о взаимодействии выполняющихся программ или процессов. Пользователи чаще всего запускают программы из командной оболочки, реагирующей на их команды. Вы видели, что в программе можно определить собственное окружение, просматривая переменные окружения и читая системные часы. Программа может также выяснить данные о пользователе, применяющем ее.
Когда пользователь регистрируется в системе Linux, у него или у нее есть имя пользователя и пароль. После того как эти данные проверены, пользователю предоставляется командная оболочка. В системе у пользователя также есть уникальный идентификатор пользователя, называемый UID (user identifier). Каждая программа, выполняемая Linux, запускается от имени пользователя и имеет связанный с ней UID.
Вы можете настроить выполнение программ так, как будто они запускаются другим пользователем. Если у программы есть свой набор прав доступа для UID, она будет выполняться от имени владельца исполняемого файла. Когда выполнена команда su, программа действует так, как будто она запущена суперпользователем. Затем она проверяет право доступа пользователя, изменяет UID на идентификатор назначенной учетной записи и запускает регистрационную командную оболочку данной учетной записи. Этот прием позволяет программе выполняться от имени другого пользователя и часто используется системными администраторами для выполнения задач технического обслуживания системы.
Поскольку UID – это ключевой параметр для идентификации пользователя, начнем с него.
У UID есть свои тип uid_t
, определенный в файле sys/types.h. Обычно это короткое целое (small integer). Одни идентификаторы пользователя заранее определены системой, другие создаются системным администратором, когда новые пользователи становятся известны системе. Как правило, идентификаторы пользователей имеют значения, большие 100.
#include
#include
uid_t getuid (void);
char *getlogin(void);
Функция getuid
возвращает UID, с которым связана программа. Обычно это UID пользователя, запустившего программу.
Функция getlogin
возвращает регистрационное имя, ассоциированное с текущим пользователем.
Системный файл /etc/passwd содержит базу данных, имеющую дело с учетными записями пользователей. Он состоит из строк по одной на каждого пользователя, в каждую строку включены имя пользователя, зашифрованный пароль, идентификатор пользователя (UID), идентификатор группы (GID), полное имя, исходный каталог и командная оболочка, запускаемая по умолчанию. Далее приведен пример такой строки:
neil:zBqxfqedfpk:500:100:Neil Matthew:/home/neil:/bin/bash
Если вы пишете программу, которая определяет UID пользователя, запустившего ее, то можете расширить ее возможности и заглянуть в файл passwd для выяснения регистрационного имени пользователя и его полного имени. Мы не рекомендуем делать это, потому что современные UNIX-подобные системы уходят от применения файлов учетных записей пользователей для повышения безопасности системы. Многие системы, включая Linux, имеют возможность использовать файлы теневых паролей (shadow password), совсем не содержащие пригодной информации о зашифрованных паролях (она часто хранится в файле /etc/shadow, которые обычные пользователи не могут читать). По этой причине определен ряд функций для предоставления эффективного программного интерфейса, позволяющего получать эту пользовательскую информацию.
#include
#include
struct passwd *getpwuid(uid_t uid);
struct passwd *getpwnam(const char *name);
Структура базы данных учетных записей пользователей passwd
определена в файле pwd.h и включает элементы, перечисленные в табл. 4.4.
Таблица 4.4
passwd | |
---|---|
char *pw_name | Регистрационное имя пользователя |
uid_t pw_uid | Номер UID |
gid_t pw_gid | Номер GID |
char *pw_dir | Исходный каталог пользователя |
char *pw_gecos | Полное имя пользователя |
char *pw_shell | Командная оболочка пользователя, запускаемая по умолчанию |
В некоторых системах UNIX может использоваться другое имя для поля с полным именем пользователя: в одних системах это pw_gecos
, как в ОС Linux, в других – pw_comment
. Это означает, что мы не можем рекомендовать его использование. Обе функции (и getpwuid
, и getpwnam
) возвращают указатель на структуру passwd
, соответствующую пользователю. Пользователь идентифицируется по UID в функции getpwuid
и по регистрационному имени в функции getpwnam
. В случае ошибки обе функции вернут пустой указатель и установят переменную errno
.
Выполните упражнение 4.11.
Упражнение 4.11. Информации о пользователе
В этом упражнении показана программа user.c, извлекающая некоторую информацию о пользователе из базы данных учетных записей.
#include
#include
#include
#include
#include
int main() {
uid_t uid;
gid_t gid;
struct passwd *pw;
uid = getuid();
gid = getgid();
printf(«User is %sn», getlogin());
printf(«User IDs: uid=%d, gid=%dn», uid, gid);
pw = getpwuid(uid);
printf(
«UID passwd entry:n name=%s, uid=%d, gid=%d, home=%s, shell=%sn»,
pw->pw_name, pw->pw_uid, pw->pw_gid, pw->pw_dir, pw->pw_shell);
pw = getpwnam(«root»);
printf(«root passwd entry:n»);
printf(«name=%s, uid=%d, gid=%d, home=%s, shell=%sn»,
pw->pw_name, pw->pw_uid, pw->pw_gid, pw->pw_dir, pw->pw_shell);
exit(0);
}
Программа предоставит следующий вывод, который может слегка отличаться в разных версиях Linux и UNIX:
$ ./user
User is neil
User IDs: uid=1000, gid=100
UID passwd entry:
name=neil, uid=1000, gid=100, home=/home/neil, shell=/bin/bash
root passwd entry:
name=root, uid=0, gid=0, home=/root, shell=/bin/bash
Как это работает
Эта программа вызывает функцию getuid
для получения UID текущего пользователя, Этот UID применяется в функции getpwuid
для получения подробной информации из файла учетных записей пользователей. В качестве альтернативы мы показываем, как для извлечения информации о пользователе можно задать в функции getpwnam
имя пользователя root
.
Примечание
В исходном коде Linux вы сможете найти в команде id
еще один пример-использования функции getuid
.
Для просмотра всех данных файла учетных записей пользователей можно воспользоваться функцией getpwent
. Она последовательно выбирает строки файла.
#include
#include
void endpwent(void);
struct passwd *getpwent(void);
void setpwent(void);
Функция getpwent
возвращает поочередно информацию о каждом пользователе. Когда не остается ни одного, она возвращает пустой указатель. Для прекращения обработки файла, когда просмотрено достаточно элементов, вы можете применить функцию endpwent
. Функция setpwent
переустанавливает позицию указателя в файле учетных записей пользователей для начала нового просмотра при следующем вызове функции getpwent
. Эти функции действуют так же, как функции просмотра каталога opendir
, readdir
и closedir
, обсуждавшиеся в главе 3.
Идентификаторы пользователя и группы (эффективный или действующий и реальный) можно получить с помощью других реже используемых функций:
#include
#include
uid_t geteuid(void);
gid_t getgid(void);
gid_t getegid(void);
int setuid(uid_t uid);
int setgid(gid_t gid);
Подробную информацию об идентификаторах группы и эффективных идентификаторах пользователей следует искать на страницах интерактивного справочного руководства системы, хотя, быть может, вы решите, что вам вообще не следует манипулировать ими.
Примечание
Только суперпользователь может вызывать функции
setuid
иsetgid
.
Информация о компьютере
Программа может установить некоторые подробные сведения о компьютере, на котором выполняется, так же, как она определяет информацию о пользователе. Подобную информацию предоставляет команда uname
, в программе на языке С можно использовать для получения этих данных одноименный системный вызов – прочтите о нем в разделе системных вызовов интерактивного справочного руководства (раздел 2) с помощью команды man 2 uname
.
Сведения о рабочем компьютере могут оказаться полезными в ряде ситуаций. Вы можете захотеть настроить поведение программы в зависимости от сетевого имени машины, на которой она выполняется, скажем, на студенческом компьютере или машине администратора. Для соблюдения лицензионных соглашений вам может потребоваться ограничить выполнение программы одной машиной. Все это означает, что вам нужен способ определения компьютера, на котором выполняется программа.
Если в системе установлены сетевые компоненты, вы очень легко можете получить сетевое имя компьютера с помощью функции gethostname
:
#include
int gethostname(char *name, size_t namelen);
Эта функция записывает сетевое имя машины в строку name
. Предполагается, что длина строки, как минимум, namelen
символов. Функция gethostname
возвращает 0 в случае успешного завершения и -1 в противном случае.
Более подробную информацию о рабочем компьютере можно получить с помощью системного вызова uname
.
#include
int uname(struct utsname *name);
Функция uname записывает информацию о компьютере в структуру, на которую указывает параметр name. Структура типа utsname, определенная в файле sys/utsname.h, обязательно должна включать элементы, перечисленные в табл. 4.5.
Таблица 4.5
utsname | |
---|---|
char sysname[] | Имя операционной системы |
char nodename[] | Имя компьютера |
char release[] | Номер выпуска (релиза) системы |
char version[] | Номер версии системы |
char machine[] | Аппаратный тип |
В случае успешного завершения функция uname
возвращает неотрицательное целое и в противном случае с установленной переменной errno
для обозначения любой возникшей ошибки.
Выполните упражнение 4.12.
Упражнение 4.12. Информации о компьютере
Далее приведена программа hostget.c, извлекающая некоторые сведения о рабочем компьютере.
#include
#include
#include
#include
int main() {
char computer[256];
struct utsname uts;
if (gethostname(computer, 255) != 0 || uname(&uts) < 0) {
fprintf(stderr, «Could not get host informationn»);
exit(1);
}
printf(«Computer host name is %sn», computer);
printf(«System is %s on %s hardwaren», uts.sysname, uts.machine);
printf(«Nodename is %sn», uts.nodename);
printf(«Version is %s, %sn», uts.release, uts.version);
exit(0);
}
Она отобразит следующие зависящие от ОС Linux данные. Если ваша машина включена в сеть, то вы увидите расширенное имя компьютера, включающее обозначение сети:
$ ./hostget
Computer host name is suse103
System is Linux on i686 hardware
Nodename is suse103
Version is 2.6.20.2-2-default, #1 SMP Fri Mar 9 21:54:10 UTC 2007
Как это работает
Эта программа вызывает функцию gethostname
для получения имени рабочего компьютера. В приведенном примере это имя – suse103
. Более подробную информацию об этом компьютере на базе Intel Pentium 4 с ОС Linux возвращает системный вызов uname
. Учтите, что формат возвращаемых строк зависит от реализации, например, строка с версией системы содержит дату компиляции ядра.
Примечание
Другой пример применения функции
uname
вы можете найти в исходном коде Linux для командыuname
, которая использует эту функцию.
Уникальный идентификатор каждого рабочего компьютера можно получить с помощью функции gethostid
.
#include
long gethostid(void);
Функция gethostid
предназначена для возврата уникального значения, характеризующего рабочий компьютер. Менеджеры, следящие за соблюдением лицензионных соглашений, применяют ее для того, чтобы обеспечить функционирование программного обеспечения только на машинах с действующими лицензиями. На рабочих станциях Sun она возвращает номер, установленный в постоянной памяти во время изготовления компьютера и, таким образом, уникальный для системного оборудования. Другие системы, например Linux, возвращают значение на базе интернет-адреса машины, обычно не слишком безопасного для проверки лицензионных прав.
Ведение системных журналов
Многие приложения нуждаются в регистрации своей деятельности. Системные программы очень часто выводят сообщения на консоль или записывают их в регистрационный системный журнал. В этих сообщениях могут регистрироваться ошибки, предупреждения или более общая информация о состоянии системы. Например, программа su может зафиксировать тот факт, что пользователь пытался получить привилегии супер пользователя и потерпел неудачу.
Очень часто зарегистрированные сообщения записываются в системные файлы в каталоге, предоставляемом для этой цели. Это может быть каталог /usr/admor/var/log. При типичной установке ОС Linux все системные сообщения содержатся в файле /var/log/messages, в файл /var/log/mail включены другие регистрируемые сообщения от почтовой системы, а в файле /var/log/debug могут храниться отладочные сообщения. Проверить конфигурацию своей системы можно в файле /etc/syslog.conf или /etc/syslog-ng/syslog-ng.conf в зависимости от версии Linux.
Далее приведены некоторые примеры зарегистрированных сообщений.
Mar 2 6 18:25:51 suse103 ifstatus: eth0 device: Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE] (rev 10)
Mar 26 18:25:51 suse103 ifstatus: eth0 configuration: eth-id-00:0c:29:0e:91:72
...
May 20 06:56:56 suse103 SuSEfirewall2: Setting up rules from /etc/sysconfig/SuSEfirewall2
...
May 20 06:56:57 suse103 SuSEfirewall2: batch committing
...
May 20 06:56:57 suse103 SuSEfirewall2: Firewall rules successfully set
...
Jun 9 09:11:14 suse103 su: (to root) neil on /dev/pts/18 09:50:35
В этом выводе показаны виды регистрируемых сообщений. Несколько первых отправлены непосредственно ядром Linux во время его загрузки и обнаружения установленного оборудования. Брандмауэр сообщает о своей перенастройке. И наконец, программа su
извещает о том, что доступ с учетной записью суперпользователя получен пользователем neil.
Примечание
Для просмотра регистрируемых сообщений вы можете запросить права суперпользователя.
Некоторые системы UNIX не предоставляют файлов с удобными для чтения сообщениями, но они снабжают администраторов средствами для чтения базы данных системных событий. См. подробности в системной документации.
Несмотря на то, что формат и хранение системных сообщений могут отличаться, метод формирования сообщений стандартный. В спецификации UNIX представлен доступный всем программам интерфейс формирования регистрируемых сообщений с помощью функции syslog
.
#include
void syslog(int priority, const char *message, arguments...);
Функция syslog посылает регистрируемое сообщение средству ведения системного журнала (logging facility). У каждого сообщения есть аргумент priority
, полученный поразрядной операцией OR
из степени важности сообщения (severity level) и типа программы, формирующей сообщение (facility value). Степень важности определяет необходимые действия, а тип программы фиксирует инициатора сообщения.
Типы программ (из файла syslog.h) включают константу LOG_USER
, применяемую для обозначения сообщения, пришедшего из приложения пользователя (по умолчанию), и константы LOG_LOCAL0
, LOG_LOCAL1
, ..., LOG_LOCAL7
, зарезервированные для локального администратора.
В табл. 4.6 перечислены степени важности сообщений в порядке убывания приоритета.
Таблица 4.6
LOG_EMERG | Кризисная ситуация |
LOG_ALERT | Проблема с высоким приоритетом, например, повреждение базы данных |
LOG_CRIT | Критическая ошибка, например, повреждение оборудования |
LOG_ERR | Ошибки |
LOG_WARNING | Предупреждение |
LOG_NOTICE | Особые обстоятельства, требующие повышенного внимания |
LOG_INFO | Информационные сообщения |
LOG_DEBUG | Отладочные сообщения |
В зависимости от настройки системы сообщения типа LOG_EMER
могут пересылаться всем пользователям системы, сообщения LOG_ALERT
могут отправляться по электронной почте администратору, сообщения LOG_DEBUG
могут игнорироваться, а сообщения других типов могут записываться в файл. Вы можете написать программу, которая применяет средство регистрации сообщений, просто вызывая функцию syslog
, когда вы хотите создать регистрируемое сообщение.
У сообщения, создаваемого syslog
, есть заголовок и тело сообщения. Заголовок создается из индикатора типа программы, формирующей сообщение, и даты и времени. Тело сообщения создается из параметра message
, передаваемого функции syslog
, который действует как строка format
функции printf
. Остальные аргументы syslog
используются в соответствии со спецификаторами преобразований в стиле функции printf
, заданными в строке message
. Дополнительно может применяться спецификатор %m
для включения строки сообщения об ошибке, ассоциированной с текущим значением переменной errno
. Эта возможность может оказаться полезной для регистрации сообщений об ошибках.
Выполните упражнение 4.13.
Упражнение 4.13. Применение функции syslog
В этой программе осуществляется попытка открыть несуществующий файл.
#include
#include
#include
int main() {
FILE *f;
f = fopen(«not_here», "r");
if (!f) syslog(LOG_ERR|LOG_USER, «oops – %mn»);
exit(0);
}
Когда вы откомпилируете и выполните программу syslog.с, то не увидите никакого вывода, но в конце файла /var/log/messages теперь содержится следующая строка:
Jun 9 09:24:50 suse103 syslog: oops – No such file or directory
Как это работает
В данной программе вы пытаетесь открыть файл, которого нет. Когда попытка заканчивается неудачно, вы вызываете функцию syslog
для записи случившегося в системный журнал.
Обратите внимание на то, что регистрируемое сообщение не указывает, какая программа вызвала средство регистрации; оно просто констатирует тот факт, что была вызвана функция syslog
с сообщением. Спецификатор преобразования %m
был заменен описанием ошибки, в данном случае сообщающим об отсутствии файла. Это гораздо полезнее, чем простой отчет, содержащий внутренний номер ошибки.
В файле syslog.h определены и другие функции, применяемые для изменения поведения средств ведения системных журналов.
К ним относятся следующие функции:
#include
void openlog(const char *ident, int logopt, int facility);
int setlogmask(int maskpri);
Вы можете изменить способ представления ваших регистрируемых сообщений, вызвав функцию openlog
. Это позволит задать строку ident
, которая будет добавляться к вашим регистрируемым сообщениям. Вы можете применять ее для индикации программы, создавшей сообщение. Параметр facility
записывает текущий принятый по умолчанию тип программы, формирующей сообщение, который будет использоваться в последующих вызовах syslog
. По умолчанию устанавливается значение LOG_USER
. Параметр logopt
настраивает поведение будущих вызовов функции syslog
. Он представляет собой результат поразрядной операции OR
нулевого или большего числа параметров, приведенных в табл. 4.7.
Таблица 4.7
logopt | |
---|---|
LOG_PID | Включает в сообщения идентификатор процесса, уникальный номер, выделяемый системой каждому процессу |
LOG_CONS | Посылает сообщения на консоль, если они не могут быть записаны |
LOG_ODELAY | Открывает средство регистрации сообщений при первом вызове функции syslog |
LOG_NDELAY | Открывает средство регистрации сообщений немедленно, не дожидаясь первого регистрируемого сообщения |
Функция openlog
выделит и откроет дескриптор файла, который будет применяться для записи в программе ведения системного журнала. Вы сможете закрыть его, вызвав функцию closelog
. Имейте в виду, что вам не нужно вызывать функцию openlog
перед вызовом syslog
, потому что последняя при необходимости самостоятельно откроет средство ведения системного журнала.
Вы можете управлять приоритетом регистрируемых вами сообщений с помощью установки маски регистрации, используя функцию setlogmask
. Все будущие вызовы syslog
с разными приоритетами, не заданными в маске регистрации, будут отброшены, таким образом, вы сможете, например, использовать маску для отключения сообщений типа LOG_DEBUG
без необходимости изменять тело программы.
Вы можете создать маску для регистрируемых сообщений, используя значение LOG_MASK(priority)
, создающее маску только для одного приоритета, или значение LOG_UPTO(priority)
, создающее маску для всех приоритетов вплоть до заданного.
Выполните упражнение 4.14.
Упражнение 4.14. Маска регистрации (logmask
)
В этом примере вы увидите logmask
в действии.
#include
#include
#include
#include
int main() {
int logmask;
openlog(«logmask», LOG_PID|LOG_CONS, LOG_USER);
syslog(LOG_INFO, «informative message, pid = %d», getpid());
syslog(LOG_DEBUG, «debug message, should appear»);
logmask = setlogmask(LOG_UPTO(LOG_NOTICE));
syslog(LOG_DEBUG, «debug message, should not appear»);
exit(0);
}
Программа logmask.c ничего не выводит, но в типичной системе Linux вы увидите в файле /var/log/messages, ближе к концу, следующую строку:
Jun 9 09:28:52 suse103 logmask[19339] : informative message, pid = 19339
Файл, настроенный на получение регистрируемых сообщений об отладке (в зависимости от настройки регистрации, это чаще всего файл /var/log/debug или иногда файл /var/log/messages), должен содержать следующую строку:
Jun 9 09:28:52 susel03 logmask[19339]: debug message, should appear
Как это работает
Программа инициализирует средство ведения системного журнала, названное logmask, и запрашивает включение идентификатора процесса в регистрируемые сообщения. Информирующее сообщение записывается в файл /var/log/messages, а отладочное сообщение – в файл /var/log/debug. Второе отладочное сообщение не появляется, потому что вы вызвали функцию setlogmask
с игнорированием всех сообщений с приоритетом ниже LOG_NOTICE
. (Учтите, что этот метод не работает в ранних вариантах ядра Linux.)
Если в установленную у вас систему не включена регистрация отладочных сообщений или она настроена иначе, отладочные сообщения могут не появляться. Для разблокирования всех отладочных сообщений и для получения подробностей настройки см. системную документацию, посвященную функции syslog
или syslog-ng
.
Программа logmask.c также использует функцию getpid
, которая, наряду с тесно связанной с ней функцией getppid
, определена следующим образом:
#include
#include
pid_t getpid(void);pid_t getppid(void);
Функции возвращают идентификаторы вызвавшего и родительского процессов. Дополнительную информацию об идентификаторах процессов (PID) см. в главе 11.