mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 07:22:34 +00:00
97 lines
2.9 KiB
C
97 lines
2.9 KiB
C
/* 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-socket.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_socket_pf(opts, &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 */
|