mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 15:32:35 +00:00
Internal: Reworked xioopts
This commit is contained in:
parent
1c1a91027a
commit
5eebca3a5b
37 changed files with 1380 additions and 1199 deletions
5
test.sh
5
test.sh
|
@ -17093,11 +17093,12 @@ tf="$td/test$N.stdout"
|
||||||
te="$td/test$N.stderr"
|
te="$td/test$N.stderr"
|
||||||
tdiff="$td/test$N.diff"
|
tdiff="$td/test$N.diff"
|
||||||
da="test$N $(date) $RANDOM"
|
da="test$N $(date) $RANDOM"
|
||||||
CMD0="$TRACE $SOCAT $opts -T 1 PIPE EXEC:cat,setsid,sigint"
|
CMD0="$TRACE $SOCAT $opts -T 2 PIPE EXEC:\"$CAT\",pty,setsid,sigint"
|
||||||
printf "test $F_n $TEST... " $N
|
printf "test $F_n $TEST... " $N
|
||||||
$CMD0 >/dev/null 2>"${te}0" &
|
$CMD0 >/dev/null 2>"${te}0" &
|
||||||
pid0=$!
|
pid0=$!
|
||||||
relsleep 2
|
#echo "pid0=$pid0" >&2 #!!!
|
||||||
|
sleep 1
|
||||||
kill -INT $pid0
|
kill -INT $pid0
|
||||||
wait
|
wait
|
||||||
if grep -q " W waitpid..: child .* exited with status 130" "${te}0" ||
|
if grep -q " W waitpid..: child .* exited with status 130" "${te}0" ||
|
||||||
|
|
19
xio-creat.c
19
xio-creat.c
|
@ -37,7 +37,8 @@ static int _xioopen_creat(const char *path, int rw, struct opt *opts) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int xioopen_creat(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3) {
|
static int xioopen_creat(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int dummy1, int dummy2, int dummy3) {
|
||||||
|
struct single *sfd = &xxfd->stream;
|
||||||
const char *filename = argv[1];
|
const char *filename = argv[1];
|
||||||
int rw = (xioflags&XIO_ACCMODE);
|
int rw = (xioflags&XIO_ACCMODE);
|
||||||
bool exists;
|
bool exists;
|
||||||
|
@ -45,32 +46,32 @@ static int xioopen_creat(int argc, const char *argv[], struct opt *opts, int xio
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
/* remove old file, or set user/permissions on old file; parse options */
|
/* remove old file, or set user/permissions on old file; parse options */
|
||||||
if ((result = _xioopen_named_early(argc, argv, fd, groups, &exists, opts)) < 0) {
|
if ((result = _xioopen_named_early(argc, argv, xxfd, groups, &exists, opts)) < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
if (opt_unlink_close) {
|
if (opt_unlink_close) {
|
||||||
if ((fd->stream.unlink_close = strdup(filename)) == NULL) {
|
if ((sfd->unlink_close = strdup(filename)) == NULL) {
|
||||||
Error1("strdup(\"%s\"): out of memory", filename);
|
Error1("strdup(\"%s\"): out of memory", filename);
|
||||||
}
|
}
|
||||||
fd->stream.opt_unlink_close = true;
|
sfd->opt_unlink_close = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Notice2("creating regular file \"%s\" for %s", filename, ddirection[rw]);
|
Notice2("creating regular file \"%s\" for %s", filename, ddirection[rw]);
|
||||||
if ((result = _xioopen_creat(filename, rw, opts)) < 0)
|
if ((result = _xioopen_creat(filename, rw, opts)) < 0)
|
||||||
return result;
|
return result;
|
||||||
fd->stream.fd = result;
|
sfd->fd = result;
|
||||||
|
|
||||||
applyopts_named(filename, opts, PH_PASTOPEN);
|
applyopts_named(filename, opts, PH_PASTOPEN);
|
||||||
if ((result = applyopts2(fd->stream.fd, opts, PH_PASTOPEN, PH_LATE2)) < 0)
|
if ((result = applyopts2(sfd, -1, opts, PH_PASTOPEN, PH_LATE2)) < 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
applyopts_cloexec(fd->stream.fd, opts);
|
applyopts_cloexec(sfd->fd, opts);
|
||||||
|
|
||||||
applyopts_fchown(fd->stream.fd, opts);
|
applyopts_fchown(sfd->fd, opts);
|
||||||
|
|
||||||
if ((result = _xio_openlate(&fd->stream, opts)) < 0)
|
if ((result = _xio_openlate(sfd, opts)) < 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
11
xio-exec.c
11
xio-exec.c
|
@ -26,13 +26,15 @@ const struct optdesc opt_dash = { "dash", "login", OPT_DASH, GROUP_EXEC, PH_PREE
|
||||||
|
|
||||||
static int xioopen_exec(int argc, const char *argv[], struct opt *opts,
|
static int xioopen_exec(int argc, const char *argv[], struct opt *opts,
|
||||||
int xioflags, /* XIO_RDONLY, XIO_MAYCHILD etc. */
|
int xioflags, /* XIO_RDONLY, XIO_MAYCHILD etc. */
|
||||||
xiofile_t *fd,
|
xiofile_t *xfd,
|
||||||
groups_t groups,
|
groups_t groups,
|
||||||
int dummy1, int dummy2, int dummy3
|
int dummy1, int dummy2, int dummy3
|
||||||
) {
|
) {
|
||||||
|
struct single *sfd = &xfd->stream;
|
||||||
int status;
|
int status;
|
||||||
bool dash = false;
|
bool dash = false;
|
||||||
int duptostderr;
|
int duptostderr;
|
||||||
|
int numleft;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
Error2("\"%s\": wrong number of parameters (%d instead of 1)", argv[0], argc-1);
|
Error2("\"%s\": wrong number of parameters (%d instead of 1)", argv[0], argc-1);
|
||||||
|
@ -40,8 +42,9 @@ static int xioopen_exec(int argc, const char *argv[], struct opt *opts,
|
||||||
|
|
||||||
retropt_bool(opts, OPT_DASH, &dash);
|
retropt_bool(opts, OPT_DASH, &dash);
|
||||||
|
|
||||||
status = _xioopen_foxec(xioflags, &fd->stream, groups, &opts, &duptostderr);
|
status = _xioopen_foxec(xioflags, sfd, groups, &opts, &duptostderr);
|
||||||
if (status < 0) return status;
|
if (status < 0)
|
||||||
|
return status;
|
||||||
if (status == 0) { /* child */
|
if (status == 0) { /* child */
|
||||||
const char *ends[] = { " ", NULL };
|
const char *ends[] = { " ", NULL };
|
||||||
const char *hquotes[] = { "'", NULL };
|
const char *hquotes[] = { "'", NULL };
|
||||||
|
@ -61,7 +64,6 @@ static int xioopen_exec(int argc, const char *argv[], struct opt *opts,
|
||||||
char *tokp;
|
char *tokp;
|
||||||
char *path = NULL;
|
char *path = NULL;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
int numleft;
|
|
||||||
|
|
||||||
/*! Close(something) */
|
/*! Close(something) */
|
||||||
/* parse command line */
|
/* parse command line */
|
||||||
|
@ -143,6 +145,7 @@ static int xioopen_exec(int argc, const char *argv[], struct opt *opts,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parent */
|
/* parent */
|
||||||
|
_xio_openlate(sfd, opts);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* WITH_EXEC */
|
#endif /* WITH_EXEC */
|
||||||
|
|
|
@ -120,10 +120,10 @@ int xioopen_fd(struct opt *opts, int rw, xiosingle_t *xfd, int numfd, int dummy2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* WITH_TERMIOS */
|
#endif /* WITH_TERMIOS */
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0)
|
||||||
applyopts(-1, opts, PH_INIT);
|
return -1;
|
||||||
|
|
||||||
applyopts2(xfd->fd, opts, PH_INIT, PH_FD);
|
applyopts2(xfd, -1, opts, PH_INIT, PH_FD);
|
||||||
|
|
||||||
return _xio_openlate(xfd, opts);
|
return _xio_openlate(xfd, opts);
|
||||||
}
|
}
|
||||||
|
|
27
xio-file.c
27
xio-file.c
|
@ -72,50 +72,51 @@ const struct addrdesc xioaddr_open = { "OPEN", 3, xioopen_open, GROUP_FD|GRO
|
||||||
if the filesystem entry already exists, the data is appended
|
if the filesystem entry already exists, the data is appended
|
||||||
if it does not exist, a file is created and the data is appended
|
if it does not exist, a file is created and the data is appended
|
||||||
*/
|
*/
|
||||||
static int xioopen_open(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3) {
|
static int xioopen_open(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3) {
|
||||||
const char *filename = argv[1];
|
const char *filename = argv[1];
|
||||||
int rw = (xioflags & XIO_ACCMODE);
|
int rw = (xioflags & XIO_ACCMODE);
|
||||||
|
struct single *sfd = &xfd->stream;
|
||||||
bool exists;
|
bool exists;
|
||||||
bool opt_unlink_close = false;
|
bool opt_unlink_close = false;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
/* remove old file, or set user/permissions on old file; parse options */
|
/* remove old file, or set user/permissions on old file; parse options */
|
||||||
if ((result = _xioopen_named_early(argc, argv, fd, groups, &exists, opts)) < 0) {
|
if ((result = _xioopen_named_early(argc, argv, xfd, groups, &exists, opts)) < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
if (opt_unlink_close) {
|
if (opt_unlink_close) {
|
||||||
if ((fd->stream.unlink_close = strdup(filename)) == NULL) {
|
if ((sfd->unlink_close = strdup(filename)) == NULL) {
|
||||||
Error1("strdup(\"%s\"): out of memory", filename);
|
Error1("strdup(\"%s\"): out of memory", filename);
|
||||||
}
|
}
|
||||||
fd->stream.opt_unlink_close = true;
|
sfd->opt_unlink_close = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Notice3("opening %s \"%s\" for %s",
|
Notice3("opening %s \"%s\" for %s",
|
||||||
filetypenames[(result&S_IFMT)>>12], filename, ddirection[rw]);
|
filetypenames[(result&S_IFMT)>>12], filename, ddirection[rw]);
|
||||||
if ((result = _xioopen_open(filename, rw, opts)) < 0)
|
if ((result = _xioopen_open(filename, rw, opts)) < 0)
|
||||||
return result;
|
return result;
|
||||||
fd->stream.fd = result;
|
sfd->fd = result;
|
||||||
|
|
||||||
#if WITH_TERMIOS
|
#if WITH_TERMIOS
|
||||||
if (Isatty(fd->stream.fd)) {
|
if (Isatty(sfd->fd)) {
|
||||||
if (Tcgetattr(fd->stream.fd, &fd->stream.savetty) < 0) {
|
if (Tcgetattr(sfd->fd, &sfd->savetty) < 0) {
|
||||||
Warn2("cannot query current terminal settings on fd %d: %s",
|
Warn2("cannot query current terminal settings on fd %d: %s",
|
||||||
fd->stream.fd, strerror(errno));
|
sfd->fd, strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
fd->stream.ttyvalid = true;
|
sfd->ttyvalid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* WITH_TERMIOS */
|
#endif /* WITH_TERMIOS */
|
||||||
|
|
||||||
applyopts_named(filename, opts, PH_FD);
|
applyopts_named(filename, opts, PH_FD);
|
||||||
applyopts(fd->stream.fd, opts, PH_FD);
|
applyopts(sfd, -1, opts, PH_FD);
|
||||||
applyopts_cloexec(fd->stream.fd, opts);
|
applyopts_cloexec(sfd->fd, opts);
|
||||||
|
|
||||||
applyopts_fchown(fd->stream.fd, opts);
|
applyopts_fchown(sfd->fd, opts);
|
||||||
|
|
||||||
if ((result = _xio_openlate(&fd->stream, opts)) < 0)
|
if ((result = _xio_openlate(sfd, opts)) < 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
33
xio-gopen.c
33
xio-gopen.c
|
@ -19,7 +19,8 @@ static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xio
|
||||||
|
|
||||||
const struct addrdesc xioaddr_gopen = { "GOPEN", 3, xioopen_gopen, GROUP_FD|GROUP_FIFO|GROUP_CHR|GROUP_BLK|GROUP_REG|GROUP_NAMED|GROUP_OPEN|GROUP_FILE|GROUP_TERMIOS|GROUP_SOCKET|GROUP_SOCK_UNIX, 0, 0, 0 HELP(":<filename>") };
|
const struct addrdesc xioaddr_gopen = { "GOPEN", 3, xioopen_gopen, GROUP_FD|GROUP_FIFO|GROUP_CHR|GROUP_BLK|GROUP_REG|GROUP_NAMED|GROUP_OPEN|GROUP_FILE|GROUP_TERMIOS|GROUP_SOCKET|GROUP_SOCK_UNIX, 0, 0, 0 HELP(":<filename>") };
|
||||||
|
|
||||||
static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3) {
|
static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int dummy1, int dummy2, int dummy3) {
|
||||||
|
struct single *sfd = &xxfd->stream;
|
||||||
const char *filename = argv[1];
|
const char *filename = argv[1];
|
||||||
flags_t openflags = (xioflags & XIO_ACCMODE);
|
flags_t openflags = (xioflags & XIO_ACCMODE);
|
||||||
mode_t st_mode;
|
mode_t st_mode;
|
||||||
|
@ -28,7 +29,7 @@ static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xio
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if ((result =
|
if ((result =
|
||||||
_xioopen_named_early(argc, argv, fd, GROUP_NAMED|groups, &exists, opts)) < 0) {
|
_xioopen_named_early(argc, argv, xxfd, GROUP_NAMED|groups, &exists, opts)) < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
st_mode = result;
|
st_mode = result;
|
||||||
|
@ -52,15 +53,15 @@ static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xio
|
||||||
Info1("\"%s\" is a socket, connecting to it", filename);
|
Info1("\"%s\" is a socket, connecting to it", filename);
|
||||||
|
|
||||||
result =
|
result =
|
||||||
_xioopen_unix_client(&fd->stream, xioflags, groups, 0, opts, filename);
|
_xioopen_unix_client(sfd, xioflags, groups, 0, opts, filename);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
applyopts_named(filename, opts, PH_PASTOPEN); /* unlink-late */
|
applyopts_named(filename, opts, PH_PASTOPEN); /* unlink-late */
|
||||||
|
|
||||||
if (Getsockname(fd->stream.fd, (struct sockaddr *)&us, &uslen) < 0) {
|
if (Getsockname(sfd->fd, (struct sockaddr *)&us, &uslen) < 0) {
|
||||||
Warn4("getsockname(%d, %p, {%d}): %s",
|
Warn4("getsockname(%d, %p, {%d}): %s",
|
||||||
fd->stream.fd, &us, uslen, strerror(errno));
|
sfd->fd, &us, uslen, strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
Notice1("successfully connected via %s",
|
Notice1("successfully connected via %s",
|
||||||
sockaddr_unix_info(&us.un, uslen,
|
sockaddr_unix_info(&us.un, uslen,
|
||||||
|
@ -78,10 +79,10 @@ static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xio
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
if (opt_unlink_close) {
|
if (opt_unlink_close) {
|
||||||
if ((fd->stream.unlink_close = strdup(filename)) == NULL) {
|
if ((sfd->unlink_close = strdup(filename)) == NULL) {
|
||||||
Error1("strdup(\"%s\"): out of memory", filename);
|
Error1("strdup(\"%s\"): out of memory", filename);
|
||||||
}
|
}
|
||||||
fd->stream.opt_unlink_close = true;
|
sfd->opt_unlink_close = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Notice3("opening %s \"%s\" for %s",
|
Notice3("opening %s \"%s\" for %s",
|
||||||
|
@ -95,27 +96,27 @@ static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xio
|
||||||
Ioctl(result, I_PUSH, "ttcompat"); /* ... AdressSanitizer */
|
Ioctl(result, I_PUSH, "ttcompat"); /* ... AdressSanitizer */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
fd->stream.fd = result;
|
sfd->fd = result;
|
||||||
|
|
||||||
#if WITH_TERMIOS
|
#if WITH_TERMIOS
|
||||||
if (Isatty(fd->stream.fd)) {
|
if (Isatty(sfd->fd)) {
|
||||||
if (Tcgetattr(fd->stream.fd, &fd->stream.savetty) < 0) {
|
if (Tcgetattr(sfd->fd, &sfd->savetty) < 0) {
|
||||||
Warn2("cannot query current terminal settings on fd %d: %s",
|
Warn2("cannot query current terminal settings on fd %d: %s",
|
||||||
fd->stream.fd, strerror(errno));
|
sfd->fd, strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
fd->stream.ttyvalid = true;
|
sfd->ttyvalid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* WITH_TERMIOS */
|
#endif /* WITH_TERMIOS */
|
||||||
applyopts_named(filename, opts, PH_FD);
|
applyopts_named(filename, opts, PH_FD);
|
||||||
applyopts(fd->stream.fd, opts, PH_FD);
|
applyopts(sfd, -1, opts, PH_FD);
|
||||||
applyopts_cloexec(fd->stream.fd, opts);
|
applyopts_cloexec(sfd->fd, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result = applyopts2(fd->stream.fd, opts, PH_PASTSOCKET, PH_CONNECTED)) < 0)
|
if ((result = applyopts2(sfd, -1, opts, PH_PASTSOCKET, PH_CONNECTED)) < 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if ((result = _xio_openlate(&fd->stream, opts)) < 0)
|
if ((result = _xio_openlate(sfd, opts)) < 0)
|
||||||
return result;
|
return result;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ int _xioopen_interface(const char *ifname,
|
||||||
|
|
||||||
/* ...res_opts[] */
|
/* ...res_opts[] */
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(xfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
xfd->salen = sizeof(xfd->peersa);
|
xfd->salen = sizeof(xfd->peersa);
|
||||||
if (pf == PF_UNSPEC) {
|
if (pf == PF_UNSPEC) {
|
||||||
|
|
2
xio-ip.c
2
xio-ip.c
|
@ -69,7 +69,7 @@ const struct optdesc opt_ip_multicast_if ={"ip-multicast-if", "multicast-if",
|
||||||
const struct optdesc opt_ip_pktoptions = { "ip-pktoptions", "pktopts", OPT_IP_PKTOPTIONS, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_PKTOPTIONS };
|
const struct optdesc opt_ip_pktoptions = { "ip-pktoptions", "pktopts", OPT_IP_PKTOPTIONS, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_PKTOPTIONS };
|
||||||
#endif
|
#endif
|
||||||
#ifdef IP_ADD_MEMBERSHIP
|
#ifdef IP_ADD_MEMBERSHIP
|
||||||
const struct optdesc opt_ip_add_membership = { "ip-add-membership", "membership",OPT_IP_ADD_MEMBERSHIP, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_IP_MREQN, OFUNC_SOCKOPT, SOL_IP, IP_ADD_MEMBERSHIP };
|
const struct optdesc opt_ip_add_membership = { "ip-add-membership", "membership",OPT_IP_ADD_MEMBERSHIP, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_IP_MREQN, OFUNC_SPEC, SOL_IP, IP_ADD_MEMBERSHIP };
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAVE_STRUCT_IP_MREQ_SOURCE) && defined(IP_ADD_SOURCE_MEMBERSHIP)
|
#if defined(HAVE_STRUCT_IP_MREQ_SOURCE) && defined(IP_ADD_SOURCE_MEMBERSHIP)
|
||||||
const struct optdesc opt_ip_add_source_membership = { "ip-add-source-membership", "source-membership",OPT_IP_ADD_SOURCE_MEMBERSHIP, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_IP_MREQ_SOURCE, OFUNC_SOCKOPT, SOL_IP, IP_ADD_SOURCE_MEMBERSHIP };
|
const struct optdesc opt_ip_add_source_membership = { "ip-add-source-membership", "source-membership",OPT_IP_ADD_SOURCE_MEMBERSHIP, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_IP_MREQ_SOURCE, OFUNC_SOCKOPT, SOL_IP, IP_ADD_SOURCE_MEMBERSHIP };
|
||||||
|
|
|
@ -48,7 +48,7 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0)
|
if (applyopts_single(xfd, opts, PH_INIT) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(xfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
retropt_bool(opts, OPT_FORK, &dofork);
|
retropt_bool(opts, OPT_FORK, &dofork);
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts(-1, opts, PH_EARLY);
|
applyopts(NULL, -1, opts, PH_EARLY);
|
||||||
|
|
||||||
/* 3 means: IP address AND port accepted */
|
/* 3 means: IP address AND port accepted */
|
||||||
if (retropt_bind(opts, (*pf!=PF_UNSPEC)?*pf:(*themlist)->ai_family,
|
if (retropt_bind(opts, (*pf!=PF_UNSPEC)?*pf:(*themlist)->ai_family,
|
||||||
|
@ -306,6 +306,7 @@ int xioopen_ipapp_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
int xioflags, xiofile_t *xfd,
|
int xioflags, xiofile_t *xfd,
|
||||||
groups_t groups, int socktype,
|
groups_t groups, int socktype,
|
||||||
int ipproto, int pf) {
|
int ipproto, int pf) {
|
||||||
|
struct single *sfd = &xfd->stream;
|
||||||
struct opt *opts0 = NULL;
|
struct opt *opts0 = NULL;
|
||||||
union sockaddr_union us_sa, *us = &us_sa;
|
union sockaddr_union us_sa, *us = &us_sa;
|
||||||
socklen_t uslen = sizeof(us_sa);
|
socklen_t uslen = sizeof(us_sa);
|
||||||
|
@ -333,8 +334,8 @@ int xioopen_ipapp_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
xfd->stream.howtoend = END_SHUTDOWN;
|
xfd->stream.howtoend = END_SHUTDOWN;
|
||||||
|
|
||||||
if (applyopts_single(&xfd->stream, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(&xfd->stream, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
applyopts(-1, opts, PH_EARLY);
|
applyopts(sfd, -1, opts, PH_EARLY);
|
||||||
|
|
||||||
if (_xioopen_ipapp_listen_prepare(opts, &opts0, argv[1], &pf, ipproto,
|
if (_xioopen_ipapp_listen_prepare(opts, &opts0, argv[1], &pf, ipproto,
|
||||||
xfd->stream.para.socket.ip.ai_flags,
|
xfd->stream.para.socket.ip.ai_flags,
|
||||||
|
|
25
xio-listen.c
25
xio-listen.c
|
@ -113,16 +113,16 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl
|
||||||
if ((xfd->fd = xiosocket(opts, pf?pf:us->sa_family, socktype, proto, level)) < 0) {
|
if ((xfd->fd = xiosocket(opts, pf?pf:us->sa_family, socktype, proto, level)) < 0) {
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
applyopts(xfd->fd, opts, PH_PASTSOCKET);
|
applyopts(xfd, -1, opts, PH_PASTSOCKET);
|
||||||
|
|
||||||
applyopts_offset(xfd, opts);
|
applyopts_offset(xfd, opts);
|
||||||
applyopts_cloexec(xfd->fd, opts);
|
applyopts_cloexec(xfd->fd, opts);
|
||||||
|
|
||||||
/* Phase prebind */
|
/* Phase prebind */
|
||||||
xiosock_reuseaddr(xfd->fd, proto, opts);
|
xiosock_reuseaddr(xfd->fd, proto, opts);
|
||||||
applyopts(xfd->fd, opts, PH_PREBIND);
|
applyopts(xfd, -1, opts, PH_PREBIND);
|
||||||
|
|
||||||
applyopts(xfd->fd, opts, PH_BIND);
|
applyopts(xfd, -1, opts, PH_BIND);
|
||||||
if (Bind(xfd->fd, (struct sockaddr *)us, uslen) < 0) {
|
if (Bind(xfd->fd, (struct sockaddr *)us, uslen) < 0) {
|
||||||
Msg4(level, "bind(%d, {%s}, "F_socklen"): %s", xfd->fd,
|
Msg4(level, "bind(%d, {%s}, "F_socklen"): %s", xfd->fd,
|
||||||
sockaddr_info(us, uslen, infobuff, sizeof(infobuff)), uslen,
|
sockaddr_info(us, uslen, infobuff, sizeof(infobuff)), uslen,
|
||||||
|
@ -136,28 +136,27 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl
|
||||||
if (((union sockaddr_union *)us)->un.sun_path[0] != '\0') {
|
if (((union sockaddr_union *)us)->un.sun_path[0] != '\0') {
|
||||||
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_FD);
|
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_FD);
|
||||||
} else {
|
} else {
|
||||||
applyopts(xfd->fd, opts, PH_FD);
|
applyopts(xfd, -1, opts, PH_FD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
applyopts(xfd->fd, opts, PH_PASTBIND);
|
applyopts(xfd, -1, opts, PH_PASTBIND);
|
||||||
#if WITH_UNIX
|
#if WITH_UNIX
|
||||||
if (us->sa_family == AF_UNIX) {
|
if (us->sa_family == AF_UNIX) {
|
||||||
if (((union sockaddr_union *)us)->un.sun_path[0] != '\0') {
|
if (((union sockaddr_union *)us)->un.sun_path[0] != '\0') {
|
||||||
/*applyopts_early(((struct sockaddr_un *)us)->sun_path, opts);*/
|
|
||||||
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_EARLY);
|
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_EARLY);
|
||||||
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_PREOPEN);
|
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_PREOPEN);
|
||||||
} else {
|
} else {
|
||||||
applyopts(xfd->fd, opts, PH_EARLY);
|
applyopts(xfd, -1, opts, PH_EARLY);
|
||||||
applyopts(xfd->fd, opts, PH_PREOPEN);
|
applyopts(xfd, -1, opts, PH_PREOPEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* WITH_UNIX */
|
#endif /* WITH_UNIX */
|
||||||
|
|
||||||
applyopts(xfd->fd, opts, PH_PRELISTEN);
|
applyopts(xfd, -1, opts, PH_PRELISTEN);
|
||||||
retropt_int(opts, OPT_BACKLOG, &backlog);
|
retropt_int(opts, OPT_BACKLOG, &backlog);
|
||||||
applyopts(xfd->fd, opts, PH_LISTEN);
|
applyopts(xfd, -1, opts, PH_LISTEN);
|
||||||
if (Listen(xfd->fd, backlog) < 0) {
|
if (Listen(xfd->fd, backlog) < 0) {
|
||||||
Error3("listen(%d, %d): %s", xfd->fd, backlog, strerror(errno));
|
Error3("listen(%d, %d): %s", xfd->fd, backlog, strerror(errno));
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
|
@ -419,9 +418,9 @@ int _xioopen_accept_fd(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts(xfd->fd, opts, PH_FD);
|
applyopts(xfd, -1, opts, PH_FD);
|
||||||
applyopts(xfd->fd, opts, PH_PASTSOCKET);
|
applyopts(xfd, -1, opts, PH_PASTSOCKET);
|
||||||
applyopts(xfd->fd, opts, PH_CONNECTED);
|
applyopts(xfd, -1, opts, PH_CONNECTED);
|
||||||
if ((result = _xio_openlate(xfd, opts)) < 0)
|
if ((result = _xio_openlate(xfd, opts)) < 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,7 @@ int _xioopen_named_early(int argc, const char *argv[], xiofile_t *xfd,
|
||||||
groups_t groups, bool *exists, struct opt *opts)
|
groups_t groups, bool *exists, struct opt *opts)
|
||||||
{
|
{
|
||||||
const char *path = argv[1];
|
const char *path = argv[1];
|
||||||
|
struct single *sfd = &xfd->stream;
|
||||||
#if HAVE_STAT64
|
#if HAVE_STAT64
|
||||||
struct stat64 statbuf;
|
struct stat64 statbuf;
|
||||||
#else
|
#else
|
||||||
|
@ -127,8 +128,9 @@ int _xioopen_named_early(int argc, const char *argv[], xiofile_t *xfd,
|
||||||
*exists = true;
|
*exists = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (applyopts_single(&xfd->stream, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0)
|
||||||
applyopts(-1, opts, PH_INIT);
|
return -1;
|
||||||
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
||||||
if (*exists && opt_unlink_early) {
|
if (*exists && opt_unlink_early) {
|
||||||
|
@ -141,7 +143,7 @@ int _xioopen_named_early(int argc, const char *argv[], xiofile_t *xfd,
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts_named(path, opts, PH_EARLY);
|
applyopts_named(path, opts, PH_EARLY);
|
||||||
applyopts(-1, opts, PH_EARLY);
|
applyopts(sfd, -1, opts, PH_EARLY);
|
||||||
if (*exists) {
|
if (*exists) {
|
||||||
applyopts_named(path, opts, PH_PREOPEN);
|
applyopts_named(path, opts, PH_PREOPEN);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -240,6 +240,7 @@ static int
|
||||||
addr_openssl */
|
addr_openssl */
|
||||||
{
|
{
|
||||||
struct single *xfd = &xxfd->stream;
|
struct single *xfd = &xxfd->stream;
|
||||||
|
struct single *sfd = xfd;
|
||||||
struct opt *opts0 = NULL;
|
struct opt *opts0 = NULL;
|
||||||
const char *hostname, *portname;
|
const char *hostname, *portname;
|
||||||
int pf = PF_UNSPEC;
|
int pf = PF_UNSPEC;
|
||||||
|
@ -284,7 +285,7 @@ static int
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
xfd->howtoend = END_SHUTDOWN;
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
retropt_bool(opts, OPT_FORK, &dofork);
|
retropt_bool(opts, OPT_FORK, &dofork);
|
||||||
|
|
||||||
|
@ -561,6 +562,7 @@ static int
|
||||||
addr_openssl */
|
addr_openssl */
|
||||||
{
|
{
|
||||||
struct single *xfd = &xxfd->stream;
|
struct single *xfd = &xxfd->stream;
|
||||||
|
struct single *sfd = xfd;
|
||||||
const char *portname;
|
const char *portname;
|
||||||
struct opt *opts0 = NULL;
|
struct opt *opts0 = NULL;
|
||||||
union sockaddr_union us_sa, *us = &us_sa;
|
union sockaddr_union us_sa, *us = &us_sa;
|
||||||
|
@ -604,7 +606,7 @@ static int
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
xfd->howtoend = END_SHUTDOWN;
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
retropt_string(opts, OPT_OPENSSL_CERTIFICATE, &opt_cert);
|
retropt_string(opts, OPT_OPENSSL_CERTIFICATE, &opt_cert);
|
||||||
if (opt_cert == NULL) {
|
if (opt_cert == NULL) {
|
||||||
|
@ -613,7 +615,7 @@ static int
|
||||||
|
|
||||||
retropt_string(opts, OPT_OPENSSL_COMMONNAME, (char **)&opt_commonname);
|
retropt_string(opts, OPT_OPENSSL_COMMONNAME, (char **)&opt_commonname);
|
||||||
|
|
||||||
applyopts(-1, opts, PH_EARLY);
|
applyopts(sfd, -1, opts, PH_EARLY);
|
||||||
|
|
||||||
result =
|
result =
|
||||||
_xioopen_openssl_prepare(opts, xfd, true, &opt_ver, opt_cert, &ctx, &use_dtls);
|
_xioopen_openssl_prepare(opts, xfd, true, &opt_ver, opt_cert, &ctx, &use_dtls);
|
||||||
|
|
54
xio-pipe.c
54
xio-pipe.c
|
@ -24,13 +24,14 @@ const struct addrdesc xioaddr_pipe = { "PIPE", 3, xioopen_fifo, GROUP_FD|GR
|
||||||
/* process an unnamed bidirectional "pipe" or "fifo" or "echo" argument with
|
/* process an unnamed bidirectional "pipe" or "fifo" or "echo" argument with
|
||||||
options */
|
options */
|
||||||
static int xioopen_fifo_unnamed(xiofile_t *sock, struct opt *opts) {
|
static int xioopen_fifo_unnamed(xiofile_t *sock, struct opt *opts) {
|
||||||
|
struct single *sfd = &sock->stream;
|
||||||
struct opt *opts2;
|
struct opt *opts2;
|
||||||
int filedes[2];
|
int filedes[2];
|
||||||
int numleft;
|
int numleft;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (applyopts_single(&sock->stream, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
if (Pipe(filedes) != 0) {
|
if (Pipe(filedes) != 0) {
|
||||||
Error2("pipe(%p): %s", filedes, strerror(errno));
|
Error2("pipe(%p): %s", filedes, strerror(errno));
|
||||||
|
@ -39,15 +40,15 @@ static int xioopen_fifo_unnamed(xiofile_t *sock, struct opt *opts) {
|
||||||
/*0 Info2("pipe({%d,%d})", filedes[0], filedes[1]);*/
|
/*0 Info2("pipe({%d,%d})", filedes[0], filedes[1]);*/
|
||||||
|
|
||||||
sock->common.tag = XIO_TAG_RDWR;
|
sock->common.tag = XIO_TAG_RDWR;
|
||||||
sock->stream.dtype = XIODATA_PIPE;
|
sfd->dtype = XIODATA_PIPE;
|
||||||
sock->stream.fd = filedes[0];
|
sfd->fd = filedes[0];
|
||||||
sock->stream.para.bipipe.fdout = filedes[1];
|
sfd->para.bipipe.fdout = filedes[1];
|
||||||
sock->stream.para.bipipe.socktype = SOCK_STREAM; /* due to socketpair reuse */
|
sfd->para.bipipe.socktype = SOCK_STREAM; /* due to socketpair reuse */
|
||||||
applyopts_cloexec(sock->stream.fd, opts);
|
applyopts_cloexec(sfd->fd, opts);
|
||||||
applyopts_cloexec(sock->stream.para.bipipe.fdout, opts);
|
applyopts_cloexec(sfd->para.bipipe.fdout, opts);
|
||||||
|
|
||||||
/* one-time and input-direction options, no second application */
|
/* one-time and input-direction options, no second application */
|
||||||
retropt_bool(opts, OPT_IGNOREEOF, &sock->stream.ignoreeof);
|
retropt_bool(opts, OPT_IGNOREEOF, &sfd->ignoreeof);
|
||||||
|
|
||||||
/* here we copy opts! */
|
/* here we copy opts! */
|
||||||
if ((opts2 = copyopts(opts, GROUP_FIFO)) == NULL) {
|
if ((opts2 = copyopts(opts, GROUP_FIFO)) == NULL) {
|
||||||
|
@ -55,18 +56,16 @@ static int xioopen_fifo_unnamed(xiofile_t *sock, struct opt *opts) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* apply options to first FD */
|
/* apply options to first FD */
|
||||||
if ((result = applyopts(sock->stream.fd, opts, PH_ALL)) < 0) {
|
if ((result = applyopts(sfd, -1, opts, PH_ALL)) < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if ((result = applyopts_single(&sock->stream, opts, PH_ALL)) < 0) {
|
if ((result = applyopts_single(sfd, opts, PH_ALL)) < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* apply options to second FD */
|
/* apply options to second FD */
|
||||||
if ((result = applyopts(sock->stream.para.bipipe.fdout, opts2, PH_ALL)) < 0)
|
if (applyopts(&sock->stream, sfd->para.bipipe.fdout, opts2, PH_ALL) < 0)
|
||||||
{
|
return -1;
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((numleft = leftopts(opts)) > 0) {
|
if ((numleft = leftopts(opts)) > 0) {
|
||||||
showleft(opts);
|
showleft(opts);
|
||||||
|
@ -78,7 +77,8 @@ static int xioopen_fifo_unnamed(xiofile_t *sock, struct opt *opts) {
|
||||||
|
|
||||||
|
|
||||||
/* open a named or unnamed pipe/fifo */
|
/* open a named or unnamed pipe/fifo */
|
||||||
static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3) {
|
static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3) {
|
||||||
|
struct single *sfd = &xfd->stream;
|
||||||
const char *pipename = argv[1];
|
const char *pipename = argv[1];
|
||||||
int rw = (xioflags & XIO_ACCMODE);
|
int rw = (xioflags & XIO_ACCMODE);
|
||||||
#if HAVE_STAT64
|
#if HAVE_STAT64
|
||||||
|
@ -92,19 +92,20 @@ static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xiof
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
return xioopen_fifo_unnamed(fd, fd->stream.opts);
|
return xioopen_fifo_unnamed(xfd, sfd->opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
|
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (applyopts_single(&fd->stream, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0)
|
||||||
applyopts(-1, opts, PH_INIT);
|
return -1;
|
||||||
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
||||||
applyopts_named(pipename, opts, PH_EARLY); /* umask! */
|
applyopts_named(pipename, opts, PH_EARLY); /* umask! */
|
||||||
applyopts(-1, opts, PH_EARLY);
|
applyopts(sfd, -1, opts, PH_EARLY);
|
||||||
|
|
||||||
if (opt_unlink_early) {
|
if (opt_unlink_early) {
|
||||||
if (Unlink(pipename) < 0) {
|
if (Unlink(pipename) < 0) {
|
||||||
|
@ -149,10 +150,10 @@ static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xiof
|
||||||
|
|
||||||
}
|
}
|
||||||
if (opt_unlink_close) {
|
if (opt_unlink_close) {
|
||||||
if ((fd->stream.unlink_close = strdup(pipename)) == NULL) {
|
if ((sfd->unlink_close = strdup(pipename)) == NULL) {
|
||||||
Error1("strdup(\"%s\"): out of memory", pipename);
|
Error1("strdup(\"%s\"): out of memory", pipename);
|
||||||
}
|
}
|
||||||
fd->stream.opt_unlink_close = true;
|
sfd->opt_unlink_close = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* exists */
|
/* exists */
|
||||||
|
@ -160,19 +161,18 @@ static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xiof
|
||||||
Notice3("opening %s \"%s\" for %s",
|
Notice3("opening %s \"%s\" for %s",
|
||||||
filetypenames[(pipstat.st_mode&S_IFMT)>>12],
|
filetypenames[(pipstat.st_mode&S_IFMT)>>12],
|
||||||
pipename, ddirection[rw]);
|
pipename, ddirection[rw]);
|
||||||
/*applyopts_early(pipename, opts);*/
|
|
||||||
applyopts_named(pipename, opts, PH_EARLY);
|
applyopts_named(pipename, opts, PH_EARLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result = _xioopen_open(pipename, rw, opts)) < 0) {
|
if ((result = _xioopen_open(pipename, rw, opts)) < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
fd->stream.fd = result;
|
sfd->fd = result;
|
||||||
|
|
||||||
applyopts_named(pipename, opts, PH_FD);
|
applyopts_named(pipename, opts, PH_FD);
|
||||||
applyopts(fd->stream.fd, opts, PH_FD);
|
applyopts(sfd, -1, opts, PH_FD);
|
||||||
applyopts_cloexec(fd->stream.fd, opts);
|
applyopts_cloexec(sfd->fd, opts);
|
||||||
return _xio_openlate(&fd->stream, opts);
|
return _xio_openlate(sfd, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* WITH_PIPE */
|
#endif /* WITH_PIPE */
|
||||||
|
|
|
@ -90,7 +90,7 @@ static int xioopen_posixmq(
|
||||||
}
|
}
|
||||||
applyopts_offset(sfd, opts);
|
applyopts_offset(sfd, opts);
|
||||||
if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
if ((sfd->para.posixmq.name = strdup(name)) == NULL) {
|
if ((sfd->para.posixmq.name = strdup(name)) == NULL) {
|
||||||
Error1("strdup(\"%s\"): out of memory", name);
|
Error1("strdup(\"%s\"): out of memory", name);
|
||||||
|
|
219
xio-progcall.c
219
xio-progcall.c
|
@ -47,12 +47,14 @@ const struct optdesc opt_sigquit = { "sigquit", NULL, OPT_SIGQUIT, GROUP_P
|
||||||
return<0: error occurred, assume parent process and no child exists !!!
|
return<0: error occurred, assume parent process and no child exists !!!
|
||||||
*/
|
*/
|
||||||
int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
struct single *fd,
|
struct single *sfd,
|
||||||
groups_t groups,
|
groups_t groups,
|
||||||
struct opt **copts, /* in: opts; out: opts for child */
|
struct opt **optsp, /* in: opts; out: opts for parent/child */
|
||||||
int *duptostderr /* out: redirect stderr to output fd */
|
int *duptostderr /* out: redirect stderr to output fd */
|
||||||
) {
|
) {
|
||||||
struct opt *popts; /* parent process options */
|
struct opt *opts; /* common options */
|
||||||
|
struct opt *popts; /* parent options */
|
||||||
|
struct opt *copts; /* child options */
|
||||||
int numleft;
|
int numleft;
|
||||||
int d, sv[2], rdpip[2], wrpip[2];
|
int d, sv[2], rdpip[2], wrpip[2];
|
||||||
int rw = (xioflags & XIO_ACCMODE);
|
int rw = (xioflags & XIO_ACCMODE);
|
||||||
|
@ -78,21 +80,21 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
char *tn = NULL;
|
char *tn = NULL;
|
||||||
int trigger[2]; /* [0] watched by parent, [1] closed by child when ready */
|
int trigger[2]; /* [0] watched by parent, [1] closed by child when ready */
|
||||||
|
|
||||||
popts = moveopts(*copts, GROUP_ALL);
|
opts = *optsp;
|
||||||
if (applyopts_single(fd, popts, PH_INIT) < 0) return -1;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts2(-1, popts, PH_INIT, PH_EARLY);
|
applyopts2(sfd, -1, opts, PH_INIT, PH_EARLY);
|
||||||
|
|
||||||
retropt_bool(popts, OPT_NOFORK, &nofork);
|
retropt_bool(opts, OPT_NOFORK, &nofork);
|
||||||
withfork = !nofork;
|
withfork = !nofork;
|
||||||
|
|
||||||
retropt_bool(popts, OPT_PIPES, &usepipes);
|
retropt_bool(opts, OPT_PIPES, &usepipes);
|
||||||
#if HAVE_PTY
|
#if HAVE_PTY
|
||||||
retropt_bool(popts, OPT_PTY, &usebestpty);
|
retropt_bool(opts, OPT_PTY, &usebestpty);
|
||||||
#if HAVE_OPENPTY
|
#if HAVE_OPENPTY
|
||||||
retropt_bool(popts, OPT_OPENPTY, &useopenpty);
|
retropt_bool(opts, OPT_OPENPTY, &useopenpty);
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAVE_DEV_PTMX) || defined(HAVE_DEV_PTC)
|
#if defined(HAVE_DEV_PTMX) || defined(HAVE_DEV_PTC)
|
||||||
retropt_bool(popts, OPT_PTMX, &useptmx);
|
retropt_bool(opts, OPT_PTMX, &useptmx);
|
||||||
#endif
|
#endif
|
||||||
usepty = (usebestpty
|
usepty = (usebestpty
|
||||||
#if HAVE_OPENPTY
|
#if HAVE_OPENPTY
|
||||||
|
@ -108,12 +110,12 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
}
|
}
|
||||||
#endif /* HAVE_PTY */
|
#endif /* HAVE_PTY */
|
||||||
|
|
||||||
if (retropt_ushort(popts, OPT_FDIN, (unsigned short *)&fdi) >= 0) {
|
if (retropt_ushort(opts, OPT_FDIN, (unsigned short *)&fdi) >= 0) {
|
||||||
if ((xioflags&XIO_ACCMODE) == XIO_RDONLY) {
|
if ((xioflags&XIO_ACCMODE) == XIO_RDONLY) {
|
||||||
Error("_xioopen_foxec(): option fdin is useless in read-only mode");
|
Error("_xioopen_foxec(): option fdin is useless in read-only mode");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (retropt_ushort(popts, OPT_FDOUT, (unsigned short *)&fdo) >= 0) {
|
if (retropt_ushort(opts, OPT_FDOUT, (unsigned short *)&fdo) >= 0) {
|
||||||
if ((xioflags&XIO_ACCMODE) == XIO_WRONLY) {
|
if ((xioflags&XIO_ACCMODE) == XIO_WRONLY) {
|
||||||
Error("_xioopen_foxec(): option fdout is useless in write-only mode");
|
Error("_xioopen_foxec(): option fdout is useless in write-only mode");
|
||||||
}
|
}
|
||||||
|
@ -125,7 +127,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
/*!! free something */
|
/*!! free something */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fd->flags |= XIO_DOESCHILD;
|
sfd->flags |= XIO_DOESCHILD;
|
||||||
|
|
||||||
#if HAVE_PTY
|
#if HAVE_PTY
|
||||||
Notice2("forking off child, using %s for %s",
|
Notice2("forking off child, using %s for %s",
|
||||||
|
@ -137,7 +139,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
ddirection[rw]);
|
ddirection[rw]);
|
||||||
#endif /* HAVE_PTY */
|
#endif /* HAVE_PTY */
|
||||||
}
|
}
|
||||||
applyopts(-1, popts, PH_PREBIGEN);
|
applyopts(sfd, -1, opts, PH_PREBIGEN);
|
||||||
|
|
||||||
if (!withfork) {
|
if (!withfork) {
|
||||||
/*0 struct single *stream1, *stream2;*/
|
/*0 struct single *stream1, *stream2;*/
|
||||||
|
@ -147,10 +149,13 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
/*!! free something */
|
/*!! free something */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fd->flags |= XIO_DOESEXEC;
|
sfd->flags |= XIO_DOESEXEC;
|
||||||
|
|
||||||
free(*copts);
|
/* Only one process, no parent,child */
|
||||||
*copts = moveopts(popts, GROUP_ALL);
|
if ((copts = moveopts(opts, GROUP_ALL)) == NULL) {
|
||||||
|
/*!! free something */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0 /*!! */
|
#if 0 /*!! */
|
||||||
if (sock1->tag == XIO_TAG_DUAL) {
|
if (sock1->tag == XIO_TAG_DUAL) {
|
||||||
|
@ -207,7 +212,8 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
/*0 Info2("dup2(%d, %d)", XIO_GETWRFD(sock[0]), fdo);*/
|
/*0 Info2("dup2(%d, %d)", XIO_GETWRFD(sock[0]), fdo);*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
/* !withfork */
|
||||||
|
} else /* withfork */
|
||||||
#if HAVE_PTY
|
#if HAVE_PTY
|
||||||
if (usepty) {
|
if (usepty) {
|
||||||
|
|
||||||
|
@ -216,7 +222,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
#elif HAVE_DEV_PTC
|
#elif HAVE_DEV_PTC
|
||||||
# define PTMX "/dev/ptc" /* AIX 4.3.3 */
|
# define PTMX "/dev/ptc" /* AIX 4.3.3 */
|
||||||
#endif
|
#endif
|
||||||
fd->dtype = XIODATA_PTY;
|
sfd->dtype = XIODATA_PTY;
|
||||||
#if HAVE_DEV_PTMX || HAVE_DEV_PTC
|
#if HAVE_DEV_PTMX || HAVE_DEV_PTC
|
||||||
if (usebestpty || useptmx) {
|
if (usebestpty || useptmx) {
|
||||||
if ((ptyfd = Open(PTMX, O_RDWR|O_NOCTTY, 0620)) < 0) {
|
if ((ptyfd = Open(PTMX, O_RDWR|O_NOCTTY, 0620)) < 0) {
|
||||||
|
@ -264,30 +270,30 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* HAVE_OPENPTY */
|
#endif /* HAVE_OPENPTY */
|
||||||
free(*copts);
|
/* withfork use_pty */
|
||||||
if ((*copts = moveopts(popts, GROUP_TERMIOS|GROUP_FORK|GROUP_EXEC|GROUP_PROCESS|GROUP_NAMED)) == NULL) {
|
if ((copts = moveopts(opts, GROUP_TERMIOS|GROUP_FORK|GROUP_EXEC|GROUP_PROCESS|GROUP_NAMED)) == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
popts = opts;
|
||||||
applyopts_cloexec(ptyfd, popts);/*!*/
|
applyopts_cloexec(ptyfd, popts);/*!*/
|
||||||
/* exec:...,pty did not kill child process under some circumstances */
|
/* exec:...,pty did not kill child process under some circumstances */
|
||||||
if (fd->howtoend == END_UNSPEC) {
|
if (sfd->howtoend == END_UNSPEC) {
|
||||||
fd->howtoend = END_CLOSE_KILL;
|
sfd->howtoend = END_CLOSE_KILL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this for parent, was after fork */
|
/* this for parent, was after fork */
|
||||||
applyopts(ptyfd, popts, PH_FD);
|
applyopts(sfd, ptyfd, popts, PH_FD);
|
||||||
applyopts(ptyfd, popts, PH_LATE);
|
sfd->fd = ptyfd;
|
||||||
if (applyopts_single(fd, popts, PH_LATE) < 0) return -1;
|
|
||||||
|
|
||||||
fd->fd = ptyfd;
|
/* end withfork, use_pty */
|
||||||
|
} else /* end withfork, use_pty */
|
||||||
} else
|
|
||||||
#endif /* HAVE_PTY */
|
#endif /* HAVE_PTY */
|
||||||
|
|
||||||
if (usepipes) {
|
if (usepipes) {
|
||||||
struct opt *popts2, *copts2;
|
/* withfork usepipes */
|
||||||
|
|
||||||
if (rw == XIO_RDWR)
|
if (rw == XIO_RDWR)
|
||||||
fd->dtype = XIODATA_2PIPE;
|
sfd->dtype = XIODATA_2PIPE;
|
||||||
if (rw != XIO_WRONLY) {
|
if (rw != XIO_WRONLY) {
|
||||||
if (Pipe(rdpip) < 0) {
|
if (Pipe(rdpip) < 0) {
|
||||||
Error2("pipe(%p): %s", rdpip, strerror(errno));
|
Error2("pipe(%p): %s", rdpip, strerror(errno));
|
||||||
|
@ -296,19 +302,18 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
}
|
}
|
||||||
/*0 Info2("pipe({%d,%d})", rdpip[0], rdpip[1]);*/
|
/*0 Info2("pipe({%d,%d})", rdpip[0], rdpip[1]);*/
|
||||||
/* rdpip[0]: read by socat; rdpip[1]: write by child */
|
/* rdpip[0]: read by socat; rdpip[1]: write by child */
|
||||||
free(*copts);
|
|
||||||
if ((*copts = moveopts(popts, GROUP_FORK|GROUP_EXEC|GROUP_PROCESS))
|
/* withfork usepipes */
|
||||||
|
if ((copts = moveopts(opts, GROUP_FORK|GROUP_EXEC|GROUP_PROCESS))
|
||||||
== NULL) {
|
== NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
popts = opts;
|
||||||
popts2 = copyopts(popts, GROUP_ALL);
|
|
||||||
copts2 = copyopts(*copts, GROUP_ALL);
|
|
||||||
|
|
||||||
if (rw != XIO_WRONLY) {
|
if (rw != XIO_WRONLY) {
|
||||||
applyopts_cloexec(rdpip[0], popts);
|
applyopts_cloexec(rdpip[0], popts);
|
||||||
applyopts(rdpip[0], popts, PH_FD);
|
applyopts(NULL, rdpip[0], popts, PH_FD);
|
||||||
applyopts(rdpip[1], *copts, PH_FD);
|
applyopts(NULL, rdpip[1], copts, PH_FD);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rw != XIO_RDONLY) {
|
if (rw != XIO_RDONLY) {
|
||||||
|
@ -317,65 +322,70 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*0 Info2("pipe({%d,%d})", wrpip[0], wrpip[1]);*/
|
|
||||||
|
|
||||||
/* wrpip[1]: write by socat; wrpip[0]: read by child */
|
/* wrpip[1]: write by socat; wrpip[0]: read by child */
|
||||||
if (rw != XIO_RDONLY) {
|
if (rw != XIO_RDONLY) {
|
||||||
applyopts_cloexec(wrpip[1], popts2);
|
applyopts_cloexec(wrpip[1], popts);
|
||||||
applyopts(wrpip[1], popts2, PH_FD);
|
applyopts(NULL, wrpip[1], popts, PH_FD);
|
||||||
applyopts(wrpip[0], copts2, PH_FD);
|
applyopts(NULL, wrpip[0], copts, PH_FD);
|
||||||
}
|
}
|
||||||
if (fd->howtoend == END_UNSPEC) {
|
if (sfd->howtoend == END_UNSPEC) {
|
||||||
fd->howtoend = END_CLOSE_KILL;
|
sfd->howtoend = END_CLOSE_KILL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this for parent, was after fork */
|
/* this for parent, was after fork */
|
||||||
switch (rw) {
|
switch (rw) {
|
||||||
case XIO_RDONLY: fd->fd = rdpip[0]; break;
|
case XIO_RDONLY: sfd->fd = rdpip[0]; break;
|
||||||
case XIO_WRONLY: fd->fd = wrpip[1]; break;
|
case XIO_WRONLY: sfd->fd = wrpip[1]; break;
|
||||||
case XIO_RDWR: fd->fd = rdpip[0];
|
case XIO_RDWR: sfd->fd = rdpip[0];
|
||||||
fd->para.exec.fdout = wrpip[1];
|
sfd->para.exec.fdout = wrpip[1];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
applyopts(fd->fd, popts, PH_FD);
|
applyopts(sfd, -1, popts, PH_FD);
|
||||||
applyopts(fd->fd, popts, PH_LATE);
|
applyopts(sfd, -1, popts, PH_LATE);
|
||||||
if (applyopts_single(fd, popts, PH_LATE) < 0) return -1;
|
if (applyopts_single(sfd, popts, PH_LATE) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* end withfork, use_pipes */
|
||||||
} else {
|
} else {
|
||||||
|
/* withfork, socketpair */
|
||||||
|
|
||||||
d = AF_UNIX;
|
d = AF_UNIX;
|
||||||
retropt_int(popts, OPT_PROTOCOL_FAMILY, &d);
|
retropt_int(opts, OPT_PROTOCOL_FAMILY, &d);
|
||||||
result = xiosocketpair(popts, d, SOCK_STREAM, 0, sv);
|
result = xiosocketpair(opts, d, SOCK_STREAM, 0, sv);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/*0 Info5("socketpair(%d, %d, %d, {%d,%d})",
|
|
||||||
d, type, protocol, sv[0], sv[1]);*/
|
/* withfork socketpair */
|
||||||
free(*copts);
|
if ((copts = moveopts(opts, GROUP_FORK|GROUP_EXEC|GROUP_PROCESS)) == NULL) {
|
||||||
if ((*copts = moveopts(popts, GROUP_FORK|GROUP_EXEC|GROUP_PROCESS)) == NULL) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
applyopts(sv[0], *copts, PH_PASTSOCKET);
|
popts = opts;
|
||||||
applyopts(sv[1], popts, PH_PASTSOCKET);
|
applyopts(NULL, sv[0], copts, PH_PASTSOCKET);
|
||||||
|
applyopts(NULL, sv[1], popts, PH_PASTSOCKET);
|
||||||
|
|
||||||
applyopts_cloexec(sv[0], *copts);
|
applyopts_cloexec(sv[0], copts);
|
||||||
applyopts(sv[0], *copts, PH_FD);
|
applyopts(NULL, sv[0], copts, PH_FD);
|
||||||
applyopts(sv[1], popts, PH_FD);
|
applyopts(NULL, sv[1], popts, PH_FD);
|
||||||
|
|
||||||
applyopts(sv[0], *copts, PH_PREBIND);
|
applyopts(NULL, sv[0], copts, PH_PREBIND);
|
||||||
applyopts(sv[0], *copts, PH_BIND);
|
applyopts(NULL, sv[0], copts, PH_BIND);
|
||||||
applyopts(sv[0], *copts, PH_PASTBIND);
|
applyopts(NULL, sv[0], copts, PH_PASTBIND);
|
||||||
applyopts(sv[1], popts, PH_PREBIND);
|
applyopts(NULL, sv[1], popts, PH_PREBIND);
|
||||||
applyopts(sv[1], popts, PH_BIND);
|
applyopts(NULL, sv[1], popts, PH_BIND);
|
||||||
applyopts(sv[1], popts, PH_PASTBIND);
|
applyopts(NULL, sv[1], popts, PH_PASTBIND);
|
||||||
|
|
||||||
if (fd->howtoend == END_UNSPEC) {
|
if (sfd->howtoend == END_UNSPEC) {
|
||||||
fd->howtoend = END_SHUTDOWN_KILL;
|
sfd->howtoend = END_SHUTDOWN_KILL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this for parent, was after fork */
|
/* this for parent, was after fork */
|
||||||
fd->fd = sv[0];
|
sfd->fd = sv[0];
|
||||||
applyopts(fd->fd, popts, PH_FD);
|
applyopts(sfd, -1, popts, PH_FD);
|
||||||
|
/* end withfork, socketpair */
|
||||||
}
|
}
|
||||||
retropt_bool(*copts, OPT_STDERR, &withstderr);
|
retropt_bool(copts, OPT_STDERR, &withstderr);
|
||||||
|
|
||||||
xiosetchilddied(); /* set SIGCHLD handler */
|
xiosetchilddied(); /* set SIGCHLD handler */
|
||||||
|
|
||||||
|
@ -387,7 +397,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!withfork || pid == 0) { /* in single process, or in child */
|
if (!withfork || pid == 0) { /* in single process, or in child */
|
||||||
applyopts_optgroup(-1, *copts, PH_PRESOCKET, PH_PRESOCKET, GROUP_PROCESS);
|
applyopts_optgroup(sfd, -1, copts, GROUP_PROCESS);
|
||||||
if (withfork) {
|
if (withfork) {
|
||||||
Close(trigger[0]); /* in child: not needed here */
|
Close(trigger[0]); /* in child: not needed here */
|
||||||
/* The child should have default handling for SIGCHLD. */
|
/* The child should have default handling for SIGCHLD. */
|
||||||
|
@ -398,9 +408,9 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
|
|
||||||
#if HAVE_PTY
|
#if HAVE_PTY
|
||||||
if (usepty) {
|
if (usepty) {
|
||||||
applyopts_named(tn, *copts, PH_PREOPEN);
|
applyopts_named(tn, copts, PH_PREOPEN);
|
||||||
applyopts_named(tn, *copts, PH_EARLY);
|
applyopts_named(tn, copts, PH_EARLY);
|
||||||
applyopts_named(tn, *copts, PH_FD);
|
applyopts_named(tn, copts, PH_FD);
|
||||||
|
|
||||||
if (ttyfd < 0) {
|
if (ttyfd < 0) {
|
||||||
if ((ttyfd = Open(tn, O_RDWR|O_NOCTTY, 0620)) < 0) {
|
if ((ttyfd = Open(tn, O_RDWR|O_NOCTTY, 0620)) < 0) {
|
||||||
|
@ -427,7 +437,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* this for child, was after fork */
|
/* this for child, was after fork */
|
||||||
applyopts(ttyfd, *copts, PH_FD);
|
applyopts(NULL, ttyfd, copts, PH_FD);
|
||||||
|
|
||||||
Info1("opened pseudo terminal %s", tn);
|
Info1("opened pseudo terminal %s", tn);
|
||||||
Close(ptyfd);
|
Close(ptyfd);
|
||||||
|
@ -451,11 +461,11 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
}
|
}
|
||||||
if ((rw == XIO_RDONLY || fdi != ttyfd) &&
|
if ((rw == XIO_RDONLY || fdi != ttyfd) &&
|
||||||
(rw == XIO_WRONLY || fdo != ttyfd)) {
|
(rw == XIO_WRONLY || fdo != ttyfd)) {
|
||||||
applyopts_cloexec(ttyfd, *copts);
|
applyopts_cloexec(ttyfd, copts);
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts(ttyfd, *copts, PH_LATE);
|
applyopts(NULL, ttyfd, copts, PH_LATE);
|
||||||
applyopts(ttyfd, *copts, PH_LATE2);
|
applyopts(NULL, ttyfd, copts, PH_LATE2);
|
||||||
} else
|
} else
|
||||||
#endif /* HAVE_PTY */
|
#endif /* HAVE_PTY */
|
||||||
if (usepipes) {
|
if (usepipes) {
|
||||||
|
@ -492,8 +502,6 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
Close(rdpip[1]);
|
Close(rdpip[1]);
|
||||||
/*0 Info2("dup2(%d, %d)", rdpip[1], fdo);*/
|
|
||||||
/*0 applyopts_cloexec(fdo, *copts);*/
|
|
||||||
}
|
}
|
||||||
if (rw != XIO_RDONLY && wrpip[0] != fdi) {
|
if (rw != XIO_RDONLY && wrpip[0] != fdi) {
|
||||||
/* make sure that the internal diagnostic socket pair fds do not conflict
|
/* make sure that the internal diagnostic socket pair fds do not conflict
|
||||||
|
@ -504,15 +512,13 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
Close(wrpip[0]);
|
Close(wrpip[0]);
|
||||||
/*0 Info2("dup2(%d, %d)", wrpip[0], fdi);*/
|
|
||||||
/*0 applyopts_cloexec(wrpip[0], *copts);*/ /* option is already consumed! */
|
|
||||||
/* applyopts_cloexec(fdi, *copts);*/ /* option is already consumed! */
|
/* applyopts_cloexec(fdi, *copts);*/ /* option is already consumed! */
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts(fdi, *copts, PH_LATE);
|
applyopts(NULL, fdi, copts, PH_LATE);
|
||||||
applyopts(fdo, *copts, PH_LATE);
|
applyopts(NULL, fdo, copts, PH_LATE);
|
||||||
applyopts(fdi, *copts, PH_LATE2);
|
applyopts(NULL, fdi, copts, PH_LATE2);
|
||||||
applyopts(fdo, *copts, PH_LATE2);
|
applyopts(NULL, fdo, copts, PH_LATE2);
|
||||||
|
|
||||||
} else { /* socketpair */
|
} else { /* socketpair */
|
||||||
Close(sv[0]);
|
Close(sv[0]);
|
||||||
|
@ -535,12 +541,12 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
/*0 Info2("dup2(%d, %d)", sv[1], fdo);*/
|
/*0 Info2("dup2(%d, %d)", sv[1], fdo);*/
|
||||||
}
|
}
|
||||||
if (fdi != sv[1] && fdo != sv[1]) {
|
if (fdi != sv[1] && fdo != sv[1]) {
|
||||||
applyopts_cloexec(sv[1], *copts);
|
applyopts_cloexec(sv[1], copts);
|
||||||
Close(sv[1]);
|
Close(sv[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts(fdi, *copts, PH_LATE);
|
applyopts(NULL, fdi, copts, PH_LATE);
|
||||||
applyopts(fdi, *copts, PH_LATE2);
|
applyopts(NULL, fdi, copts, PH_LATE2);
|
||||||
}
|
}
|
||||||
if (withfork) {
|
if (withfork) {
|
||||||
Info("notifying parent that child process is ready");
|
Info("notifying parent that child process is ready");
|
||||||
|
@ -548,8 +554,8 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
}
|
}
|
||||||
} /* withfork */
|
} /* withfork */
|
||||||
else {
|
else {
|
||||||
applyopts(-1, *copts, PH_LATE);
|
applyopts(NULL, -1, copts, PH_LATE);
|
||||||
applyopts(-1, *copts, PH_LATE2);
|
applyopts(NULL, -1, copts, PH_LATE2);
|
||||||
}
|
}
|
||||||
_xioopen_setdelayeduser();
|
_xioopen_setdelayeduser();
|
||||||
if (withstderr) {
|
if (withstderr) {
|
||||||
|
@ -558,6 +564,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
*duptostderr = -1;
|
*duptostderr = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*optsp = copts;
|
||||||
return 0; /* indicate child process */
|
return 0; /* indicate child process */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,12 +572,6 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
Notice1("forked off child process "F_pid, pid);
|
Notice1("forked off child process "F_pid, pid);
|
||||||
Close(trigger[1]); /* in parent */
|
Close(trigger[1]); /* in parent */
|
||||||
|
|
||||||
#if 0
|
|
||||||
if ((popts = copyopts(*copts,
|
|
||||||
GROUP_FD|GROUP_TERMIOS|GROUP_FORK|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_FIFO)) == NULL)
|
|
||||||
return STAT_RETRYLATER;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_PTY
|
#if HAVE_PTY
|
||||||
if (usepty) {
|
if (usepty) {
|
||||||
# if 0
|
# if 0
|
||||||
|
@ -586,13 +587,12 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
} else {
|
} else {
|
||||||
Close(sv[1]);
|
Close(sv[1]);
|
||||||
}
|
}
|
||||||
fd->para.exec.pid = pid;
|
sfd->para.exec.pid = pid;
|
||||||
|
|
||||||
if (applyopts_single(fd, popts, PH_LATE) < 0) return -1;
|
if (applyopts_single(sfd, popts, PH_LATE) < 0) return -1;
|
||||||
applyopts_signal(fd, popts);
|
applyopts(sfd, -1, popts, PH_LATE);
|
||||||
applyopts(-1, popts, PH_LATE);
|
applyopts(sfd, -1, popts, PH_LATE2);
|
||||||
applyopts(-1, popts, PH_LATE2);
|
applyopts(sfd, -1, popts, PH_PASTEXEC);
|
||||||
applyopts(-1, popts, PH_PASTEXEC);
|
|
||||||
if ((numleft = leftopts(popts)) > 0) {
|
if ((numleft = leftopts(popts)) > 0) {
|
||||||
showleft(popts);
|
showleft(popts);
|
||||||
Error1("INTERNAL: %d option(s) remained unused", numleft);
|
Error1("INTERNAL: %d option(s) remained unused", numleft);
|
||||||
|
@ -607,6 +607,11 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
Info("child process notified parent that it is ready");
|
Info("child process notified parent that it is ready");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyopts(sfd, ptyfd, popts, PH_LATE);
|
||||||
|
if (applyopts_single(sfd, popts, PH_LATE) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*optsp = popts;
|
||||||
return pid; /* indicate parent (main) process */
|
return pid; /* indicate parent (main) process */
|
||||||
}
|
}
|
||||||
#endif /* WITH_EXEC || WITH_SYSTEM */
|
#endif /* WITH_EXEC || WITH_SYSTEM */
|
||||||
|
|
|
@ -114,7 +114,7 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
xfd->howtoend = END_SHUTDOWN;
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(xfd, 1, opts, PH_INIT);
|
||||||
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
|
|
||||||
|
@ -203,6 +203,8 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
xiofreeaddrinfo(themlist);
|
||||||
|
applyopts(xfd, -1, opts, PH_ALL);
|
||||||
|
|
||||||
if ((result = _xio_openlate(xfd, opts)) < 0)
|
if ((result = _xio_openlate(xfd, opts)) < 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
28
xio-pty.c
28
xio-pty.c
|
@ -30,6 +30,7 @@ const struct optdesc opt_pty_intervall = { "pty-interval", NULL, OPT_P
|
||||||
|
|
||||||
static int xioopen_pty(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3) {
|
static int xioopen_pty(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3) {
|
||||||
/* we expect the form: filename */
|
/* we expect the form: filename */
|
||||||
|
struct single *sfd = &xfd->stream;
|
||||||
int ptyfd = -1, ttyfd = -1;
|
int ptyfd = -1, ttyfd = -1;
|
||||||
#if defined(HAVE_DEV_PTMX) || defined(HAVE_DEV_PTC)
|
#if defined(HAVE_DEV_PTMX) || defined(HAVE_DEV_PTC)
|
||||||
bool useptmx = false; /* use /dev/ptmx or equivalent */
|
bool useptmx = false; /* use /dev/ptmx or equivalent */
|
||||||
|
@ -51,10 +52,10 @@ static int xioopen_pty(int argc, const char *argv[], struct opt *opts, int xiofl
|
||||||
Error2("%s: wrong number of parameters (%d instead of 0)", argv[0], argc-1);
|
Error2("%s: wrong number of parameters (%d instead of 0)", argv[0], argc-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
xfd->stream.howtoend = END_CLOSE;
|
sfd->howtoend = END_CLOSE;
|
||||||
|
|
||||||
if (applyopts_single(&xfd->stream, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
|
|
||||||
|
@ -88,10 +89,10 @@ static int xioopen_pty(int argc, const char *argv[], struct opt *opts, int xiofl
|
||||||
retropt_timespec(opts, OPT_PTY_INTERVALL, &pollintv);
|
retropt_timespec(opts, OPT_PTY_INTERVALL, &pollintv);
|
||||||
#endif /* HAVE_POLL */
|
#endif /* HAVE_POLL */
|
||||||
|
|
||||||
if (applyopts_single(&xfd->stream, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts2(-1, opts, PH_INIT, PH_EARLY);
|
applyopts2(sfd, -1, opts, PH_INIT, PH_EARLY);
|
||||||
|
|
||||||
applyopts(-1, opts, PH_PREBIGEN);
|
applyopts(sfd, -1, opts, PH_PREBIGEN);
|
||||||
|
|
||||||
#if defined(HAVE_DEV_PTMX)
|
#if defined(HAVE_DEV_PTMX)
|
||||||
# define PTMX "/dev/ptmx" /* Linux */
|
# define PTMX "/dev/ptmx" /* Linux */
|
||||||
|
@ -155,10 +156,10 @@ static int xioopen_pty(int argc, const char *argv[], struct opt *opts, int xiofl
|
||||||
ptyname, linkname, strerror(errno));
|
ptyname, linkname, strerror(errno));
|
||||||
}
|
}
|
||||||
if (opt_unlink_close) {
|
if (opt_unlink_close) {
|
||||||
if ((xfd->stream.unlink_close = strdup(linkname)) == NULL) {
|
if ((sfd->unlink_close = strdup(linkname)) == NULL) {
|
||||||
Error1("strdup(\"%s\"): out of memory", linkname);
|
Error1("strdup(\"%s\"): out of memory", linkname);
|
||||||
}
|
}
|
||||||
xfd->stream.opt_unlink_close = true;
|
sfd->opt_unlink_close = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,9 +167,9 @@ static int xioopen_pty(int argc, const char *argv[], struct opt *opts, int xiofl
|
||||||
applyopts_named(ptyname, opts, PH_FD);
|
applyopts_named(ptyname, opts, PH_FD);
|
||||||
|
|
||||||
applyopts_cloexec(ptyfd, opts);/*!*/
|
applyopts_cloexec(ptyfd, opts);/*!*/
|
||||||
xfd->stream.dtype = XIODATA_PTY;
|
sfd->dtype = XIODATA_PTY;
|
||||||
|
|
||||||
applyopts(ptyfd, opts, PH_FD);
|
applyopts(sfd, ptyfd, opts, PH_FD);
|
||||||
|
|
||||||
{
|
{
|
||||||
/* special handling of user-late etc.; with standard behaviour (up to
|
/* special handling of user-late etc.; with standard behaviour (up to
|
||||||
|
@ -196,9 +197,10 @@ static int xioopen_pty(int argc, const char *argv[], struct opt *opts, int xiofl
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xfd->stream.fd = ptyfd;
|
sfd->fd = ptyfd;
|
||||||
applyopts(ptyfd, opts, PH_LATE);
|
applyopts(sfd, -1, opts, PH_LATE);
|
||||||
if (applyopts_single(&xfd->stream, opts, PH_LATE) < 0) return -1;
|
if (applyopts_single(sfd, opts, PH_LATE) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
#if HAVE_POLL
|
#if HAVE_POLL
|
||||||
/* if you can and wish: */
|
/* if you can and wish: */
|
||||||
|
|
|
@ -118,7 +118,7 @@ int _xioopen_rawip_sendto(const char *hostname, const char *protname,
|
||||||
retropt_int(opts, OPT_PROTOCOL_FAMILY, pf);
|
retropt_int(opts, OPT_PROTOCOL_FAMILY, pf);
|
||||||
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(xfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
xfd->salen = sizeof(xfd->peersa);
|
xfd->salen = sizeof(xfd->peersa);
|
||||||
if ((result =
|
if ((result =
|
||||||
|
|
|
@ -40,6 +40,7 @@ const struct optdesc opt_noecho = { "noecho", NULL, OPT_NOECHO,
|
||||||
static int xioopen_readline(int argc, const char *argv[], struct opt *opts,
|
static int xioopen_readline(int argc, const char *argv[], struct opt *opts,
|
||||||
int xioflags, xiofile_t *xfd, groups_t groups,
|
int xioflags, xiofile_t *xfd, groups_t groups,
|
||||||
int dummy1, int dummy2, int dummy3) {
|
int dummy1, int dummy2, int dummy3) {
|
||||||
|
struct single *sfd = &xfd->stream;
|
||||||
int rw = (xioflags & XIO_ACCMODE);
|
int rw = (xioflags & XIO_ACCMODE);
|
||||||
char msgbuf[256], *cp = msgbuf;
|
char msgbuf[256], *cp = msgbuf;
|
||||||
bool noprompt = false;
|
bool noprompt = false;
|
||||||
|
@ -85,10 +86,10 @@ static int xioopen_readline(int argc, const char *argv[], struct opt *opts,
|
||||||
}
|
}
|
||||||
#endif /* WITH_TERMIOS */
|
#endif /* WITH_TERMIOS */
|
||||||
|
|
||||||
if (applyopts_single(&xfd->stream, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
applyopts2(xfd->stream.fd, opts, PH_INIT, PH_FD);
|
applyopts2(sfd, -1, opts, PH_INIT, PH_FD);
|
||||||
|
|
||||||
Using_history();
|
Using_history();
|
||||||
applyopts_offset(&xfd->stream, opts);
|
applyopts_offset(&xfd->stream, opts);
|
||||||
|
|
216
xio-socket.c
216
xio-socket.c
|
@ -167,32 +167,32 @@ const struct optdesc opt_so_peercred = { "so-peercred", "peercred", OPT_SO_PEERC
|
||||||
const struct optdesc opt_so_priority = { "so-priority", "priority", OPT_SO_PRIORITY, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_PRIORITY};
|
const struct optdesc opt_so_priority = { "so-priority", "priority", OPT_SO_PRIORITY, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_PRIORITY};
|
||||||
#endif
|
#endif
|
||||||
#ifdef SO_REUSEPORT /* AIX 4.3.3, BSD, HP-UX, Linux >=3.9 */
|
#ifdef SO_REUSEPORT /* AIX 4.3.3, BSD, HP-UX, Linux >=3.9 */
|
||||||
const struct optdesc opt_so_reuseport= { "so-reuseport","reuseport",OPT_SO_REUSEPORT,GROUP_SOCKET, PH_PREBIND, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_REUSEPORT };
|
const struct optdesc opt_so_reuseport = { "so-reuseport","reuseport",OPT_SO_REUSEPORT,GROUP_SOCKET, PH_PREBIND, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_REUSEPORT };
|
||||||
#endif /* defined(SO_REUSEPORT) */
|
#endif /* defined(SO_REUSEPORT) */
|
||||||
#ifdef SO_SECURITY_AUTHENTICATION
|
#ifdef SO_SECURITY_AUTHENTICATION
|
||||||
const struct optdesc opt_so_security_authentication={"so-security-authentication","securityauthentication",OPT_SO_SECURITY_AUTHENTICATION,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_SECURITY_AUTHENTICATION};
|
const struct optdesc opt_so_security_authentication={"so-security-authentication","securityauthentication",OPT_SO_SECURITY_AUTHENTICATION,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_SECURITY_AUTHENTICATION};
|
||||||
#endif
|
#endif
|
||||||
#ifdef SO_SECURITY_ENCRYPTION_NETWORK
|
#ifdef SO_SECURITY_ENCRYPTION_NETWORK
|
||||||
const struct optdesc opt_so_security_encryption_network={"so-security-encryption-network","securityencryptionnetwork",OPT_SO_SECURITY_ENCRYPTION_NETWORK,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_SECURITY_ENCRYPTION_NETWORK};
|
const struct optdesc opt_so_security_encryption_network= { "so-security-encryption-network","securityencryptionnetwork",OPT_SO_SECURITY_ENCRYPTION_NETWORK,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_SECURITY_ENCRYPTION_NETWORK};
|
||||||
#endif
|
#endif
|
||||||
#ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
|
#ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
|
||||||
const struct optdesc opt_so_security_encryption_transport={"so-security-encryption-transport","securityencryptiontransport",OPT_SO_SECURITY_ENCRYPTION_TRANSPORT,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_SECURITY_ENCRYPTION_TRANSPORT};
|
const struct optdesc opt_so_security_encryption_transport= { "so-security-encryption-transport","securityencryptiontransport",OPT_SO_SECURITY_ENCRYPTION_TRANSPORT,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_SECURITY_ENCRYPTION_TRANSPORT};
|
||||||
#endif
|
#endif
|
||||||
#ifdef SO_USE_IFBUFS
|
#ifdef SO_USE_IFBUFS
|
||||||
const struct optdesc opt_so_use_ifbufs={ "so-use-ifbufs","useifbufs",OPT_SO_USE_IFBUFS,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_USE_IFBUFS};
|
const struct optdesc opt_so_use_ifbufs= { "so-use-ifbufs","useifbufs",OPT_SO_USE_IFBUFS,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_USE_IFBUFS};
|
||||||
#endif /* SO_USE_IFBUFS */
|
#endif /* SO_USE_IFBUFS */
|
||||||
#ifdef SO_USELOOPBACK /* AIX433, Solaris, HP-UX */
|
#ifdef SO_USELOOPBACK /* AIX433, Solaris, HP-UX */
|
||||||
const struct optdesc opt_so_useloopback={"so-useloopback","useloopback",OPT_SO_USELOOPBACK,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT, SOL_SOCKET, SO_USELOOPBACK};
|
const struct optdesc opt_so_useloopback= { "so-useloopback","useloopback",OPT_SO_USELOOPBACK,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT, SOL_SOCKET, SO_USELOOPBACK};
|
||||||
#endif /* SO_USELOOPBACK */
|
#endif /* SO_USELOOPBACK */
|
||||||
#ifdef SO_DGRAM_ERRIND /* Solaris */
|
#ifdef SO_DGRAM_ERRIND /* Solaris */
|
||||||
const struct optdesc opt_so_dgram_errind={"so-dgram-errind","dgramerrind",OPT_SO_DGRAM_ERRIND,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_DGRAM_ERRIND};
|
const struct optdesc opt_so_dgram_errind= { "so-dgram-errind","dgramerrind",OPT_SO_DGRAM_ERRIND,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_DGRAM_ERRIND};
|
||||||
#endif /* SO_DGRAM_ERRIND */
|
#endif /* SO_DGRAM_ERRIND */
|
||||||
#ifdef SO_DONTLINGER /* Solaris */
|
#ifdef SO_DONTLINGER /* Solaris */
|
||||||
const struct optdesc opt_so_dontlinger = {"so-dontlinger", "dontlinger", OPT_SO_DONTLINGER, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_DONTLINGER };
|
const struct optdesc opt_so_dontlinger = { "so-dontlinger", "dontlinger", OPT_SO_DONTLINGER, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_DONTLINGER };
|
||||||
#endif
|
#endif
|
||||||
/* the SO_PROTOTYPE is OS defined on Solaris, HP-UX; we lend this for a more
|
/* the SO_PROTOTYPE is OS defined on Solaris, HP-UX; we lend this for a more
|
||||||
general purpose */
|
general purpose */
|
||||||
const struct optdesc opt_so_prototype = {"so-protocol", "protocol", OPT_SO_PROTOTYPE, GROUP_SOCKET,PH_SOCKET, TYPE_INT,OFUNC_SPEC, SOL_SOCKET,SO_PROTOCOL };
|
const struct optdesc opt_so_prototype = { "so-protocol", "protocol", OPT_SO_PROTOTYPE, GROUP_SOCKET,PH_SOCKET, TYPE_INT,OFUNC_SPEC, SOL_SOCKET,SO_PROTOCOL };
|
||||||
#ifdef FIOSETOWN
|
#ifdef FIOSETOWN
|
||||||
const struct optdesc opt_fiosetown = { "fiosetown", NULL, OPT_FIOSETOWN, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_IOCTL, FIOSETOWN };
|
const struct optdesc opt_fiosetown = { "fiosetown", NULL, OPT_FIOSETOWN, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_IOCTL, FIOSETOWN };
|
||||||
#endif
|
#endif
|
||||||
|
@ -219,7 +219,7 @@ static
|
||||||
int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts,
|
int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
int xioflags, xiofile_t *xxfd, groups_t groups,
|
int xioflags, xiofile_t *xxfd, groups_t groups,
|
||||||
int dummy1, int dummy2, int dummy3) {
|
int dummy1, int dummy2, int dummy3) {
|
||||||
struct single *xfd = &xxfd->stream;
|
struct single *sfd = &xxfd->stream;
|
||||||
const char *pfname = argv[1];
|
const char *pfname = argv[1];
|
||||||
const char *protname = argv[2];
|
const char *protname = argv[2];
|
||||||
const char *address = argv[3];
|
const char *address = argv[3];
|
||||||
|
@ -251,11 +251,12 @@ int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
/*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/
|
/*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
sfd->howtoend = END_SHUTDOWN;
|
||||||
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0)
|
||||||
applyopts(-1, opts, PH_INIT);
|
return -1;
|
||||||
applyopts(-1, opts, PH_EARLY);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
|
applyopts(sfd, -1, opts, PH_EARLY);
|
||||||
|
|
||||||
themsize = 0;
|
themsize = 0;
|
||||||
if ((result =
|
if ((result =
|
||||||
|
@ -272,24 +273,24 @@ int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
#endif
|
#endif
|
||||||
sizeof(them.soa.sa_family);
|
sizeof(them.soa.sa_family);
|
||||||
|
|
||||||
xfd->dtype = XIOREAD_STREAM|XIOWRITE_STREAM;
|
sfd->dtype = XIOREAD_STREAM|XIOWRITE_STREAM;
|
||||||
|
|
||||||
socket_init(0, &us);
|
socket_init(0, &us);
|
||||||
if (retropt_bind(opts, 0 /*pf*/, socktype, proto, (struct sockaddr *)&us, &uslen, 3,
|
if (retropt_bind(opts, 0 /*pf*/, socktype, proto, (struct sockaddr *)&us, &uslen, 3,
|
||||||
xfd->para.socket.ip.ai_flags)
|
sfd->para.socket.ip.ai_flags)
|
||||||
!= STAT_NOACTION) {
|
!= STAT_NOACTION) {
|
||||||
needbind = true;
|
needbind = true;
|
||||||
us.soa.sa_family = pf;
|
us.soa.sa_family = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result =
|
if ((result =
|
||||||
xioopen_connect(xfd,
|
xioopen_connect(sfd,
|
||||||
needbind?&us:NULL, uslen,
|
needbind?&us:NULL, uslen,
|
||||||
(struct sockaddr *)&them, themlen,
|
(struct sockaddr *)&them, themlen,
|
||||||
opts, pf, socktype, proto, false)) != 0) {
|
opts, pf, socktype, proto, false)) != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if ((result = _xio_openlate(xfd, opts)) < 0) {
|
if ((result = _xio_openlate(sfd, opts)) < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return STAT_OK;
|
return STAT_OK;
|
||||||
|
@ -300,7 +301,7 @@ static
|
||||||
int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts,
|
int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
int xioflags, xiofile_t *xxfd, groups_t groups,
|
int xioflags, xiofile_t *xxfd, groups_t groups,
|
||||||
int dummy1, int dummy2, int dummy3) {
|
int dummy1, int dummy2, int dummy3) {
|
||||||
struct single *xfd = &xxfd->stream;
|
struct single *sfd = &xxfd->stream;
|
||||||
const char *pfname = argv[1];
|
const char *pfname = argv[1];
|
||||||
const char *protname = argv[2];
|
const char *protname = argv[2];
|
||||||
const char *usname = argv[3];
|
const char *usname = argv[3];
|
||||||
|
@ -331,7 +332,7 @@ int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
/*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/
|
/*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
sfd->howtoend = END_SHUTDOWN;
|
||||||
|
|
||||||
socket_init(0, &us);
|
socket_init(0, &us);
|
||||||
ussize = 0;
|
ussize = 0;
|
||||||
|
@ -349,14 +350,15 @@ int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
;
|
;
|
||||||
us.soa.sa_family = pf;
|
us.soa.sa_family = pf;
|
||||||
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0)
|
||||||
applyopts(-1, opts, PH_INIT);
|
return -1;
|
||||||
applyopts(-1, opts, PH_EARLY);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
|
applyopts(sfd, -1, opts, PH_EARLY);
|
||||||
|
|
||||||
opts0 = copyopts(opts, GROUP_ALL);
|
opts0 = copyopts(opts, GROUP_ALL);
|
||||||
|
|
||||||
if ((result =
|
if ((result =
|
||||||
xioopen_listen(xfd, xioflags,
|
xioopen_listen(sfd, xioflags,
|
||||||
&us.soa, uslen,
|
&us.soa, uslen,
|
||||||
opts, opts0, 0/*instead of pf*/, socktype, proto))
|
opts, opts0, 0/*instead of pf*/, socktype, proto))
|
||||||
!= STAT_OK)
|
!= STAT_OK)
|
||||||
|
@ -392,7 +394,7 @@ int _xioopen_socket_sendto(const char *pfname, const char *type,
|
||||||
const char *protname, const char *address,
|
const char *protname, const char *address,
|
||||||
struct opt *opts, int xioflags, xiofile_t *xxfd,
|
struct opt *opts, int xioflags, xiofile_t *xxfd,
|
||||||
groups_t groups) {
|
groups_t groups) {
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
xiosingle_t *sfd = &xxfd->stream;
|
||||||
char *garbage;
|
char *garbage;
|
||||||
union sockaddr_union us = {{0}};
|
union sockaddr_union us = {{0}};
|
||||||
socklen_t uslen = 0; size_t ussize;
|
socklen_t uslen = 0; size_t ussize;
|
||||||
|
@ -422,37 +424,37 @@ int _xioopen_socket_sendto(const char *pfname, const char *type,
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
/*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/
|
/*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
sfd->howtoend = END_SHUTDOWN;
|
||||||
|
|
||||||
xfd->peersa.soa.sa_family = pf;
|
sfd->peersa.soa.sa_family = pf;
|
||||||
themsize = 0;
|
themsize = 0;
|
||||||
if ((result =
|
if ((result =
|
||||||
dalan(address, (uint8_t *)&xfd->peersa.soa.sa_data, &themsize,
|
dalan(address, (uint8_t *)&sfd->peersa.soa.sa_data, &themsize,
|
||||||
sizeof(xfd->peersa), 'i'))
|
sizeof(sfd->peersa), 'i'))
|
||||||
< 0) {
|
< 0) {
|
||||||
Error1("data too long: \"%s\"", address);
|
Error1("data too long: \"%s\"", address);
|
||||||
} else if (result > 0) {
|
} else if (result > 0) {
|
||||||
Error1("syntax error in \"%s\"", address);
|
Error1("syntax error in \"%s\"", address);
|
||||||
}
|
}
|
||||||
xfd->salen = themsize + sizeof(sa_family_t)
|
sfd->salen = themsize + sizeof(sa_family_t)
|
||||||
#if HAVE_STRUCT_SOCKADDR_SALEN
|
#if HAVE_STRUCT_SOCKADDR_SALEN
|
||||||
+ sizeof(xfd->peersa.soa.sa_len)
|
+ sizeof(sfd->peersa.soa.sa_len)
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
#if HAVE_STRUCT_SOCKADDR_SALEN
|
#if HAVE_STRUCT_SOCKADDR_SALEN
|
||||||
xfd->peersa.soa.sa_len =
|
sfd->peersa.soa.sa_len =
|
||||||
sizeof(xfd->peersa.soa.sa_len) + sizeof(xfd->peersa.soa.sa_family) +
|
sizeof(sfd->peersa.soa.sa_len) + sizeof(sfd->peersa.soa.sa_family) +
|
||||||
themsize;
|
themsize;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
if (pf == PF_UNSPEC) {
|
if (pf == PF_UNSPEC) {
|
||||||
pf = xfd->peersa.soa.sa_family;
|
pf = sfd->peersa.soa.sa_family;
|
||||||
}
|
}
|
||||||
|
|
||||||
xfd->dtype = XIODATA_RECVFROM;
|
sfd->dtype = XIODATA_RECVFROM;
|
||||||
|
|
||||||
if (retropt_string(opts, OPT_BIND, &bindstring) == 0) {
|
if (retropt_string(opts, OPT_BIND, &bindstring) == 0) {
|
||||||
ussize = 0;
|
ussize = 0;
|
||||||
|
@ -474,7 +476,7 @@ int _xioopen_socket_sendto(const char *pfname, const char *type,
|
||||||
|
|
||||||
return
|
return
|
||||||
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
||||||
opts, xioflags, xfd, groups, pf, socktype, proto, 0);
|
opts, xioflags, sfd, groups, pf, socktype, proto, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -773,7 +775,7 @@ int xiogetpacketinfo(struct single *sfd, int fd)
|
||||||
Does not fork, does not retry.
|
Does not fork, does not retry.
|
||||||
returns 0 on success.
|
returns 0 on success.
|
||||||
*/
|
*/
|
||||||
int _xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen,
|
int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
|
||||||
struct sockaddr *them, size_t themlen,
|
struct sockaddr *them, size_t themlen,
|
||||||
struct opt *opts, int pf, int socktype, int protocol,
|
struct opt *opts, int pf, int socktype, int protocol,
|
||||||
bool alt, int level) {
|
bool alt, int level) {
|
||||||
|
@ -790,40 +792,40 @@ int _xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((xfd->fd = xiosocket(opts, pf, socktype, protocol, level)) < 0) {
|
if ((sfd->fd = xiosocket(opts, pf, socktype, protocol, level)) < 0) {
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts_offset(xfd, opts);
|
applyopts_offset(sfd, opts);
|
||||||
applyopts(xfd->fd, opts, PH_PASTSOCKET);
|
applyopts(sfd, -1, opts, PH_PASTSOCKET);
|
||||||
applyopts(xfd->fd, opts, PH_FD);
|
applyopts(sfd, -1, opts, PH_FD);
|
||||||
|
|
||||||
applyopts_cloexec(xfd->fd, opts);
|
applyopts_cloexec(sfd->fd, opts);
|
||||||
|
|
||||||
if (xiobind(xfd, us, uslen, opts, pf, alt, level) < 0) {
|
if (xiobind(sfd, us, uslen, opts, pf, alt, level) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts(xfd->fd, opts, PH_CONNECT);
|
applyopts(sfd, -1, opts, PH_CONNECT);
|
||||||
|
|
||||||
if (xfd->para.socket.connect_timeout.tv_sec != 0 ||
|
if (sfd->para.socket.connect_timeout.tv_sec != 0 ||
|
||||||
xfd->para.socket.connect_timeout.tv_usec != 0) {
|
sfd->para.socket.connect_timeout.tv_usec != 0) {
|
||||||
fcntl_flags = Fcntl(xfd->fd, F_GETFL);
|
fcntl_flags = Fcntl(sfd->fd, F_GETFL);
|
||||||
Fcntl_l(xfd->fd, F_SETFL, fcntl_flags|O_NONBLOCK);
|
Fcntl_l(sfd->fd, F_SETFL, fcntl_flags|O_NONBLOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = Connect(xfd->fd, them, themlen);
|
result = Connect(sfd->fd, them, themlen);
|
||||||
_errno = errno;
|
_errno = errno;
|
||||||
la.soa.sa_family = them->sa_family; lalen = sizeof(la);
|
la.soa.sa_family = them->sa_family; lalen = sizeof(la);
|
||||||
if (Getsockname(xfd->fd, &la.soa, &lalen) < 0) {
|
if (Getsockname(sfd->fd, &la.soa, &lalen) < 0) {
|
||||||
Msg4(level-1, "getsockname(%d, %p, {%d}): %s",
|
Msg4(level-1, "getsockname(%d, %p, {%d}): %s",
|
||||||
xfd->fd, &la.soa, lalen, strerror(errno));
|
sfd->fd, &la.soa, lalen, strerror(errno));
|
||||||
}
|
}
|
||||||
errno = _errno;
|
errno = _errno;
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
if (errno == EINPROGRESS) {
|
if (errno == EINPROGRESS) {
|
||||||
if (xfd->para.socket.connect_timeout.tv_sec != 0 ||
|
if (sfd->para.socket.connect_timeout.tv_sec != 0 ||
|
||||||
xfd->para.socket.connect_timeout.tv_usec != 0) {
|
sfd->para.socket.connect_timeout.tv_usec != 0) {
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
struct pollfd writefd;
|
struct pollfd writefd;
|
||||||
int err;
|
int err;
|
||||||
|
@ -831,62 +833,62 @@ int _xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen,
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
Info4("connect(%d, %s, "F_Zd"): %s",
|
Info4("connect(%d, %s, "F_Zd"): %s",
|
||||||
xfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
|
sfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
|
||||||
themlen, strerror(errno));
|
themlen, strerror(errno));
|
||||||
timeout = xfd->para.socket.connect_timeout;
|
timeout = sfd->para.socket.connect_timeout;
|
||||||
writefd.fd = xfd->fd;
|
writefd.fd = sfd->fd;
|
||||||
writefd.events = (POLLOUT|POLLERR);
|
writefd.events = (POLLOUT|POLLERR);
|
||||||
result = xiopoll(&writefd, 1, &timeout);
|
result = xiopoll(&writefd, 1, &timeout);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
Msg4(level, "xiopoll({%d,POLLOUT|POLLERR},,{"F_tv_sec"."F_tv_usec"): %s",
|
Msg4(level, "xiopoll({%d,POLLOUT|POLLERR},,{"F_tv_sec"."F_tv_usec"): %s",
|
||||||
xfd->fd, timeout.tv_sec, timeout.tv_usec, strerror(errno));
|
sfd->fd, timeout.tv_sec, timeout.tv_usec, strerror(errno));
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
Msg2(level, "connecting to %s: %s",
|
Msg2(level, "connecting to %s: %s",
|
||||||
sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
|
sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
|
||||||
strerror(ETIMEDOUT));
|
strerror(ETIMEDOUT));
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
if (writefd.revents & POLLERR) {
|
if (writefd.revents & POLLERR) {
|
||||||
#if 0
|
#if 0
|
||||||
unsigned char dummy[1];
|
unsigned char dummy[1];
|
||||||
Read(xfd->fd, &dummy, 1); /* get error message */
|
Read(sfd->fd, &dummy, 1); /* get error message */
|
||||||
Msg2(level, "connecting to %s: %s",
|
Msg2(level, "connecting to %s: %s",
|
||||||
sockaddr_info(them, infobuff, sizeof(infobuff)),
|
sockaddr_info(them, infobuff, sizeof(infobuff)),
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
#else
|
#else
|
||||||
Connect(xfd->fd, them, themlen); /* get error message */
|
Connect(sfd->fd, them, themlen); /* get error message */
|
||||||
Msg4(level, "connect(%d, %s, "F_Zd"): %s",
|
Msg4(level, "connect(%d, %s, "F_Zd"): %s",
|
||||||
xfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
|
sfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
|
||||||
themlen, strerror(errno));
|
themlen, strerror(errno));
|
||||||
#endif
|
#endif
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
/* otherwise OK or network error */
|
/* otherwise OK or network error */
|
||||||
result = Getsockopt(xfd->fd, SOL_SOCKET, SO_ERROR, &err, &errlen);
|
result = Getsockopt(sfd->fd, SOL_SOCKET, SO_ERROR, &err, &errlen);
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
Msg2(level, "getsockopt(%d, SOL_SOCKET, SO_ERROR, ...): %s",
|
Msg2(level, "getsockopt(%d, SOL_SOCKET, SO_ERROR, ...): %s",
|
||||||
xfd->fd, strerror(err));
|
sfd->fd, strerror(err));
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
Debug2("getsockopt(%d, SOL_SOCKET, SO_ERROR, { %d }) -> 0",
|
Debug2("getsockopt(%d, SOL_SOCKET, SO_ERROR, { %d }) -> 0",
|
||||||
xfd->fd, err);
|
sfd->fd, err);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
Msg4(level, "connect(%d, %s, "F_Zd"): %s",
|
Msg4(level, "connect(%d, %s, "F_Zd"): %s",
|
||||||
xfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
|
sfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
|
||||||
themlen, strerror(err));
|
themlen, strerror(err));
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
Fcntl_l(xfd->fd, F_SETFL, fcntl_flags);
|
Fcntl_l(sfd->fd, F_SETFL, fcntl_flags);
|
||||||
} else {
|
} else {
|
||||||
Warn4("connect(%d, %s, "F_Zd"): %s",
|
Warn4("connect(%d, %s, "F_Zd"): %s",
|
||||||
xfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
|
sfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
|
||||||
themlen, strerror(errno));
|
themlen, strerror(errno));
|
||||||
}
|
}
|
||||||
} else if (pf == PF_UNIX) {
|
} else if (pf == PF_UNIX) {
|
||||||
|
@ -896,21 +898,21 @@ int _xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen,
|
||||||
*/
|
*/
|
||||||
int _errno = errno;
|
int _errno = errno;
|
||||||
Info4("connect(%d, %s, "F_Zd"): %s",
|
Info4("connect(%d, %s, "F_Zd"): %s",
|
||||||
xfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
|
sfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
|
||||||
themlen, strerror(errno));
|
themlen, strerror(errno));
|
||||||
/* caller must handle this condition */
|
/* caller must handle this condition */
|
||||||
Close(xfd->fd); xfd->fd = -1;
|
Close(sfd->fd); sfd->fd = -1;
|
||||||
errno = _errno;
|
errno = _errno;
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
} else {
|
} else {
|
||||||
/* try to find details about error, especially from ICMP */
|
/* try to find details about error, especially from ICMP */
|
||||||
xiogetpacketinfo(xfd, xfd->fd);
|
xiogetpacketinfo(sfd, sfd->fd);
|
||||||
|
|
||||||
/* continue mainstream */
|
/* continue mainstream */
|
||||||
Msg4(level, "connect(%d, %s, "F_Zd"): %s",
|
Msg4(level, "connect(%d, %s, "F_Zd"): %s",
|
||||||
xfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
|
sfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
|
||||||
themlen, strerror(errno));
|
themlen, strerror(errno));
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
} else { /* result >= 0 */
|
} else { /* result >= 0 */
|
||||||
|
@ -918,14 +920,14 @@ int _xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen,
|
||||||
sockaddr_info(&la.soa, themlen, infobuff, sizeof(infobuff)));
|
sockaddr_info(&la.soa, themlen, infobuff, sizeof(infobuff)));
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts_fchown(xfd->fd, opts); /* OPT_USER, OPT_GROUP */
|
applyopts_fchown(sfd->fd, opts); /* OPT_USER, OPT_GROUP */
|
||||||
applyopts(xfd->fd, opts, PH_CONNECTED);
|
applyopts(sfd, -1, opts, PH_CONNECTED);
|
||||||
#if WITH_UNIX
|
#if WITH_UNIX
|
||||||
if (pf == PF_UNIX && us != NULL) {
|
if (pf == PF_UNIX && us != NULL) {
|
||||||
applyopts_named(us->un.sun_path, opts, PH_LATE);
|
applyopts_named(us->un.sun_path, opts, PH_LATE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
applyopts(xfd->fd, opts, PH_LATE);
|
applyopts(sfd, -1, opts, PH_LATE);
|
||||||
|
|
||||||
return STAT_OK;
|
return STAT_OK;
|
||||||
}
|
}
|
||||||
|
@ -1043,7 +1045,7 @@ int xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen,
|
||||||
int _xioopen_dgram_sendto(/* them is already in xfd->peersa */
|
int _xioopen_dgram_sendto(/* them is already in xfd->peersa */
|
||||||
union sockaddr_union *us, socklen_t uslen,
|
union sockaddr_union *us, socklen_t uslen,
|
||||||
struct opt *opts,
|
struct opt *opts,
|
||||||
int xioflags, xiosingle_t *xfd, groups_t groups,
|
int xioflags, xiosingle_t *sfd, groups_t groups,
|
||||||
int pf, int socktype, int ipproto, bool alt) {
|
int pf, int socktype, int ipproto, bool alt) {
|
||||||
int level = E_ERROR;
|
int level = E_ERROR;
|
||||||
union sockaddr_union la; socklen_t lalen = sizeof(la);
|
union sockaddr_union la; socklen_t lalen = sizeof(la);
|
||||||
|
@ -1055,39 +1057,39 @@ int _xioopen_dgram_sendto(/* them is already in xfd->peersa */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((xfd->fd = xiosocket(opts, pf, socktype, ipproto, level)) < 0) {
|
if ((sfd->fd = xiosocket(opts, pf, socktype, ipproto, level)) < 0) {
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts_offset(xfd, opts);
|
applyopts_offset(sfd, opts);
|
||||||
applyopts_single(xfd, opts, PH_PASTSOCKET);
|
applyopts_single(sfd, opts, PH_PASTSOCKET);
|
||||||
applyopts(xfd->fd, opts, PH_PASTSOCKET);
|
applyopts(sfd, -1, opts, PH_PASTSOCKET);
|
||||||
applyopts_single(xfd, opts, PH_FD);
|
applyopts_single(sfd, opts, PH_FD);
|
||||||
applyopts(xfd->fd, opts, PH_FD);
|
applyopts(sfd, -1, opts, PH_FD);
|
||||||
|
|
||||||
applyopts_cloexec(xfd->fd, opts);
|
applyopts_cloexec(sfd->fd, opts);
|
||||||
|
|
||||||
if (xiobind(xfd, us, uslen, opts, pf, alt, level) < 0) {
|
if (xiobind(sfd, us, uslen, opts, pf, alt, level) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*applyopts(xfd->fd, opts, PH_CONNECT);*/
|
/*applyopts(sfd, -1, opts, PH_CONNECT);*/
|
||||||
|
|
||||||
if (Getsockname(xfd->fd, &la.soa, &lalen) < 0) {
|
if (Getsockname(sfd->fd, &la.soa, &lalen) < 0) {
|
||||||
Warn4("getsockname(%d, %p, {%d}): %s",
|
Warn4("getsockname(%d, %p, {%d}): %s",
|
||||||
xfd->fd, &la.soa, lalen, strerror(errno));
|
sfd->fd, &la.soa, lalen, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts_fchown(xfd->fd, opts);
|
applyopts_fchown(sfd->fd, opts);
|
||||||
applyopts(xfd->fd, opts, PH_CONNECTED);
|
applyopts(sfd, -1, opts, PH_CONNECTED);
|
||||||
#if WITH_UNIX
|
#if WITH_UNIX
|
||||||
if (pf == PF_UNIX && us != NULL) {
|
if (pf == PF_UNIX && us != NULL) {
|
||||||
applyopts_named(us->un.sun_path, opts, PH_LATE);
|
applyopts_named(us->un.sun_path, opts, PH_LATE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/*0 applyopts(xfd->fd, opts, PH_LATE); */
|
/*0 applyopts(sfd, -1, opts, PH_LATE); */
|
||||||
|
|
||||||
/* xfd->dtype = DATA_RECVFROM; *//* no, the caller must set this (ev _SKIPIP) */
|
/* sfd->dtype = DATA_RECVFROM; *//* no, the caller must set this (ev _SKIPIP) */
|
||||||
Notice1("successfully prepared local socket %s",
|
Notice1("successfully prepared local socket %s",
|
||||||
sockaddr_info(&la.soa, lalen, infobuff, sizeof(infobuff)));
|
sockaddr_info(&la.soa, lalen, infobuff, sizeof(infobuff)));
|
||||||
|
|
||||||
|
@ -1150,8 +1152,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts_single(xfd, opts, PH_PASTSOCKET);
|
applyopts(xfd, -1, opts, PH_PASTSOCKET);
|
||||||
applyopts(xfd->fd, opts, PH_PASTSOCKET);
|
|
||||||
|
|
||||||
applyopts_cloexec(xfd->fd, opts);
|
applyopts_cloexec(xfd->fd, opts);
|
||||||
|
|
||||||
|
@ -1160,12 +1161,11 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts(xfd->fd, opts, PH_PASTBIND);
|
applyopts(xfd, -1, opts, PH_PASTBIND);
|
||||||
|
|
||||||
#if WITH_UNIX
|
#if WITH_UNIX
|
||||||
if (pf == AF_UNIX && us != NULL) {
|
if (pf == AF_UNIX && us != NULL) {
|
||||||
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_FD);
|
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_FD);
|
||||||
/*applyopts_early(((struct sockaddr_un *)us)->sun_path, opts);*/
|
|
||||||
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_EARLY);
|
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_EARLY);
|
||||||
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_PREOPEN);
|
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_PREOPEN);
|
||||||
}
|
}
|
||||||
|
@ -1283,9 +1283,9 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
|
||||||
/*xiosetsockaddrenv("SOCK", la, lalen, proto);*/
|
/*xiosetsockaddrenv("SOCK", la, lalen, proto);*/
|
||||||
xiosetsockaddrenv("PEER", pa, palen, proto);
|
xiosetsockaddrenv("PEER", pa, palen, proto);
|
||||||
|
|
||||||
applyopts(xfd->fd, opts, PH_FD);
|
applyopts(xfd, -1, opts, PH_FD);
|
||||||
|
|
||||||
applyopts(xfd->fd, opts, PH_CONNECTED);
|
applyopts(xfd, -1, opts, PH_CONNECTED);
|
||||||
|
|
||||||
xfd->peersa = *(union sockaddr_union *)pa;
|
xfd->peersa = *(union sockaddr_union *)pa;
|
||||||
xfd->salen = palen;
|
xfd->salen = palen;
|
||||||
|
@ -1357,8 +1357,7 @@ int _xioopen_dgram_recv(struct single *xfd, int xioflags,
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts_single(xfd, opts, PH_PASTSOCKET);
|
applyopts(xfd, -1, opts, PH_PASTSOCKET);
|
||||||
applyopts(xfd->fd, opts, PH_PASTSOCKET);
|
|
||||||
|
|
||||||
applyopts_cloexec(xfd->fd, opts);
|
applyopts_cloexec(xfd->fd, opts);
|
||||||
|
|
||||||
|
@ -1369,7 +1368,6 @@ int _xioopen_dgram_recv(struct single *xfd, int xioflags,
|
||||||
#if WITH_UNIX
|
#if WITH_UNIX
|
||||||
if (pf == AF_UNIX && us != NULL) {
|
if (pf == AF_UNIX && us != NULL) {
|
||||||
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_FD);
|
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_FD);
|
||||||
/*applyopts_early(((struct sockaddr_un *)us)->sun_path, opts);*/
|
|
||||||
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_EARLY);
|
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_EARLY);
|
||||||
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_PREOPEN);
|
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_PREOPEN);
|
||||||
}
|
}
|
||||||
|
@ -2023,7 +2021,7 @@ xiosocket(struct opt *opts, int pf, int socktype, int proto, int msglevel) {
|
||||||
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
retropt_int(opts, OPT_SO_PROTOTYPE, &proto);
|
retropt_int(opts, OPT_SO_PROTOTYPE, &proto);
|
||||||
applyopts(-1, opts, PH_PRESOCKET);
|
applyopts(NULL, -1, opts, PH_PRESOCKET);
|
||||||
result = Socket(pf, socktype, proto);
|
result = Socket(pf, socktype, proto);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
int _errno = errno;
|
int _errno = errno;
|
||||||
|
@ -2070,8 +2068,8 @@ int xiobind(
|
||||||
applyopts_named(us->un.sun_path, opts, PH_PREOPEN);
|
applyopts_named(us->un.sun_path, opts, PH_PREOPEN);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
applyopts(xfd->fd, opts, PH_PREBIND);
|
applyopts(xfd, xfd->fd, opts, PH_PREBIND);
|
||||||
applyopts(xfd->fd, opts, PH_BIND);
|
applyopts(xfd, xfd->fd, opts, PH_BIND);
|
||||||
#if WITH_TCP || WITH_UDP
|
#if WITH_TCP || WITH_UDP
|
||||||
if (alt) {
|
if (alt) {
|
||||||
union sockaddr_union sin, *sinp;
|
union sockaddr_union sin, *sinp;
|
||||||
|
@ -2170,7 +2168,7 @@ int xiobind(
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
applyopts(xfd->fd, opts, PH_PASTBIND);
|
applyopts(xfd, -1, opts, PH_PASTBIND);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ static int xioopen_socketpair(int argc, const char *argv[], struct opt *opts, in
|
||||||
const struct addrdesc xioaddr_socketpair = { "SOCKETPAIR", 3, xioopen_socketpair, GROUP_FD|GROUP_SOCKET, 0, 0, 0 HELP(":<filename>") };
|
const struct addrdesc xioaddr_socketpair = { "SOCKETPAIR", 3, xioopen_socketpair, GROUP_FD|GROUP_SOCKET, 0, 0, 0 HELP(":<filename>") };
|
||||||
|
|
||||||
|
|
||||||
/* open a socketpair */
|
/* Open a socketpair */
|
||||||
static int xioopen_socketpair(
|
static int xioopen_socketpair(
|
||||||
int argc,
|
int argc,
|
||||||
const char *argv[],
|
const char *argv[],
|
||||||
|
@ -32,7 +32,7 @@ static int xioopen_socketpair(
|
||||||
int dummy2,
|
int dummy2,
|
||||||
int dummy3)
|
int dummy3)
|
||||||
{
|
{
|
||||||
struct single *sfd;
|
struct single *sfd = &xfd->stream;
|
||||||
struct opt *opts2;
|
struct opt *opts2;
|
||||||
int pf = PF_UNIX;
|
int pf = PF_UNIX;
|
||||||
int protocol = 0;
|
int protocol = 0;
|
||||||
|
@ -44,10 +44,9 @@ static int xioopen_socketpair(
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
|
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
sfd = &xfd->stream;
|
|
||||||
sfd->para.bipipe.socktype = SOCK_DGRAM;
|
sfd->para.bipipe.socktype = SOCK_DGRAM;
|
||||||
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
retropt_int(opts, OPT_PROTOCOL_FAMILY, &pf);
|
retropt_int(opts, OPT_PROTOCOL_FAMILY, &pf);
|
||||||
retropt_int(opts, OPT_SO_TYPE, &sfd->para.bipipe.socktype);
|
retropt_int(opts, OPT_SO_TYPE, &sfd->para.bipipe.socktype);
|
||||||
retropt_int(opts, OPT_SO_PROTOTYPE, &protocol);
|
retropt_int(opts, OPT_SO_PROTOTYPE, &protocol);
|
||||||
|
@ -78,7 +77,7 @@ static int xioopen_socketpair(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* apply options to first FD */
|
/* apply options to first FD */
|
||||||
if ((result = applyopts(sfd->fd, opts, PH_ALL)) < 0) {
|
if ((result = applyopts(sfd, -1, opts, PH_ALL)) < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if ((result = applyopts_single(sfd, opts, PH_ALL)) < 0) {
|
if ((result = applyopts_single(sfd, opts, PH_ALL)) < 0) {
|
||||||
|
@ -86,10 +85,8 @@ static int xioopen_socketpair(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* apply options to second FD */
|
/* apply options to second FD */
|
||||||
if ((result = applyopts(sfd->para.bipipe.fdout, opts2, PH_ALL)) < 0)
|
if (applyopts(sfd, sfd->para.bipipe.fdout, opts2, PH_ALL) < 0)
|
||||||
{
|
return -1;
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((numleft = leftopts(opts)) > 0) {
|
if ((numleft = leftopts(opts)) > 0) {
|
||||||
Error1("%d option(s) could not be used", numleft);
|
Error1("%d option(s) could not be used", numleft);
|
||||||
|
|
|
@ -76,7 +76,7 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
xfd->howtoend = END_SHUTDOWN;
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(xfd, 1, opts, PH_INIT);
|
||||||
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
|
|
||||||
|
@ -180,6 +180,8 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts
|
||||||
xiofreeaddrinfo(themlist);
|
xiofreeaddrinfo(themlist);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
xiofreeaddrinfo(themlist);
|
||||||
|
applyopts(xfd, -1, opts, PH_ALL);
|
||||||
|
|
||||||
if ((result = _xio_openlate(xfd, opts)) < 0)
|
if ((result = _xio_openlate(xfd, opts)) < 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -539,7 +539,7 @@ static int xioopen_socks5(
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
xfd->howtoend = END_SHUTDOWN;
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(xfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
retropt_bool(opts, OPT_FORK, &dofork);
|
retropt_bool(opts, OPT_FORK, &dofork);
|
||||||
|
@ -594,7 +594,7 @@ static int xioopen_socks5(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xiofreeaddrinfo(themlist);
|
xiofreeaddrinfo(themlist);
|
||||||
applyopts(xfd->fd, opts, PH_ALL);
|
applyopts(xfd, -1, opts, PH_ALL);
|
||||||
|
|
||||||
if ((result = _xio_openlate(xfd, opts)) < 0)
|
if ((result = _xio_openlate(xfd, opts)) < 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
12
xio-stdio.c
12
xio-stdio.c
|
@ -89,16 +89,16 @@ int xioopen_stdio_bi(xiofile_t *sock) {
|
||||||
sock->dual.stream[1]->opts, PH_INIT)
|
sock->dual.stream[1]->opts, PH_INIT)
|
||||||
< 0)
|
< 0)
|
||||||
return -1;
|
return -1;
|
||||||
applyopts(-1, sock->dual.stream[0]->opts, PH_INIT);
|
applyopts(sock->dual.stream[0], -1, sock->dual.stream[0]->opts, PH_INIT);
|
||||||
applyopts(-1, sock->dual.stream[1]->opts, PH_INIT);
|
applyopts(sock->dual.stream[1], -1, sock->dual.stream[1]->opts, PH_INIT);
|
||||||
if ((result = applyopts(-1, optspr, PH_EARLY)) < 0)
|
if ((result = applyopts(NULL, -1, optspr, PH_EARLY)) < 0)
|
||||||
return result;
|
return result;
|
||||||
if ((result = applyopts(-1, optspr, PH_PREOPEN)) < 0)
|
if ((result = applyopts(NULL, -1, optspr, PH_PREOPEN)) < 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
/* apply options to first FD */
|
/* apply options to first FD */
|
||||||
if ((result =
|
if ((result =
|
||||||
applyopts(sock->dual.stream[0]->fd,
|
applyopts(sock->dual.stream[0], -1,
|
||||||
sock->dual.stream[0]->opts, PH_ALL))
|
sock->dual.stream[0]->opts, PH_ALL))
|
||||||
< 0) {
|
< 0) {
|
||||||
return result;
|
return result;
|
||||||
|
@ -113,7 +113,7 @@ int xioopen_stdio_bi(xiofile_t *sock) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* apply options to second FD */
|
/* apply options to second FD */
|
||||||
if ((result = applyopts(sock->dual.stream[1]->fd,
|
if ((result = applyopts(sock->dual.stream[1], -1,
|
||||||
sock->dual.stream[1]->opts, PH_ALL)) < 0) {
|
sock->dual.stream[1]->opts, PH_ALL)) < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,18 +43,20 @@ void dummy(void) {
|
||||||
if (0) { { ;
|
if (0) { { ;
|
||||||
#endif
|
#endif
|
||||||
#ifdef I_POP
|
#ifdef I_POP
|
||||||
} else if (opt->desc->func == OFUNC_STREAMS_I_POP_ALL) {
|
case OFUNC_STREAMS_I_POP_ALL:
|
||||||
while (Ioctl(fd, I_POP, 0) >= 0) {
|
while (Ioctl(fd, I_POP, 0) >= 0) {
|
||||||
Warn2("ioctl(%d, I_POP, 0): %s", fd, strerror(errno));
|
Warn2("ioctl(%d, I_POP, 0): %s", fd, strerror(errno));
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef I_PUSH
|
#ifdef I_PUSH
|
||||||
} else if (opt->desc->func == OFUNC_STREAMS_I_PUSH) {
|
case OFUNC_STREAMS_I_PUSH:
|
||||||
if (Ioctl(fd, I_PUSH, opt->value.u_string) < 0) {
|
if (Ioctl(fd, I_PUSH, opt->value.u_string) < 0) {
|
||||||
Warn3("ioctl(%d, I_PUSH, \"%s\"): %s",
|
Warn3("ioctl(%d, I_PUSH, \"%s\"): %s",
|
||||||
fd, opt->value.u_string, strerror(errno));
|
fd, opt->value.u_string, strerror(errno));
|
||||||
return -1;
|
rc = -1;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
} } }
|
} } }
|
||||||
|
|
|
@ -25,18 +25,20 @@ const struct addrdesc xioaddr_system = { "SYSTEM", 3, xioopen_system, GROUP_FD|G
|
||||||
|
|
||||||
static int xioopen_system(int argc, const char *argv[], struct opt *opts,
|
static int xioopen_system(int argc, const char *argv[], struct opt *opts,
|
||||||
int xioflags, /* XIO_RDONLY etc. */
|
int xioflags, /* XIO_RDONLY etc. */
|
||||||
xiofile_t *fd,
|
xiofile_t *xfd,
|
||||||
groups_t groups,
|
groups_t groups,
|
||||||
int dummy1, int dummy2, int dummy3
|
int dummy1, int dummy2, int dummy3
|
||||||
) {
|
) {
|
||||||
|
struct single *sfd = &xfd->stream;
|
||||||
int status;
|
int status;
|
||||||
char *path = NULL;
|
char *path = NULL;
|
||||||
int duptostderr;
|
int duptostderr;
|
||||||
int result;
|
int result;
|
||||||
const char *string = argv[1];
|
const char *string = argv[1];
|
||||||
|
|
||||||
status = _xioopen_foxec(xioflags, &fd->stream, groups, &opts, &duptostderr);
|
status = _xioopen_foxec(xioflags, sfd, groups, &opts, &duptostderr);
|
||||||
if (status < 0) return status;
|
if (status < 0)
|
||||||
|
return status;
|
||||||
if (status == 0) { /* child */
|
if (status == 0) { /* child */
|
||||||
int numleft;
|
int numleft;
|
||||||
|
|
||||||
|
@ -72,6 +74,7 @@ static int xioopen_system(int argc, const char *argv[], struct opt *opts,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parent */
|
/* parent */
|
||||||
|
_xio_openlate(sfd, opts);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
/****** TERMIOS addresses ******/
|
/****** TERMIOS addresses ******/
|
||||||
#if _WITH_TERMIOS
|
#if _WITH_TERMIOS
|
||||||
#if WITH_TERMIOS
|
#if WITH_TERMIOS
|
||||||
const struct optdesc opt_tiocsctty={ "tiocsctty", "ctty",OPT_TIOCSCTTY, GROUP_TERMIOS, PH_LATE2, TYPE_BOOL, OFUNC_SPEC };
|
const struct optdesc opt_tiocsctty = { "tiocsctty", "ctty",OPT_TIOCSCTTY, GROUP_TERMIOS, PH_LATE2, TYPE_BOOL, OFUNC_SPEC };
|
||||||
|
|
||||||
/* it is important for handling of these options that they have PH_FD */
|
/* it is important for handling of these options that they have PH_FD */
|
||||||
const struct optdesc opt_brkint = { "brkint", NULL, OPT_BRKINT, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, BRKINT };
|
const struct optdesc opt_brkint = { "brkint", NULL, OPT_BRKINT, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, BRKINT };
|
||||||
|
|
27
xio-tun.c
27
xio-tun.c
|
@ -46,6 +46,7 @@ static const struct optname xio_route_options[] = {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3) {
|
static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3) {
|
||||||
|
struct single *sfd = &xfd->stream;
|
||||||
char *tundevice = NULL;
|
char *tundevice = NULL;
|
||||||
char *tunname = NULL, *tuntype = NULL;
|
char *tunname = NULL, *tuntype = NULL;
|
||||||
int pf = /*! PF_UNSPEC*/ PF_INET;
|
int pf = /*! PF_UNSPEC*/ PF_INET;
|
||||||
|
@ -79,10 +80,10 @@ static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xiofl
|
||||||
|
|
||||||
/*========================= the tunnel interface =========================*/
|
/*========================= the tunnel interface =========================*/
|
||||||
Notice("creating tunnel network interface");
|
Notice("creating tunnel network interface");
|
||||||
applyopts_optgroup(-1, opts, PH_PRESOCKET, PH_PRESOCKET, GROUP_PROCESS);
|
applyopts_optgroup(&xfd->stream, -1, opts, GROUP_PROCESS);
|
||||||
if ((result = _xioopen_open(tundevice, rw, opts)) < 0)
|
if ((result = _xioopen_open(tundevice, rw, opts)) < 0)
|
||||||
return result;
|
return result;
|
||||||
xfd->stream.fd = result;
|
sfd->fd = result;
|
||||||
|
|
||||||
/* prepare configuration of the new network interface */
|
/* prepare configuration of the new network interface */
|
||||||
memset(&ifr, 0, sizeof(ifr));
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
|
@ -113,10 +114,10 @@ static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xiofl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ioctl(xfd->stream.fd, TUNSETIFF, &ifr) < 0) {
|
if (Ioctl(sfd->fd, TUNSETIFF, &ifr) < 0) {
|
||||||
Error3("ioctl(%d, TUNSETIFF, {\"%s\"}: %s",
|
Error3("ioctl(%d, TUNSETIFF, {\"%s\"}: %s",
|
||||||
xfd->stream.fd, ifr.ifr_name, strerror(errno));
|
sfd->fd, ifr.ifr_name, strerror(errno));
|
||||||
Close(xfd->stream.fd);
|
Close(sfd->fd);
|
||||||
}
|
}
|
||||||
Notice1("TUN: new device \"%s\"", ifr.ifr_name);
|
Notice1("TUN: new device \"%s\"", ifr.ifr_name);
|
||||||
|
|
||||||
|
@ -125,7 +126,7 @@ static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xiofl
|
||||||
/* we seem to need a socket for manipulating the interface */
|
/* we seem to need a socket for manipulating the interface */
|
||||||
if ((sockfd = Socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
|
if ((sockfd = Socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||||
Error1("socket(PF_INET, SOCK_DGRAM, 0): %s", strerror(errno));
|
Error1("socket(PF_INET, SOCK_DGRAM, 0): %s", strerror(errno));
|
||||||
sockfd = xfd->stream.fd; /* desparate fallback attempt */
|
sockfd = sfd->fd; /* desparate fallback attempt */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------- setting interface address and netmask ------------*/
|
/*--------------------- setting interface address and netmask ------------*/
|
||||||
|
@ -135,7 +136,7 @@ static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xiofl
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
if ((result = xioparsenetwork(ifaddr, pf, &network,
|
if ((result = xioparsenetwork(ifaddr, pf, &network,
|
||||||
xfd->stream.para.socket.ip.ai_flags))
|
sfd->para.socket.ip.ai_flags))
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
/*! recover */
|
/*! recover */
|
||||||
return result;
|
return result;
|
||||||
|
@ -157,16 +158,16 @@ static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xiofl
|
||||||
free(ifaddr);
|
free(ifaddr);
|
||||||
}
|
}
|
||||||
/*--------------------- setting interface flags --------------------------*/
|
/*--------------------- setting interface flags --------------------------*/
|
||||||
applyopts_single(&xfd->stream, opts, PH_FD);
|
applyopts_single(sfd, opts, PH_FD);
|
||||||
|
|
||||||
_xiointerface_apply_iff(sockfd, ifr.ifr_name, xfd->stream.para.interface.iff_opts);
|
_xiointerface_apply_iff(sockfd, ifr.ifr_name, sfd->para.interface.iff_opts);
|
||||||
|
|
||||||
applyopts(xfd->stream.fd, opts, PH_FD);
|
applyopts(sfd, -1, opts, PH_FD);
|
||||||
applyopts_cloexec(xfd->stream.fd, opts);
|
applyopts_cloexec(sfd->fd, opts);
|
||||||
|
|
||||||
applyopts_fchown(xfd->stream.fd, opts);
|
applyopts_fchown(sfd->fd, opts);
|
||||||
|
|
||||||
if ((result = _xio_openlate(&xfd->stream, opts)) < 0)
|
if ((result = _xio_openlate(sfd, opts)) < 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
20
xio-udp.c
20
xio-udp.c
|
@ -149,7 +149,7 @@ int _xioopen_ipdgram_listen(struct single *sfd,
|
||||||
}
|
}
|
||||||
doreuseaddr |= (retropt_2integrals(opts, OPT_SO_REUSEADDR,
|
doreuseaddr |= (retropt_2integrals(opts, OPT_SO_REUSEADDR,
|
||||||
&reuseaddr, ¬null) >= 0);
|
&reuseaddr, ¬null) >= 0);
|
||||||
applyopts(sfd->fd, opts, PH_PASTSOCKET);
|
applyopts(sfd, -1, opts, PH_PASTSOCKET);
|
||||||
|
|
||||||
/* SO_REUSEADDR handling of UDP sockets is helpful on Solaris */
|
/* SO_REUSEADDR handling of UDP sockets is helpful on Solaris */
|
||||||
if (doreuseaddr) {
|
if (doreuseaddr) {
|
||||||
|
@ -163,8 +163,8 @@ int _xioopen_ipdgram_listen(struct single *sfd,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
applyopts_cloexec(sfd->fd, opts);
|
applyopts_cloexec(sfd->fd, opts);
|
||||||
applyopts(sfd->fd, opts, PH_PREBIND);
|
applyopts(sfd, -1, opts, PH_PREBIND);
|
||||||
applyopts(sfd->fd, opts, PH_BIND);
|
applyopts(sfd, -1, opts, PH_BIND);
|
||||||
if (Bind(sfd->fd, &us->soa, uslen) < 0) {
|
if (Bind(sfd->fd, &us->soa, uslen) < 0) {
|
||||||
Error4("bind(%d, {%s}, "F_socklen"): %s", sfd->fd,
|
Error4("bind(%d, {%s}, "F_socklen"): %s", sfd->fd,
|
||||||
sockaddr_info(&us->soa, uslen, infobuff, sizeof(infobuff)),
|
sockaddr_info(&us->soa, uslen, infobuff, sizeof(infobuff)),
|
||||||
|
@ -176,7 +176,7 @@ int _xioopen_ipdgram_listen(struct single *sfd,
|
||||||
Error4("getsockname(%d, %p, {%d}): %s",
|
Error4("getsockname(%d, %p, {%d}): %s",
|
||||||
sfd->fd, &us->soa, uslen, strerror(errno));
|
sfd->fd, &us->soa, uslen, strerror(errno));
|
||||||
}
|
}
|
||||||
applyopts(sfd->fd, opts, PH_PASTBIND);
|
applyopts(sfd, -1, opts, PH_PASTBIND);
|
||||||
|
|
||||||
if (ipproto == IPPROTO_UDP) {
|
if (ipproto == IPPROTO_UDP) {
|
||||||
Notice1("listening on UDP %s",
|
Notice1("listening on UDP %s",
|
||||||
|
@ -255,7 +255,7 @@ int _xioopen_ipdgram_listen(struct single *sfd,
|
||||||
break;
|
break;
|
||||||
} /* end of the big while loop */
|
} /* end of the big while loop */
|
||||||
|
|
||||||
applyopts(sfd->fd, opts, PH_CONNECT);
|
applyopts(sfd, -1, opts, PH_CONNECT);
|
||||||
if ((result = Connect(sfd->fd, &them->soa, themlen)) < 0) {
|
if ((result = Connect(sfd->fd, &them->soa, themlen)) < 0) {
|
||||||
Error4("connect(%d, {%s}, "F_socklen"): %s",
|
Error4("connect(%d, {%s}, "F_socklen"): %s",
|
||||||
sfd->fd,
|
sfd->fd,
|
||||||
|
@ -274,7 +274,7 @@ int _xioopen_ipdgram_listen(struct single *sfd,
|
||||||
|
|
||||||
sfd->howtoend = END_SHUTDOWN;
|
sfd->howtoend = END_SHUTDOWN;
|
||||||
applyopts_fchown(sfd->fd, opts);
|
applyopts_fchown(sfd->fd, opts);
|
||||||
applyopts(sfd->fd, opts, PH_LATE);
|
applyopts(sfd, -1, opts, PH_LATE);
|
||||||
|
|
||||||
if ((result = _xio_openlate(sfd, opts)) < 0)
|
if ((result = _xio_openlate(sfd, opts)) < 0)
|
||||||
return result;
|
return result;
|
||||||
|
@ -287,6 +287,7 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
int xioflags, xiofile_t *xfd,
|
int xioflags, xiofile_t *xfd,
|
||||||
groups_t groups, int pf, int ipproto,
|
groups_t groups, int pf, int ipproto,
|
||||||
int protname) {
|
int protname) {
|
||||||
|
struct single *sfd = &xfd->stream;
|
||||||
const char *portname = argv[1];
|
const char *portname = argv[1];
|
||||||
union sockaddr_union us;
|
union sockaddr_union us;
|
||||||
int socktype = SOCK_DGRAM;
|
int socktype = SOCK_DGRAM;
|
||||||
|
@ -314,8 +315,9 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
retropt_int(opts, OPT_SO_PROTOTYPE, &ipproto);
|
retropt_int(opts, OPT_SO_PROTOTYPE, &ipproto);
|
||||||
|
|
||||||
if (applyopts_single(&xfd->stream, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0)
|
||||||
applyopts(-1, opts, PH_INIT);
|
return -1;
|
||||||
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
uslen = socket_init(pf, &us);
|
uslen = socket_init(pf, &us);
|
||||||
retropt_bind(opts, pf, socktype, ipproto,
|
retropt_bind(opts, pf, socktype, ipproto,
|
||||||
|
@ -383,7 +385,7 @@ int _xioopen_udp_sendto(const char *hostname, const char *servname,
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
xfd->howtoend = END_SHUTDOWN;
|
||||||
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(xfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
xfd->salen = sizeof(xfd->peersa);
|
xfd->salen = sizeof(xfd->peersa);
|
||||||
if ((result =
|
if ((result =
|
||||||
|
|
41
xio-unix.c
41
xio-unix.c
|
@ -148,10 +148,10 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
|
||||||
}
|
}
|
||||||
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(xfd, -1, opts, PH_INIT);
|
||||||
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
||||||
applyopts_offset(xfd, opts);
|
applyopts_offset(xfd, opts);
|
||||||
applyopts(-1, opts, PH_EARLY);
|
applyopts(xfd, -1, opts, PH_EARLY);
|
||||||
|
|
||||||
uslen = xiosetunix(pf, &us, name, abstract, xfd->para.socket.un.tight);
|
uslen = xiosetunix(pf, &us, name, abstract, xfd->para.socket.un.tight);
|
||||||
|
|
||||||
|
@ -229,9 +229,9 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
xfd->howtoend = END_SHUTDOWN;
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(xfd, -1, opts, PH_INIT);
|
||||||
applyopts_offset(xfd, opts);
|
applyopts_offset(xfd, opts);
|
||||||
applyopts(-1, opts, PH_EARLY);
|
applyopts(xfd, -1, opts, PH_EARLY);
|
||||||
|
|
||||||
themlen = xiosetunix(pf, &them, name, abstract, xfd->para.socket.un.tight);
|
themlen = xiosetunix(pf, &them, name, abstract, xfd->para.socket.un.tight);
|
||||||
|
|
||||||
|
@ -361,6 +361,7 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i
|
||||||
socklen_t uslen = sizeof(us);
|
socklen_t uslen = sizeof(us);
|
||||||
bool needbind = false;
|
bool needbind = false;
|
||||||
bool opt_unlink_close = (abstract != 1);
|
bool opt_unlink_close = (abstract != 1);
|
||||||
|
int result;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
Error2("%s: wrong number of parameters (%d instead of 1)",
|
||||||
|
@ -394,20 +395,24 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i
|
||||||
Error1("Option \"%s\" only with bind option", namedopt->desc->defname);
|
Error1("Option \"%s\" only with bind option", namedopt->desc->defname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
||||||
|
applyopts(xfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
|
result =
|
||||||
|
_xioopen_dgram_sendto(needbind?(union sockaddr_union *)&us:NULL, uslen,
|
||||||
|
opts, xioflags, xfd, groups,
|
||||||
|
pf, socktype, protocol, 0);
|
||||||
|
if (result != 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
if (opt_unlink_close && needbind) {
|
if (opt_unlink_close && needbind) {
|
||||||
if ((xfd->unlink_close = strdup(us.un.sun_path)) == NULL) {
|
if ((xfd->unlink_close = strdup(us.un.sun_path)) == NULL) {
|
||||||
Error1("strdup(\"%s\"): out of memory", name);
|
Error1("strdup(\"%s\"): out of memory", name);
|
||||||
}
|
}
|
||||||
xfd->opt_unlink_close = true;
|
xfd->opt_unlink_close = true;
|
||||||
}
|
}
|
||||||
|
return STAT_OK;
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
|
||||||
applyopts(-1, opts, PH_INIT);
|
|
||||||
|
|
||||||
return
|
|
||||||
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
|
||||||
opts, xioflags, xfd, groups,
|
|
||||||
pf, socktype, protocol, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -438,7 +443,7 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
xfd->howtoend = END_NONE;
|
xfd->howtoend = END_NONE;
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(xfd, -1, opts, PH_INIT);
|
||||||
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
||||||
applyopts_offset(xfd, opts);
|
applyopts_offset(xfd, opts);
|
||||||
|
|
||||||
|
@ -447,7 +452,7 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
|
||||||
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
}
|
}
|
||||||
applyopts(-1, opts, PH_EARLY);
|
applyopts(xfd, -1, opts, PH_EARLY);
|
||||||
|
|
||||||
uslen = xiosetunix(pf, &us, name, abstract, xfd->para.socket.un.tight);
|
uslen = xiosetunix(pf, &us, name, abstract, xfd->para.socket.un.tight);
|
||||||
|
|
||||||
|
@ -519,7 +524,7 @@ int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
xfd->howtoend = END_SHUTDOWN;
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(xfd, -1, opts, PH_INIT);
|
||||||
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
||||||
applyopts_offset(xfd, opts);
|
applyopts_offset(xfd, opts);
|
||||||
|
|
||||||
|
@ -528,7 +533,7 @@ int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
||||||
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
}
|
}
|
||||||
applyopts(-1, opts, PH_EARLY);
|
applyopts(xfd, -1, opts, PH_EARLY);
|
||||||
|
|
||||||
uslen = xiosetunix(pf, &us.un, name, abstract, xfd->para.socket.un.tight);
|
uslen = xiosetunix(pf, &us.un, name, abstract, xfd->para.socket.un.tight);
|
||||||
|
|
||||||
|
@ -607,11 +612,11 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, groups_t groups,
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
xfd->howtoend = END_SHUTDOWN;
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(xfd, -1, opts, PH_INIT);
|
||||||
applyopts_offset(xfd, opts);
|
applyopts_offset(xfd, opts);
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
retropt_int(opts, OPT_SO_PROTOTYPE, &protocol);
|
retropt_int(opts, OPT_SO_PROTOTYPE, &protocol);
|
||||||
applyopts(-1, opts, PH_EARLY);
|
applyopts(xfd, -1, opts, PH_EARLY);
|
||||||
|
|
||||||
themlen = xiosetunix(pf, &them.un, name, abstract, xfd->para.socket.un.tight);
|
themlen = xiosetunix(pf, &them.un, name, abstract, xfd->para.socket.un.tight);
|
||||||
if (!(ABSTRACT && abstract)) {
|
if (!(ABSTRACT && abstract)) {
|
||||||
|
|
|
@ -52,8 +52,8 @@ static int vsock_init(struct opt *opts, struct single *xfd) {
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0)
|
if (applyopts_single(xfd, opts, PH_INIT) < 0)
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
|
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(xfd, -1, opts, PH_INIT);
|
||||||
applyopts(-1, opts, PH_EARLY);
|
applyopts(xfd, -1, opts, PH_EARLY);
|
||||||
|
|
||||||
xfd->dtype = XIODATA_STREAM;
|
xfd->dtype = XIODATA_STREAM;
|
||||||
|
|
||||||
|
|
2
xio.h
2
xio.h
|
@ -172,7 +172,7 @@ typedef struct single {
|
||||||
size_t actbytes; /* so many bytes still to be read (when readbytes!=0)*/
|
size_t actbytes; /* so many bytes still to be read (when readbytes!=0)*/
|
||||||
xiolock_t lock; /* parameters of lockfile */
|
xiolock_t lock; /* parameters of lockfile */
|
||||||
bool havelock; /* we are happy owner of the above lock */
|
bool havelock; /* we are happy owner of the above lock */
|
||||||
int triggerfd; /* close this FD in child process to notify parent */
|
int triggerfd; /* in child process close this FD to notify parent */
|
||||||
bool cool_write; /* downlevel EPIPE, ECONNRESET to notice */
|
bool cool_write; /* downlevel EPIPE, ECONNRESET to notice */
|
||||||
/* until here, keep consistent with bipipe.dual ! */
|
/* until here, keep consistent with bipipe.dual ! */
|
||||||
int argc; /* number of fields in argv */
|
int argc; /* number of fields in argv */
|
||||||
|
|
|
@ -111,6 +111,15 @@ static int xiohelp_option(FILE *of, const struct optname *on, const char *name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *xiohelp_opttypename(enum e_types typnum)
|
||||||
|
{
|
||||||
|
if (typnum < 0 || typnum >= TYPE_OVERFLOW) {
|
||||||
|
Warn2("%s(): invalid type number %d", __func__, typnum);
|
||||||
|
return "<invalid>";
|
||||||
|
}
|
||||||
|
return optiontypenames[typnum];
|
||||||
|
}
|
||||||
|
|
||||||
int xioopenhelp(FILE *of,
|
int xioopenhelp(FILE *of,
|
||||||
int level /* 0..only addresses, 1..and options */
|
int level /* 0..only addresses, 1..and options */
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#ifndef __xiohelp_h_included
|
#ifndef __xiohelp_h_included
|
||||||
#define __xiohelp_h_included 1
|
#define __xiohelp_h_included 1
|
||||||
|
|
||||||
|
extern const char *xiohelp_opttypename(enum e_types typnum);
|
||||||
|
|
||||||
extern int xioopenhelp(FILE *of,
|
extern int xioopenhelp(FILE *of,
|
||||||
int level /* 0..only addresses, 1..and options */
|
int level /* 0..only addresses, 1..and options */
|
||||||
);
|
);
|
||||||
|
|
33
xioopts.h
33
xioopts.h
|
@ -82,10 +82,12 @@ enum e_types {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TYPE_GENERIC, /* type is determined from (text) data provided (dalan syntax) */
|
TYPE_GENERIC, /* type is determined from (text) data provided (dalan syntax) */
|
||||||
|
TYPE_OVERFLOW /* marker: beyond last type */
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
enum e_func {
|
enum e_func {
|
||||||
OFUNC_NONE, /* no function - should not occur */
|
OFUNC_NONE, /* no function - should not occur */
|
||||||
|
/* Options to be applied to FD directly */
|
||||||
OFUNC_FLAG, /* no function, but bitposition, only with bool; arg1 is mask */
|
OFUNC_FLAG, /* no function, but bitposition, only with bool; arg1 is mask */
|
||||||
OFUNC_FLAG_PATTERN, /* no function, but bitpattern: arg1 is pattern, arg2 is mask */
|
OFUNC_FLAG_PATTERN, /* no function, but bitpattern: arg1 is pattern, arg2 is mask */
|
||||||
OFUNC_SEEK32, /* lseek(): arg1 is whence (SEEK_SET etc.) */
|
OFUNC_SEEK32, /* lseek(): arg1 is whence (SEEK_SET etc.) */
|
||||||
|
@ -100,12 +102,6 @@ enum e_func {
|
||||||
OFUNC_SOCKOPT_APPEND,/* getsockopt(), append data, setsockopt() */
|
OFUNC_SOCKOPT_APPEND,/* getsockopt(), append data, setsockopt() */
|
||||||
OFUNC_SOCKOPT_GENERIC,/* generic setsockopt() (level, optname on cmdline) */
|
OFUNC_SOCKOPT_GENERIC,/* generic setsockopt() (level, optname on cmdline) */
|
||||||
OFUNC_FLOCK, /* flock() */
|
OFUNC_FLOCK, /* flock() */
|
||||||
OFUNC_TERMIO, /* termio() ? */
|
|
||||||
OFUNC_SPEC, /* special, i.e. no generalizable function call */
|
|
||||||
OFUNC_OFFSET, /* put a value into xiofile struct; major is offset */
|
|
||||||
OFUNC_OFFSET_MASKS, /* set pos or neg bit pattern in array[2] */
|
|
||||||
/*OFUNC_APPL,*/ /* special, i.e. application must know which f. */
|
|
||||||
OFUNC_EXT, /* with extended file descriptors only */
|
|
||||||
OFUNC_TERMIOS_FLAG, /* a flag in struct termios: major..tcflag, minor..bit
|
OFUNC_TERMIOS_FLAG, /* a flag in struct termios: major..tcflag, minor..bit
|
||||||
*/
|
*/
|
||||||
OFUNC_TERMIOS_PATTERN, /* a multibit: major..tcflag, minor..pattern,
|
OFUNC_TERMIOS_PATTERN, /* a multibit: major..tcflag, minor..pattern,
|
||||||
|
@ -114,14 +110,23 @@ enum e_func {
|
||||||
OFUNC_TERMIOS_CHAR, /* a termios functional character: major..c_cc index */
|
OFUNC_TERMIOS_CHAR, /* a termios functional character: major..c_cc index */
|
||||||
OFUNC_TERMIOS_SPEED, /* termios c_ispeed etc on FreeBSD */
|
OFUNC_TERMIOS_SPEED, /* termios c_ispeed etc on FreeBSD */
|
||||||
OFUNC_TERMIOS_SPEC, /* termios combined modes */
|
OFUNC_TERMIOS_SPEC, /* termios combined modes */
|
||||||
|
|
||||||
|
OFUNC_EXT, /* with extended file descriptors only */
|
||||||
|
# define OFUNC_XIO OFUNC_EXT
|
||||||
|
OFUNC_SPEC, /* special, i.e. no generalizable function call */
|
||||||
|
OFUNC_OFFSET, /* put a value into xiofile struct; major is offset */
|
||||||
|
OFUNC_OFFSET_MASK, /* set/unset bit pattern in variable */
|
||||||
|
OFUNC_OFFSET_MASKS, /* set pos or neg bit pattern in array[2] */
|
||||||
|
/*OFUNC_APPL,*/ /* special, i.e. application must know which f. */
|
||||||
OFUNC_SIGNAL, /* a signal that should be passed to child process */
|
OFUNC_SIGNAL, /* a signal that should be passed to child process */
|
||||||
OFUNC_RESOLVER, /* a bit position used on _res.options */
|
OFUNC_RESOLVER, /* a bit position used on _res.options */
|
||||||
OFUNC_IFFLAG, /* interface flag: locical-or a 1bit mask */
|
OFUNC_IFFLAG, /* interface flag: logical-or a 1bit mask */
|
||||||
|
OFUNC_SET_NAMESPACE, /* set/change Linux namespace */
|
||||||
|
OFUNC_RESET_NAMESPACE, /* set Linux namespace back to default */
|
||||||
# define ENABLE_OFUNC
|
# define ENABLE_OFUNC
|
||||||
# include "xio-streams.h" /* push a POSIX STREAMS module */
|
# include "xio-streams.h" /* push a POSIX STREAMS module */
|
||||||
# undef ENABLE_OFUNC
|
# undef ENABLE_OFUNC
|
||||||
OFUNC_SET_NAMESPACE, /* set/change Linux namespace */
|
OFUNC_OVERFLOW /* marker: beyond last func */
|
||||||
OFUNC_RESET_NAMESPACE, /* set Linux namespace back to default */
|
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
/* for simpler handling of option-to-connection-type relations we define
|
/* for simpler handling of option-to-connection-type relations we define
|
||||||
|
@ -980,12 +985,13 @@ extern int retropt_flag(struct opt *opts, int optcode, flags_t *result);
|
||||||
extern int retropt_string(struct opt *opts, int optcode, char **result);
|
extern int retropt_string(struct opt *opts, int optcode, char **result);
|
||||||
extern int retropt_timespec(struct opt *opts, int optcode, struct timespec *result);
|
extern int retropt_timespec(struct opt *opts, int optcode, struct timespec *result);
|
||||||
extern int retropt_bind(struct opt *opts, int af, int socktype, int ipproto, struct sockaddr *sa, socklen_t *salen, int feats, const int ai_flags[2]);
|
extern int retropt_bind(struct opt *opts, int af, int socktype, int ipproto, struct sockaddr *sa, socklen_t *salen, int feats, const int ai_flags[2]);
|
||||||
extern int applyopts(int fd, struct opt *opts, enum e_phase phase);
|
extern int applyopt_fd(int fd, struct opt *opt);
|
||||||
extern int applyopts2(int fd, struct opt *opts, unsigned int from, unsigned int to);
|
extern int applyopt_single(struct single *sfd, struct opt *opt);
|
||||||
extern int applyopts_optgroup(int fd, struct opt *opts, int from, int to, groups_t groups);
|
extern int applyopts(struct single *sfd, int fd, struct opt *opts, enum e_phase phase);
|
||||||
|
extern int applyopts2(struct single *sfd, int fd, struct opt *opts, unsigned int from, unsigned int to);
|
||||||
|
extern int applyopts_optgroup(struct single *sfd, int fd, struct opt *opts, groups_t groups);
|
||||||
extern int applyopts_flags(struct opt *opts, groups_t group, flags_t *result);
|
extern int applyopts_flags(struct opt *opts, groups_t group, flags_t *result);
|
||||||
extern int applyopts_cloexec(int fd, struct opt *opts);
|
extern int applyopts_cloexec(int fd, struct opt *opts);
|
||||||
extern int applyopts_early(const char *path, struct opt *opts);
|
|
||||||
extern int applyopts_fchown(int fd, struct opt *opts);
|
extern int applyopts_fchown(int fd, struct opt *opts);
|
||||||
extern int applyopts_single(struct single *fd, struct opt *opts, enum e_phase phase);
|
extern int applyopts_single(struct single *fd, struct opt *opts, enum e_phase phase);
|
||||||
extern int applyopts_offset(struct single *xfd, struct opt *opts);
|
extern int applyopts_offset(struct single *xfd, struct opt *opts);
|
||||||
|
@ -1005,6 +1011,7 @@ extern groups_t groupbits(int fd);
|
||||||
extern groups_t _groupbits(mode_t mode);
|
extern groups_t _groupbits(mode_t mode);
|
||||||
extern int dropopts(struct opt *opts, unsigned int phase);
|
extern int dropopts(struct opt *opts, unsigned int phase);
|
||||||
extern int dropopts2(struct opt *opts, unsigned int from, unsigned int to);
|
extern int dropopts2(struct opt *opts, unsigned int from, unsigned int to);
|
||||||
|
extern int dumpopts(struct opt *opts);
|
||||||
|
|
||||||
#if HAVE_BASIC_UID_T==1
|
#if HAVE_BASIC_UID_T==1
|
||||||
# define retropt_uid(o,c,r) retropt_short(o,c,r)
|
# define retropt_uid(o,c,r) retropt_short(o,c,r)
|
||||||
|
|
|
@ -62,14 +62,19 @@ void socatsignalpass(int sig) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ /*debug*/
|
||||||
|
int n = 0;
|
||||||
for (i=0; i<sigdesc->sig_use; ++i) {
|
for (i=0; i<sigdesc->sig_use; ++i) {
|
||||||
if (sigdesc->sig_pids[i]) {
|
if (sigdesc->sig_pids[i]) {
|
||||||
|
++n;
|
||||||
if (Kill(sigdesc->sig_pids[i], sig) < 0) {
|
if (Kill(sigdesc->sig_pids[i], sig) < 0) {
|
||||||
Warn2("kill("F_pid", %d): %m",
|
Warn2("kill("F_pid", %d): %m",
|
||||||
sigdesc->sig_pids[i], sig);
|
sigdesc->sig_pids[i], sig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Info1("socatsignalpass(): n=%d", n);
|
||||||
|
}
|
||||||
#if !HAVE_SIGACTION
|
#if !HAVE_SIGACTION
|
||||||
Signal(sig, socatsignalpass);
|
Signal(sig, socatsignalpass);
|
||||||
#endif /* !HAVE_SIGACTION */
|
#endif /* !HAVE_SIGACTION */
|
||||||
|
|
Loading…
Reference in a new issue