| /* source: xio-socketpair.c */ |
| /* Copyright Gerhard Rieger and contributors (see file CHANGES) */ |
| /* Published under the GNU General Public License V.2, see file COPYING */ |
| |
| /* this file contains the source for opening addresses of socketpair type */ |
| |
| #include "xiosysincludes.h" |
| #include "xioopen.h" |
| |
| #include "xio-named.h" |
| |
| #include "xio-socketpair.h" |
| |
| |
| #if WITH_SOCKETPAIR |
| |
| static int xioopen_socketpair(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); |
| |
| const struct addrdesc xioaddr_socketpair = { "SOCKETPAIR", 3, xioopen_socketpair, GROUP_FD|GROUP_SOCKET, 0, 0, 0 HELP(":<filename>") }; |
| |
| |
| /* Open a socketpair */ |
| static int xioopen_socketpair( |
| int argc, |
| const char *argv[], |
| struct opt *opts, |
| int xioflags, |
| xiofile_t *xfd, |
| const struct addrdesc *addrdesc) |
| { |
| struct single *sfd = &xfd->stream; |
| struct opt *opts2; |
| int pf = PF_UNIX; |
| int protocol = 0; |
| int filedes[2]; |
| int numleft; |
| int result; |
| |
| if (argc != 1) { |
| xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); |
| return STAT_NORETRY; |
| } |
| |
| sfd->para.bipipe.socktype = SOCK_DGRAM; |
| if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; |
| applyopts(sfd, -1, opts, PH_INIT); |
| retropt_int(opts, OPT_PROTOCOL_FAMILY, &pf); |
| retropt_int(opts, OPT_SO_TYPE, &sfd->para.bipipe.socktype); |
| retropt_int(opts, OPT_SO_PROTOTYPE, &protocol); |
| |
| if (Socketpair(pf, sfd->para.bipipe.socktype, protocol, filedes) != 0) { |
| Error5("socketpair(%d, %d, %d, %p): %s", pf, sfd->para.bipipe.socktype, protocol, filedes, strerror(errno)); |
| return -1; |
| } |
| Info2("socketpair({%d,%d})", filedes[0], filedes[1]); |
| |
| sfd->tag = XIO_TAG_RDWR; |
| if (sfd->para.bipipe.socktype == SOCK_STREAM) { |
| sfd->dtype = XIOREAD_STREAM|XIOWRITE_PIPE; |
| } else { |
| sfd->dtype = XIOREAD_RECV|XIOREAD_RECV_NOCHECK|XIOWRITE_PIPE; |
| } |
| sfd->fd = filedes[0]; |
| sfd->para.bipipe.fdout = filedes[1]; |
| applyopts_cloexec(sfd->fd, opts); |
| applyopts_cloexec(sfd->para.bipipe.fdout, opts); |
| |
| /* one-time and input-direction options, no second application */ |
| retropt_bool(opts, OPT_IGNOREEOF, &sfd->ignoreeof); |
| |
| /* here we copy opts! */ |
| if ((opts2 = copyopts(opts, GROUP_SOCKET)) == NULL) { |
| return STAT_NORETRY; |
| } |
| |
| /* apply options to first FD */ |
| if ((result = applyopts(sfd, -1, opts, PH_ALL)) < 0) { |
| return result; |
| } |
| if ((result = applyopts_single(sfd, opts, PH_ALL)) < 0) { |
| return result; |
| } |
| |
| /* apply options to second FD */ |
| if (applyopts(sfd, sfd->para.bipipe.fdout, opts2, PH_ALL) < 0) |
| return -1; |
| |
| if ((numleft = leftopts(opts)) > 0) { |
| Error1("%d option(s) could not be used", numleft); |
| showleft(opts); |
| } |
| Notice("writing to and reading from unnamed socketpair"); |
| return 0; |
| } |
| |
| #endif /* WITH_SOCKETPAIR */ |