Postfix3.3.1
unix_listen.c
[詳解]
1 /*++
2 /* NAME
3 /* unix_listen 3
4 /* SUMMARY
5 /* start UNIX-domain listener
6 /* SYNOPSIS
7 /* #include <listen.h>
8 /*
9 /* int unix_listen(addr, backlog, block_mode)
10 /* const char *addr;
11 /* int backlog;
12 /* int block_mode;
13 /*
14 /* int unix_accept(fd)
15 /* int fd;
16 /* DESCRIPTION
17 /* The \fBunix_listen\fR() routine starts a listener in the UNIX domain
18 /* on the specified address, with the specified backlog, and returns
19 /* the resulting file descriptor.
20 /*
21 /* unix_accept() accepts a connection and sanitizes error results.
22 /*
23 /* Arguments:
24 /* .IP addr
25 /* Null-terminated string with connection destination.
26 /* .IP backlog
27 /* This argument is passed on to the \fIlisten(2)\fR routine.
28 /* .IP block_mode
29 /* Either NON_BLOCKING for a non-blocking socket, or BLOCKING for
30 /* blocking mode.
31 /* .IP fd
32 /* File descriptor returned by unix_listen().
33 /* DIAGNOSTICS
34 /* Fatal errors: unix_listen() aborts upon any system call failure.
35 /* unix_accept() leaves all error handling up to the caller.
36 /* LICENSE
37 /* .ad
38 /* .fi
39 /* The Secure Mailer license must be distributed with this software.
40 /* AUTHOR(S)
41 /* Wietse Venema
42 /* IBM T.J. Watson Research
43 /* P.O. Box 704
44 /* Yorktown Heights, NY 10598, USA
45 /*--*/
46 
47 /* System interfaces. */
48 
49 #include <sys_defs.h>
50 #include <sys/socket.h>
51 #include <sys/un.h>
52 #include <string.h>
53 #include <unistd.h>
54 #include <sys/stat.h>
55 #include <errno.h>
56 
57 /* Utility library. */
58 
59 #include "msg.h"
60 #include "iostuff.h"
61 #include "listen.h"
62 #include "sane_accept.h"
63 
64 /* unix_listen - create UNIX-domain listener */
65 
66 int unix_listen(const char *addr, int backlog, int block_mode)
67 {
68 #undef sun
69  struct sockaddr_un sun;
70  ssize_t len = strlen(addr);
71  int sock;
72 
73  /*
74  * Translate address information to internal form.
75  */
76  if (len >= sizeof(sun.sun_path))
77  msg_fatal("unix-domain name too long: %s", addr);
78  memset((void *) &sun, 0, sizeof(sun));
79  sun.sun_family = AF_UNIX;
80 #ifdef HAS_SUN_LEN
81  sun.sun_len = len + 1;
82 #endif
83  memcpy(sun.sun_path, addr, len + 1);
84 
85  /*
86  * Create a listener socket. Do whatever we can so we don't run into
87  * trouble when this process is restarted after crash.
88  */
89  if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
90  msg_fatal("socket: %m");
91  if (unlink(addr) < 0 && errno != ENOENT)
92  msg_fatal("remove %s: %m", addr);
93  if (bind(sock, (struct sockaddr *) &sun, sizeof(sun)) < 0)
94  msg_fatal("bind: %s: %m", addr);
95 #ifdef FCHMOD_UNIX_SOCKETS
96  if (fchmod(sock, 0666) < 0)
97  msg_fatal("fchmod socket %s: %m", addr);
98 #else
99  if (chmod(addr, 0666) < 0)
100  msg_fatal("chmod socket %s: %m", addr);
101 #endif
102  non_blocking(sock, block_mode);
103  if (listen(sock, backlog) < 0)
104  msg_fatal("listen: %m");
105  return (sock);
106 }
107 
108 /* unix_accept - accept connection */
109 
110 int unix_accept(int fd)
111 {
112  return (sane_accept(fd, (struct sockaddr *) 0, (SOCKADDR_SIZE *) 0));
113 }
int unix_listen(const char *addr, int backlog, int block_mode)
Definition: unix_listen.c:66
#define SOCKADDR_SIZE
Definition: sys_defs.h:1411
int sane_accept(int sock, struct sockaddr *sa, SOCKADDR_SIZE *len)
Definition: sane_accept.c:47
int unix_accept(int fd)
Definition: unix_listen.c:110
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
int non_blocking(int, int)
Definition: non_blocking.c:55