Пример
Пример
В качестве примера передачи идентифицирующих данных мы изменим наш потоковый доменный сервер Unix, так чтобы он запрашивал идентифицирующие данные клиента. В листинге 15.12 показана новая функция, read_cred, аналогичная функции read, но возвращающая также структуру fcred, содержащую идентифицирующие данные отправителя.
Листинг 15.12. Функция read_cred: чтение и возвращение идентифицирующих данных отправителя
//unixdomain/readcred.c
1 #include "unp.h"
2 #define CONTROL_LEN (sizeof(struct cmsghdr) + sizeof(struct cmsgcred))
3 ssize_t
4 read_cred(int fd, void *ptr, size_t nbytes, struct cmsgcred *cmsgcredptr)
5 {
6 struct msghdr msg;
7 struct iovec iov[1];
8 char control[CONTROL_LEN];
9 int n;
10 msg.msg_name = NULL;
11 msg.msg_namelen = 0;
12 iov[0].iov_base = ptr;
13 iov[0].iov_len = nbytes;
14 msg.msg_iov = iov;
15 msg.msg_iovlen = 1;
16 msg.msg_control = control;
17 msg.msg_controllen = sizeof(control);
18 msg.msg_flags = 0;
19 if ((n = recvmsg(fd, &msg, 0)) < 0)
20 return(n);
21 cmsgcredptr->cmcred_ngroups = 0; /* идентифицирующие данные не получены */
22 if (cmsgcredptr && msg.msg_controllen > 0) {
23 struct cmsghdr *cmptr = (struct cmsghdr*)control;
24 if (cmptr->cmsg_len < CONTROL_LEN)
25 err_quit("control length = %d", cmptr->cmsg_len);
26 if (cmptr->cmsg_level != SOL_SOCKET)
27 err_quit("control level != SOL_SOCKET");
28 if (cmptr->cmsg_type != SCM_CREDS)
29 err_quit("control type != SCM_CREDS");
30 memcpy(cmsgcredptr, CMSG_DATA(cmptr), sizeof(struct cmsgcred));
31 }
32 return(n);
33 }
3-4 Первые три аргумента идентичны аргументам функции read, а четвертый аргумент — это указатель на структуру cmsgcred, которая будет заполнена.
22-31 Если данные были переданы, проверяются длина, уровень и тип вспомогательных данных, и результирующая структура копируется обратно вызывающему процессу. Если никаких идентифицирующих данных не было передано, мы обнуляем структуру. Поскольку число групп (cmcred_ngroups) всегда равно 1 или больше, нулевое значение указывает вызывающему процессу, что ядро не возвратило никаких идентифицирующих данных.
Функция main для нашего эхо-сервера (см. листинг 15.3) остается неизменной. В листинге 15.13 показана новая версия функции str_echo, полученная путем модификации листинга 5.2. Эта функция вызывается дочерним процессом после того, как родительский процесс принял новое клиентское соединение и вызвал функцию fork.
Листинг 15.13. Функция str_echo, запрашивающая идентифицирующие данные клиента
//unixdomain/strecho.c
1 #include "unp.h"
2 ssize_t read_cred(int, void*, size_t, struct cmsgcred*);
3 void
4 str_echo(int sockfd)
5 {
6 ssize_t n;
7 int i;
8 char buf[MAXLINE];
9 struct cmsgcred cred;
10 again:
11 while ((n = read_cred(sockfd, buf, MAXLINE, &cred)) > 0) {
12 if (cred.cmcred_ngroups == 0) {
13 printf("(no credentials returned) ");
14 } else {
15 printf("PID of sender = %d ", cred.cmcred_pid);
16 printf("real user ID = %d ", cred.cmcred_uid);
17 printf("real group ID = %d ", cred.cmcred_gid);
18 printf("effective user ID = %d ", cred.cmcred_euid);
19 printf("%d groups:", cred.cmcred_ngroups - 1);
20 for (i = 1; i < cred.cmcred_ngroups; i++)
21 printf(" %d", cred.cmcred_groups[i]);
22 printf(" ");
23 }
24 Writen(sockfd, buf, n);
25 }
26 if (n < 0 && errno == EINTR)
27 goto again;
28 else if (n < 0)
29 err_sys("str_echo: read error");
30 }
11-23 Если идентифицирующие данные возвращаются, они выводятся.
24-25 Оставшаяся часть цикла не меняется. Этот код считывает строки от клиента и затем отправляет их обратно клиенту.
Наш клиент, представленный в листинге 15.4, остается практически неизменным. Мы добавляем передачу пустой структуры cmsgcred при вызове sendmsg, которая заполняется ядром.
Перед запуском клиента определим свои личные данные командой id:
freebsd % id
uid=1007(andy) gid=1007(andy) groups=1007(andy), 0(wheel)
Если мы запустим сервер в одном окне, а клиент в другом, то для сервера после однократного выполнения клиента получим представленный ниже вывод.
freebsd % unixstrserv02
PID of sender = 26881
real user ID = 1007
real group ID = 1007
effective user ID = 1007
2 groups: 1007 0
Информация выводится только после отправки клиентом данных серверу. Мы видим, что сведения соответствуют тем, которые были получены командой id.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
25.5. Пример
25.5. Пример Для закрепления материала этой главы ниже приводится пример приложения, в котором задействовано большинство функциональных возможностей qdbm. Подразумевается, что в результате выполнения этого приложения будет создана простая база данных телефонных номеров,
27.1.1. Пример
27.1.1. Пример В главе 8 был представлен пример использования обычной разделяемой библиотеки. Библиотеку libhello.so, которую нам удалось создать, можно загружать во время выполнения. Программа loadhello загружает libhello.so динамически и вызывает функцию print_hello, которая находится в
Пример
Пример В листинге 11.1[1] показана простая программа, вызывающая функцию gethostbyname для любого числа аргументов командной строки и выводящая всю возвращаемую информацию.Листинг 11.1. Вызов функции и вывод возвращаемой информации//names/hostent.c 1 #include "unp.h" 2 int 3 main(int argc, char **argv) 4 { 5 char
Пример
Пример Сначала приведем пример с Ipv4:freebsd % traceroute www.unpbook.comtraceroute to www.unpbook.com (206.168.112.219): 30 hops max. 24 data bytes1 12.106.32.1 (12.106.32.1) 0.799 ms 0.719 ms 0.540 ms2 12.124.47.113 (12.124.47.113) 1.758 ms 1.760 ms 1.839 ms3 gbr2-p27.sffca.ip.att.net (12.123.195.38) 2.744 ms 2.575 ms 2.648 ms4 tbr2-p012701.sffca.ip.att.net (12.122.11.85) 3.770 ms 3.689 ms 3.848 ms5 gbr3-p50.dvmco.ip.att.net (12.122.2.66) 26.202 ms 26.242 ms
Пример
Пример Сначала мы запустим нашу программу с аргументом командной строки -0 и убедимся, что сервер имен отвечает на приходящие дейтаграммы, не содержащие контрольной суммы. Мы также задаем флаг -v.macosx # udpcksum -i en1 -0 -v bridget.rudoff.com domaindevice = en1local net = 172.24.37.64. netmask = 255.255.255.224cmd = udp and src host
9.4. Пример
9.4. Пример В архитектуре x86 есть инструкции, определяющие позицию старшего и младшего значащих битов в слове. Процессор выполняет эти инструкции очень быстро. С другой стороны, чтобы сделать то же самое на языке С, потребуется написать цикл с операциями побитового
Пример 10-27. Простой пример сравнения строк
Пример 10-27. Простой пример сравнения строк #!/bin/bash# match-string.sh: простое сравнение строкmatch_string (){ MATCH=0 NOMATCH=90 PARAMS=2 # Функция требует два входных аргумента. BAD_PARAMS=91 [ $# -eq $PARAMS ] || return $BAD_PARAMS case "$1" in "$2") return $MATCH;; * ) return $NOMATCH;; esac}a=oneb=twoc=threed=twomatch_string $a # неверное число
Пример 12-20. Пример форматирования списка файлов в каталоге
Пример 12-20. Пример форматирования списка файлов в каталоге #!/bin/bash# За основу сценария взят пример "man column".(printf "PERMISSIONS LINKS OWNER GROUP SIZE DATE TIME PROG-NAME " ; ls -l | sed 1d) | column -t# Команда "sed 1d" удаляет первую строку, выводимую командой ls,#+ (для локали "С" это строка: "total N",#+ где "N" -- общее
Пример 12-45. Пример работы с m4
Пример 12-45. Пример работы с m4 #!/bin/bash# m4.sh: Демонстрация некоторых возможносией макропроцессора m4# Строкиstring=abcdA01echo "len($string)" | m4 # 7echo "substr($string,4)" | m4 # A01echo "regexp($string,[0-1][0-1],&Z)" | m4 # 01Z# Арифметикаecho "incr(22)" | m4 # 23echo "eval(99 / 3)" | m4 #
Пример 24-2. Еще один пример проверки аргументов с помощью "И-списков"
Пример 24-2. Еще один пример проверки аргументов с помощью "И-списков" #!/bin/bashARGS=1 # Ожидаемое число аргументов.E_BADARGS=65 # Код завершения, если число аргументов меньше ожидаемого.test $# -ne $ARGS && echo "Порядок использования: `basename $0` $ARGS аргумент(а)(ов)" && exit $E_BADARGS# Если
Пример 25-8. Пример реализации алгоритма Решето Эратосфена
Пример 25-8. Пример реализации алгоритма Решето Эратосфена #!/bin/bash# sieve.sh# Решето Эратосфена# Очень старый алгоритм поиска простых чисел.# Этот сценарий выполняется во много раз медленнее# чем аналогичная программа на C.LOWER_LIMIT=1 # Начиная с 1.UPPER_LIMIT=1000 # До 1000.# (Вы можете
Пример
Пример В примере создаются два класса обработчик и инициатор события, устанавливается связь между ними и иллюстрируется обработка события в нескольких объектах одновременно:#include "stdafx.h" #include "sigslot.h"struct EventRaiser { // источник события signal<const char*> event; // const char* – тип аргумента.