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