Postfix3.3.1
全て データ構造 ファイル 関数 変数 型定義 マクロ定義
stream_recv_fd.c
[詳解]
1 /*++
2 /* NAME
3 /* stream_recv_fd 3
4 /* SUMMARY
5 /* receive file descriptor
6 /* SYNOPSIS
7 /* #include <iostuff.h>
8 /*
9 /* int stream_recv_fd(fd)
10 /* int fd;
11 /* DESCRIPTION
12 /* stream_recv_fd() receives a file descriptor via the specified
13 /* stream. The result value is the received descriptor.
14 /*
15 /* Arguments:
16 /* .IP fd
17 /* File descriptor that connects the sending and receiving processes.
18 /* DIAGNOSTICS
19 /* stream_recv_fd() returns -1 upon failure.
20 /* LICENSE
21 /* .ad
22 /* .fi
23 /* The Secure Mailer license must be distributed with this software.
24 /* AUTHOR(S)
25 /* Wietse Venema
26 /* IBM T.J. Watson Research
27 /* P.O. Box 704
28 /* Yorktown Heights, NY 10598, USA
29 /*--*/
30 
31 /* System library. */
32 
33 #include <sys_defs.h> /* includes <sys/types.h> */
34 
35 #ifdef STREAM_CONNECTIONS
36 
37 #include <sys/stat.h>
38 #include <unistd.h>
39 #include <errno.h>
40 #include <stropts.h>
41 #include <fcntl.h>
42 
43 #endif
44 
45 /* Utility library. */
46 
47 #include <msg.h>
48 #include <iostuff.h>
49 
50 /* stream_recv_fd - receive file descriptor */
51 
52 int stream_recv_fd(int fd)
53 {
54 #ifdef STREAM_CONNECTIONS
55  struct strrecvfd fdinfo;
56 
57  /*
58  * This will return EAGAIN on a non-blocking stream when someone else
59  * snatched the connection from us.
60  */
61  if (ioctl(fd, I_RECVFD, &fdinfo) < 0)
62  return (-1);
63  return (fdinfo.fd);
64 #else
65  msg_fatal("stream connections are not implemented");
66 #endif
67 }
68 
69 #ifdef TEST
70 
71  /*
72  * Proof-of-concept program. Receive a descriptor (presumably from the
73  * stream_send_fd test program) and copy its content until EOF.
74  */
75 #include <unistd.h>
76 #include <string.h>
77 #include <stdlib.h>
78 #include <split_at.h>
79 #include <listen.h>
80 
81 int main(int argc, char **argv)
82 {
83  char *transport;
84  char *endpoint;
85  int listen_sock;
86  int client_sock;
87  int client_fd;
88  ssize_t read_count;
89  char buf[1024];
90 
91  if (argc != 2
92  || (endpoint = split_at(transport = argv[1], ':')) == 0
93  || *endpoint == 0 || *transport == 0)
94  msg_fatal("usage: %s transport:endpoint", argv[0]);
95 
96  if (strcmp(transport, "stream") == 0) {
97  listen_sock = stream_listen(endpoint, BLOCKING, 0);
98  } else {
99  msg_fatal("invalid transport name: %s", transport);
100  }
101  if (listen_sock < 0)
102  msg_fatal("listen %s:%s: %m", transport, endpoint);
103 
104  client_sock = stream_accept(listen_sock);
105  if (client_sock < 0)
106  msg_fatal("stream_accept: %m");
107 
108  while ((client_fd = stream_recv_fd(client_sock)) >= 0) {
109  msg_info("client_fd = %d", client_fd);
110  while ((read_count = read(client_fd, buf, sizeof(buf))) > 0)
111  write(1, buf, read_count);
112  if (read_count < 0)
113  msg_fatal("read: %m");
114  if (close(client_fd) != 0)
115  msg_fatal("close(%d): %m", client_fd);
116  }
117  exit(0);
118 }
119 
120 #endif
int stream_listen(const char *, int, int)
Definition: stream_listen.c:71
int main(int argc, char **argv)
Definition: anvil.c:1010
int stream_recv_fd(int fd)
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
char * split_at(char *string, int delimiter)
Definition: split_at.c:53
#define BLOCKING
Definition: iostuff.h:48
int stream_accept(int)
Definition: stream_listen.c:87
void msg_info(const char *fmt,...)
Definition: msg.c:199