Чтение онлайн

ЖАНРЫ

Разработка приложений в среде Linux. Второе издание

Троан Эрик В.

Шрифт:

 16: #include <sys/socket.h>

 17: #include <sys/uio.h>

 18: #include <sys/un.h>

 19: #include <sys/wait.h>

 20: #include <unistd.h>

 21:

 22: #include "sockutil.h" /* простые служебные функции */

 23:

 24: /* Дочерний процесс. Он пересылает файловый дескриптор. */

 25: int childProcess(char * filename, int sock) {

 26: int fd;

 27: struct iovec vector; /*
некоторые данные для передачи fd в w/ */

 28: struct msghdr msg; /* полное сообщение */

 29: struct cmsghdr * cmsg; /* управляющее сообщение, которое */

 30: /* включает в себя fd */

 31:

 32: /* Открыть файл, дескриптор которого будет передан. */

 33: if ((fd = open(filename, O_RDONLY)) < 0) {

 34: perror("open");

 35: return 1;

 36: }

 37:

 38: /* Передать имя файла через сокет, включая завершающий

 39: символ '\0' */

 40: vector.iov_base = filename;

 41: vector.iov_len = strlen(filename) + 1;

 42:

 43: /* Соединить первую часть сообщения. Включить

 44: имя файла iovec */

 45: msg.msg_name = NULL;

 46: msg.msg_namelen = 0;

 47: msg.msg_iov = &vector;

 48: msg.msg_iovlen = 1;

 49:

 50: /* Теперь управляющее сообщение. Мы должны выделить участок памяти

 51: для файлового дескриптора. */

 52: cmsg = alloca(sizeof(struct cmsghdr) + sizeof(fd));

 53: cmsg->cmsg_len = sizeof(struct cmsghdr) + sizeof(fd);

 54: cmsg->cmsg_level = SOL_SOCKET;

 55: cmsg->cmsg_type = SCM_RIGHTS;

 56:

 57: /* Копировать файловый дескриптор в конец

 58: управляющего сообщения */

 59: memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));

 60:

 61: msg.msg_control = cmsg;

 62: msg.msg_controllen = cmsg->cmsg_len;

 63:

 64: if (sendmsg(sock, &msg, 0) != vector.iov_len)

 65: die("sendmsg");

 66:

 67: return 0;

 68: }

 69:

 70: /* Родительский процесс. Он получает файловый дескриптор. */

 71: int parentProcess(int sock) {

 72: char buf[80]; /* пространство
для передачи имени файла */

 73: struct iovec vector; /* имя файла от дочернего процесса */

 74: struct msghdr msg; /* полное сообщение */

 75: struct cmsghdr * cmsg; /* управляющее сообщение с fd */

 76: int fd;

 77:

 78: /* установка iovec для имени файла */

 79: vector.iov_base = buf;

 80: vector.iov_len = 80;

 81:

 82: /* сообщение, которое мы хотим получить */

 83:

 84: msg.msg_name = NULL;

 85: msg.msg_namelen = 0;

 86: msg.msg_iov = &vector;

 87: msg.msg_iovlen = 1;

 88:

 89: /* динамическое распределение (чтобы мы могли выделить участок

 90: памяти для файлового дескриптора) */

 91: cmsg = alloca(sizeof(struct cmsghdr) + sizeof(fd));

 92: cmsg->cmsg_len = sizeof(struct cmsghdr) + sizeof(fd);

 93: msg.msg_control = cmsg;

 94: msg.msg_controllen = cmsg->cmsg_len;

 95:

 96: if (!recvmsg(sock, &msg, 0))

 97: return 1;

 98:

 99: printf("получен файловый дескриптор для '%s'\n",

100: (char *) vector.iov_base);

101:

102: /* присвоение файлового дескриптора из управляющей структуры */

103: memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));

104:

105: copyData(fd, 1);

106:

107: return 0;

108: }

109:

110: int main(int argc, char ** argv) {

111: int socks[2];

112: int status;

113:

114: if (argc != 2) {

115: fprintf(stderr, "поддерживается только один аргумент\n");

116: return 1;

117: }

118:

119: /* Создание сокетов. Один служит для родительского процесса,

120: второй — для дочернего (мы можем поменять их местами,

121: если нужно). */

122: if (socketpair(PF_UNIX, SOCK_STREAM, 0, socks))

123: die("socketpair");

124:

125: if (!fork) {

126: /* дочерний процесс */

Поделиться с друзьями: