1 /*++
2 /* NAME
3 /* stream_connect 3
4 /* SUMMARY
5 /* connect to stream listener
6 /* SYNOPSIS
7 /* #include <connect.h>
8 /*
9 /* int stream_connect(path, block_mode, timeout)
10 /* const char *path;
11 /* int block_mode;
12 /* int timeout;
13 /* DESCRIPTION
14 /* stream_connect() connects to a stream listener for the specified
15 /* pathname, and returns the resulting file descriptor.
16 /*
17 /* Arguments:
18 /* .IP path
19 /* Null-terminated string with listener endpoint name.
20 /* .IP block_mode
21 /* Either NON_BLOCKING for a non-blocking stream, or BLOCKING for
22 /* blocking mode. However, a stream connection succeeds or fails
23 /* immediately.
24 /* .IP timeout
25 /* This argument is ignored; it is present for compatibility with
26 /* other interfaces. Stream connections succeed or fail immediately.
27 /* DIAGNOSTICS
28 /* The result is -1 in case the connection could not be made.
29 /* Fatal errors: other system call failures.
30 /* LICENSE
31 /* .ad
32 /* .fi
33 /* The Secure Mailer license must be distributed with this software.
34 /* AUTHOR(S)
35 /* Wietse Venema
36 /* IBM T.J. Watson Research
37 /* P.O. Box 704
38 /* Yorktown Heights, NY 10598, USA
39 /*--*/
40
41 /* System library. */
42
43 #include <sys_defs.h>
44
45 #ifdef STREAM_CONNECTIONS
46
47 #include <sys/stat.h>
48 #include <unistd.h>
49 #include <fcntl.h>
50 #include <errno.h>
51 #include <stropts.h>
52
53 #endif
54
55 /* Utility library. */
56
57 #include <msg.h>
58 #include <connect.h>
59
60 /* stream_connect - connect to stream listener */
61
stream_connect(const char * path,int block_mode,int unused_timeout)62 int stream_connect(const char *path, int block_mode, int unused_timeout)
63 {
64 #ifdef STREAM_CONNECTIONS
65 const char *myname = "stream_connect";
66 int pair[2];
67 int fifo;
68
69 /*
70 * The requested file system object must exist, otherwise we can't reach
71 * the server.
72 */
73 if ((fifo = open(path, O_WRONLY | O_NONBLOCK, 0)) < 0)
74 return (-1);
75
76 /*
77 * This is for {unix,inet}_connect() compatibility.
78 */
79 if (block_mode == BLOCKING)
80 non_blocking(fifo, BLOCKING);
81
82 /*
83 * Create a pipe, and send one pipe end to the server.
84 */
85 if (pipe(pair) < 0)
86 msg_fatal("%s: pipe: %m", myname);
87 if (ioctl(fifo, I_SENDFD, pair[1]) < 0)
88 msg_fatal("%s: send file descriptor: %m", myname);
89 close(pair[1]);
90
91 /*
92 * This is for {unix,inet}_connect() compatibility.
93 */
94 if (block_mode == NON_BLOCKING)
95 non_blocking(pair[0], NON_BLOCKING);
96
97 /*
98 * Cleanup.
99 */
100 close(fifo);
101
102 /*
103 * Keep the other end of the pipe.
104 */
105 return (pair[0]);
106 #else
107 msg_fatal("stream connections are not implemented");
108 #endif
109 }
110