Postfix3.3.1
unix_connect.c
[詳解]
1 /*++
2 /* NAME
3 /* unix_connect 3
4 /* SUMMARY
5 /* connect to UNIX-domain listener
6 /* SYNOPSIS
7 /* #include <connect.h>
8 /*
9 /* int unix_connect(addr, block_mode, timeout)
10 /* const char *addr;
11 /* int block_mode;
12 /* int timeout;
13 /* DESCRIPTION
14 /* unix_connect() connects to a listener in the UNIX domain at the
15 /* specified address, and returns the resulting file descriptor.
16 /*
17 /* Arguments:
18 /* .IP addr
19 /* Null-terminated string with connection destination.
20 /* .IP block_mode
21 /* Either NON_BLOCKING for a non-blocking socket, or BLOCKING for
22 /* blocking mode.
23 /* .IP timeout
24 /* Bounds the number of seconds that the operation may take. Specify
25 /* a value <= 0 to disable the time limit.
26 /* DIAGNOSTICS
27 /* The result is -1 in case the connection could not be made.
28 /* Fatal errors: other system call failures.
29 /* LICENSE
30 /* .ad
31 /* .fi
32 /* The Secure Mailer license must be distributed with this software.
33 /* AUTHOR(S)
34 /* Wietse Venema
35 /* IBM T.J. Watson Research
36 /* P.O. Box 704
37 /* Yorktown Heights, NY 10598, USA
38 /*--*/
39 
40 /* System interfaces. */
41 
42 #include <sys_defs.h>
43 #include <sys/socket.h>
44 #include <sys/un.h>
45 #include <string.h>
46 #include <unistd.h>
47 #include <errno.h>
48 
49 /* Utility library. */
50 
51 #include "msg.h"
52 #include "iostuff.h"
53 #include "sane_connect.h"
54 #include "connect.h"
55 #include "timed_connect.h"
56 
57 /* unix_connect - connect to UNIX-domain listener */
58 
59 int unix_connect(const char *addr, int block_mode, int timeout)
60 {
61 #undef sun
62  struct sockaddr_un sun;
63  ssize_t len = strlen(addr);
64  int sock;
65 
66  /*
67  * Translate address information to internal form.
68  */
69  if (len >= sizeof(sun.sun_path))
70  msg_fatal("unix-domain name too long: %s", addr);
71  memset((void *) &sun, 0, sizeof(sun));
72  sun.sun_family = AF_UNIX;
73 #ifdef HAS_SUN_LEN
74  sun.sun_len = len + 1;
75 #endif
76  memcpy(sun.sun_path, addr, len + 1);
77 
78  /*
79  * Create a client socket.
80  */
81  if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
82  return (-1);
83 
84  /*
85  * Timed connect.
86  */
87  if (timeout > 0) {
89  if (timed_connect(sock, (struct sockaddr *) &sun, sizeof(sun), timeout) < 0) {
90  close(sock);
91  return (-1);
92  }
93  if (block_mode != NON_BLOCKING)
94  non_blocking(sock, block_mode);
95  return (sock);
96  }
97 
98  /*
99  * Maybe block until connected.
100  */
101  else {
102  non_blocking(sock, block_mode);
103  if (sane_connect(sock, (struct sockaddr *) &sun, sizeof(sun)) < 0
104  && errno != EINPROGRESS) {
105  close(sock);
106  return (-1);
107  }
108  return (sock);
109  }
110 }
int sane_connect(int sock, struct sockaddr *sa, SOCKADDR_SIZE len)
Definition: sane_connect.c:44
int unix_connect(const char *addr, int block_mode, int timeout)
Definition: unix_connect.c:59
int timed_connect(int sock, struct sockaddr *sa, int len, int timeout)
Definition: timed_connect.c:67
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
#define NON_BLOCKING
Definition: iostuff.h:49
int non_blocking(int, int)
Definition: non_blocking.c:55