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