Version 1.8.0.0
[socat.git] / xio-socketpair.c
blobf9b3977e8ab3c3d84f48750e8742bb814c29a1f0
1 /* source: xio-socketpair.c */
2 /* Copyright Gerhard Rieger and contributors (see file CHANGES) */
3 /* Published under the GNU General Public License V.2, see file COPYING */
5 /* this file contains the source for opening addresses of socketpair type */
7 #include "xiosysincludes.h"
8 #include "xioopen.h"
10 #include "xio-named.h"
12 #include "xio-socketpair.h"
15 #if WITH_SOCKETPAIR
17 static int xioopen_socketpair(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
19 const struct addrdesc xioaddr_socketpair = { "SOCKETPAIR", 3, xioopen_socketpair, GROUP_FD|GROUP_SOCKET, 0, 0, 0 HELP(":<filename>") };
22 /* Open a socketpair */
23 static int xioopen_socketpair(
24 int argc,
25 const char *argv[],
26 struct opt *opts,
27 int xioflags,
28 xiofile_t *xfd,
29 const struct addrdesc *addrdesc)
31 struct single *sfd = &xfd->stream;
32 struct opt *opts2;
33 int pf = PF_UNIX;
34 int protocol = 0;
35 int filedes[2];
36 int numleft;
37 int result;
39 if (argc != 1) {
40 xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
41 return STAT_NORETRY;
44 sfd->para.bipipe.socktype = SOCK_DGRAM;
45 if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
46 applyopts(sfd, -1, opts, PH_INIT);
47 retropt_int(opts, OPT_PROTOCOL_FAMILY, &pf);
48 retropt_int(opts, OPT_SO_TYPE, &sfd->para.bipipe.socktype);
49 retropt_int(opts, OPT_SO_PROTOTYPE, &protocol);
51 if (Socketpair(pf, sfd->para.bipipe.socktype, protocol, filedes) != 0) {
52 Error5("socketpair(%d, %d, %d, %p): %s", pf, sfd->para.bipipe.socktype, protocol, filedes, strerror(errno));
53 return -1;
55 Info2("socketpair({%d,%d})", filedes[0], filedes[1]);
57 sfd->tag = XIO_TAG_RDWR;
58 if (sfd->para.bipipe.socktype == SOCK_STREAM) {
59 sfd->dtype = XIOREAD_STREAM|XIOWRITE_PIPE;
60 } else {
61 sfd->dtype = XIOREAD_RECV|XIOREAD_RECV_NOCHECK|XIOWRITE_PIPE;
63 sfd->fd = filedes[0];
64 sfd->para.bipipe.fdout = filedes[1];
65 applyopts_cloexec(sfd->fd, opts);
66 applyopts_cloexec(sfd->para.bipipe.fdout, opts);
68 /* one-time and input-direction options, no second application */
69 retropt_bool(opts, OPT_IGNOREEOF, &sfd->ignoreeof);
71 /* here we copy opts! */
72 if ((opts2 = copyopts(opts, GROUP_SOCKET)) == NULL) {
73 return STAT_NORETRY;
76 /* apply options to first FD */
77 if ((result = applyopts(sfd, -1, opts, PH_ALL)) < 0) {
78 return result;
80 if ((result = applyopts_single(sfd, opts, PH_ALL)) < 0) {
81 return result;
84 /* apply options to second FD */
85 if (applyopts(sfd, sfd->para.bipipe.fdout, opts2, PH_ALL) < 0)
86 return -1;
88 if ((numleft = leftopts(opts)) > 0) {
89 Error1("%d option(s) could not be used", numleft);
90 showleft(opts);
92 Notice("writing to and reading from unnamed socketpair");
93 return 0;
96 #endif /* WITH_SOCKETPAIR */