mirror of
https://github.com/moparisthebest/socat
synced 2024-12-21 22:48:48 -05:00
cleanup xio-unix.c: merged classic with abstract functions; names, ...
This commit is contained in:
parent
d70b8963aa
commit
b6c2d46008
3
CHANGES
3
CHANGES
@ -35,6 +35,9 @@ corrections:
|
|||||||
replaced the select() calls by poll() to cleanly fix the problems with
|
replaced the select() calls by poll() to cleanly fix the problems with
|
||||||
many file descriptors already open
|
many file descriptors already open
|
||||||
|
|
||||||
|
further changes:
|
||||||
|
cleanup in xio-unix.c
|
||||||
|
|
||||||
####################### V 1.6.0.1:
|
####################### V 1.6.0.1:
|
||||||
|
|
||||||
new features:
|
new features:
|
||||||
|
2
test.sh
2
test.sh
@ -2364,7 +2364,7 @@ N=$((N+1))
|
|||||||
|
|
||||||
NAME=UNIXSOCKET
|
NAME=UNIXSOCKET
|
||||||
case "$TESTS" in
|
case "$TESTS" in
|
||||||
*%functions%*|*%$NAME%*)
|
*%functions%*|*%unix%*|*%$NAME%*)
|
||||||
TEST="$NAME: echo via connection to UNIX domain socket"
|
TEST="$NAME: echo via connection to UNIX domain socket"
|
||||||
tf="$td/test$N.stdout"
|
tf="$td/test$N.stdout"
|
||||||
te="$td/test$N.stderr"
|
te="$td/test$N.stderr"
|
||||||
|
596
xio-unix.c
596
xio-unix.c
@ -1,5 +1,5 @@
|
|||||||
/* source: xio-unix.c */
|
/* source: xio-unix.c */
|
||||||
/* Copyright Gerhard Rieger 2001-2007 */
|
/* Copyright Gerhard Rieger 2001-2008 */
|
||||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||||
|
|
||||||
/* this file contains the source for opening addresses of UNIX socket type */
|
/* this file contains the source for opening addresses of UNIX socket type */
|
||||||
@ -15,52 +15,56 @@
|
|||||||
|
|
||||||
#if WITH_UNIX
|
#if WITH_UNIX
|
||||||
|
|
||||||
static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
/* to avoid unneccessary "live" if () conditionals when no abstract support is
|
||||||
static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
compiled in (or at least to give optimizing compilers a good chance) we need
|
||||||
static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
a constant that can be used in C expressions */
|
||||||
static int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
#if WITH_ABSTRACT_UNIXSOCKET
|
||||||
|
# define ABSTRACT 1
|
||||||
|
#else
|
||||||
|
# define ABSTRACT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3);
|
||||||
|
static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3);
|
||||||
|
static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3);
|
||||||
|
static int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3);
|
||||||
static
|
static
|
||||||
int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
||||||
int xioflags, xiofile_t *xfd, unsigned groups,
|
int xioflags, xiofile_t *xxfd, unsigned groups,
|
||||||
int pf, int socktype, int ipproto);
|
int abstract, int dummy2, int dummy3);
|
||||||
static
|
static
|
||||||
int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3);
|
||||||
|
|
||||||
|
/* the first free parameter is 0 for "normal" unix domain sockets, or 1 for
|
||||||
|
abstract unix sockets (Linux); the second and third free parameter are
|
||||||
|
unsused */
|
||||||
|
const struct addrdesc xioaddr_unix_connect = { "unix-connect", 3, xioopen_unix_connect, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":<filename>") };
|
||||||
|
#if WITH_LISTEN
|
||||||
|
const struct addrdesc xioaddr_unix_listen = { "unix-listen", 3, xioopen_unix_listen, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":<filename>") };
|
||||||
|
#endif /* WITH_LISTEN */
|
||||||
|
const struct addrdesc xioaddr_unix_sendto = { "unix-sendto", 3, xioopen_unix_sendto, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":<filename>") };
|
||||||
|
const struct addrdesc xioaddr_unix_recvfrom= { "unix-recvfrom", 3, xioopen_unix_recvfrom, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY|GROUP_CHILD, 0, 0, 0 HELP(":<filename>") };
|
||||||
|
const struct addrdesc xioaddr_unix_recv = { "unix-recv", 1, xioopen_unix_recv, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":<filename>") };
|
||||||
|
const struct addrdesc xioaddr_unix_client = { "unix-client", 3, xioopen_unix_client, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":<filename>") };
|
||||||
#if WITH_ABSTRACT_UNIXSOCKET
|
#if WITH_ABSTRACT_UNIXSOCKET
|
||||||
static int xioopen_abstract_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
const struct addrdesc xioaddr_abstract_connect = { "abstract-connect", 3, xioopen_unix_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":<filename>") };
|
||||||
static int xioopen_abstract_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
#if WITH_LISTEN
|
||||||
static int xioopen_abstract_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
const struct addrdesc xioaddr_abstract_listen = { "abstract-listen", 3, xioopen_unix_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 1, 0, 0 HELP(":<filename>") };
|
||||||
static int xioopen_abstract_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
#endif /* WITH_LISTEN */
|
||||||
static
|
const struct addrdesc xioaddr_abstract_sendto = { "abstract-sendto", 3, xioopen_unix_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":<filename>") };
|
||||||
int xioopen_abstract_recv(int argc, const char *argv[], struct opt *opts,
|
const struct addrdesc xioaddr_abstract_recvfrom= { "abstract-recvfrom", 3, xioopen_unix_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY|GROUP_CHILD, 1, 0, 0 HELP(":<filename>") };
|
||||||
int xioflags, xiofile_t *xfd, unsigned groups,
|
const struct addrdesc xioaddr_abstract_recv = { "abstract-recv", 1, xioopen_unix_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":<filename>") };
|
||||||
int pf, int socktype, int ipproto);
|
const struct addrdesc xioaddr_abstract_client = { "abstract-client", 3, xioopen_unix_client, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":<filename>") };
|
||||||
static
|
|
||||||
int xioopen_abstract_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
|
||||||
#endif /* WITH_ABSTRACT_UNIXSOCKET */
|
#endif /* WITH_ABSTRACT_UNIXSOCKET */
|
||||||
|
|
||||||
const struct addrdesc addr_unix_connect = { "unix-connect", 3, xioopen_unix_connect, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, SOCK_STREAM, 0 HELP(":<filename>") };
|
const struct optdesc xioopt_unix_tightsocklen = { "unix-tightsocklen", "tightsocklen", OPT_UNIX_TIGHTSOCKLEN, GROUP_SOCK_UNIX, PH_INIT, TYPE_BOOL, OFUNC_SPEC, 0, 0 };
|
||||||
#if WITH_LISTEN
|
|
||||||
const struct addrdesc addr_unix_listen = { "unix-listen", 3, xioopen_unix_listen, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 0, SOCK_STREAM, 0 HELP(":<filename>") };
|
|
||||||
#endif /* WITH_LISTEN */
|
|
||||||
const struct addrdesc addr_unix_sendto = { "unix-sendto", 3, xioopen_unix_sendto, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, SOCK_DGRAM, 0 HELP(":<filename>") };
|
|
||||||
const struct addrdesc addr_unix_recvfrom= { "unix-recvfrom", 3, xioopen_unix_recvfrom, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY|GROUP_CHILD, PF_UNIX, SOCK_DGRAM, 0 HELP(":<filename>") };
|
|
||||||
const struct addrdesc addr_unix_recv = { "unix-recv", 1, xioopen_unix_recv, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, PF_UNIX, SOCK_DGRAM, 0 HELP(":<filename>") };
|
|
||||||
const struct addrdesc addr_unix_client = { "unix-client", 3, xioopen_unix_client, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, PF_UNIX, 0, 0 HELP(":<filename>") };
|
|
||||||
#if WITH_ABSTRACT_UNIXSOCKET
|
|
||||||
const struct addrdesc xioaddr_abstract_connect = { "abstract-connect", 3, xioopen_abstract_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, SOCK_STREAM, 0 HELP(":<filename>") };
|
|
||||||
#if WITH_LISTEN
|
|
||||||
const struct addrdesc xioaddr_abstract_listen = { "abstract-listen", 3, xioopen_abstract_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 0, SOCK_STREAM, 0 HELP(":<filename>") };
|
|
||||||
#endif /* WITH_LISTEN */
|
|
||||||
const struct addrdesc xioaddr_abstract_sendto = { "abstract-sendto", 3, xioopen_abstract_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, SOCK_DGRAM, 0 HELP(":<filename>") };
|
|
||||||
const struct addrdesc xioaddr_abstract_recvfrom= { "abstract-recvfrom", 3, xioopen_abstract_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY|GROUP_CHILD, PF_UNIX, SOCK_DGRAM, 0 HELP(":<filename>") };
|
|
||||||
const struct addrdesc xioaddr_abstract_recv = { "abstract-recv", 1, xioopen_abstract_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, PF_UNIX, SOCK_DGRAM, 0 HELP(":<filename>") };
|
|
||||||
const struct addrdesc xioaddr_abstract_client = { "abstract-client", 3, xioopen_abstract_client, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, PF_UNIX, 0, 0 HELP(":<filename>") };
|
|
||||||
#endif /* WITH_ABSTRACT_UNIXSOCKET */
|
|
||||||
|
|
||||||
const struct optdesc opt_unix_tightsocklen = { "unix-tightsocklen", "tightsocklen", OPT_UNIX_TIGHTSOCKLEN, GROUP_SOCK_UNIX, PH_INIT, TYPE_BOOL, OFUNC_SPEC, 0, 0 };
|
|
||||||
|
|
||||||
|
|
||||||
|
/* fills the socket address struct and returns its effective length.
|
||||||
|
abstract is usually 0; != 0 generates an abstract socket address on Linux.
|
||||||
|
tight calculates the resulting length from the path length, not from the
|
||||||
|
struct length.
|
||||||
|
*/
|
||||||
socklen_t
|
socklen_t
|
||||||
xiosetunix(struct sockaddr_un *saun,
|
xiosetunix(struct sockaddr_un *saun,
|
||||||
const char *path,
|
const char *path,
|
||||||
@ -69,22 +73,8 @@ xiosetunix(struct sockaddr_un *saun,
|
|||||||
size_t pathlen;
|
size_t pathlen;
|
||||||
socklen_t len;
|
socklen_t len;
|
||||||
|
|
||||||
if (!abstract) {
|
#ifdef WITH_ABSTRACT_UNIXSOCKET
|
||||||
if ((pathlen = strlen(path)) > sizeof(saun->sun_path)) {
|
if (abstract) {
|
||||||
Warn2("unix socket address "F_Zu" characters long, truncating to "F_Zu"",
|
|
||||||
pathlen, sizeof(saun->sun_path));
|
|
||||||
}
|
|
||||||
strncpy(saun->sun_path, path, sizeof(saun->sun_path));
|
|
||||||
if (tight) {
|
|
||||||
len = sizeof(struct sockaddr_un)-sizeof(saun->sun_path)+
|
|
||||||
MIN(pathlen, sizeof(saun->sun_path));
|
|
||||||
#if HAVE_STRUCT_SOCKADDR_SALEN
|
|
||||||
saun->sun_len = len;
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
len = sizeof(struct sockaddr_un);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((pathlen = strlen(path)) >= sizeof(saun->sun_path)) {
|
if ((pathlen = strlen(path)) >= sizeof(saun->sun_path)) {
|
||||||
Warn2("socket address "F_Zu" characters long, truncating to "F_Zu"",
|
Warn2("socket address "F_Zu" characters long, truncating to "F_Zu"",
|
||||||
pathlen+1, sizeof(saun->sun_path));
|
pathlen+1, sizeof(saun->sun_path));
|
||||||
@ -100,15 +90,32 @@ xiosetunix(struct sockaddr_un *saun,
|
|||||||
} else {
|
} else {
|
||||||
len = sizeof(struct sockaddr_un);
|
len = sizeof(struct sockaddr_un);
|
||||||
}
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
#endif /* WITH_ABSTRACT_UNIXSOCKET */
|
||||||
|
|
||||||
|
if ((pathlen = strlen(path)) > sizeof(saun->sun_path)) {
|
||||||
|
Warn2("unix socket address "F_Zu" characters long, truncating to "F_Zu"",
|
||||||
|
pathlen, sizeof(saun->sun_path));
|
||||||
|
}
|
||||||
|
strncpy(saun->sun_path, path, sizeof(saun->sun_path));
|
||||||
|
if (tight) {
|
||||||
|
len = sizeof(struct sockaddr_un)-sizeof(saun->sun_path)+
|
||||||
|
MIN(pathlen, sizeof(saun->sun_path));
|
||||||
|
} else {
|
||||||
|
len = sizeof(struct sockaddr_un);
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WITH_LISTEN
|
#if WITH_LISTEN
|
||||||
static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) {
|
static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3) {
|
||||||
/* we expect the form: filename */
|
/* we expect the form: filename */
|
||||||
const char *name;
|
const char *name;
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
xiosingle_t *xfd = &xxfd->stream;
|
||||||
|
int pf = PF_UNIX;
|
||||||
|
int socktype = SOCK_STREAM;
|
||||||
|
int protocol = 0;
|
||||||
struct sockaddr_un us;
|
struct sockaddr_un us;
|
||||||
socklen_t uslen;
|
socklen_t uslen;
|
||||||
bool tight = true;
|
bool tight = true;
|
||||||
@ -127,37 +134,41 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
|
|||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
uslen = xiosetunix(&us, name, false, tight);
|
uslen = xiosetunix(&us, name, abstract, tight);
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
|
||||||
|
|
||||||
if (opt_unlink_close) {
|
|
||||||
if ((xfd->unlink_close = strdup(name)) == NULL) {
|
|
||||||
Error1("strdup(\"%s\"): out of memory", name);
|
|
||||||
}
|
|
||||||
xfd->opt_unlink_close = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
xfd->howtoend = END_SHUTDOWN;
|
||||||
|
|
||||||
|
if (!(ABSTRACT && abstract)) {
|
||||||
|
/* only for non abstract because abstract do not work in file system */
|
||||||
|
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
||||||
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
|
if (opt_unlink_close) {
|
||||||
|
if ((xfd->unlink_close = strdup(name)) == NULL) {
|
||||||
|
Error1("strdup(\"%s\"): out of memory", name);
|
||||||
|
}
|
||||||
|
xfd->opt_unlink_close = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(-1, opts, PH_INIT);
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(-1, opts, PH_EARLY);
|
applyopts(-1, opts, PH_EARLY);
|
||||||
|
|
||||||
if (opt_unlink_early) {
|
if (!(ABSTRACT && abstract)) {
|
||||||
if (Unlink(name) < 0) {
|
if (opt_unlink_early) {
|
||||||
if (errno == ENOENT) {
|
if (Unlink(name) < 0) {
|
||||||
Warn2("unlink(\"%s\"): %s", name, strerror(errno));
|
if (errno == ENOENT) {
|
||||||
} else {
|
Warn2("unlink(\"%s\"): %s", name, strerror(errno));
|
||||||
Error2("unlink(\"%s\"): %s", name, strerror(errno));
|
} else {
|
||||||
|
Error2("unlink(\"%s\"): %s", name, strerror(errno));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* trying to set user-early, perm-early etc. here is useless because
|
/* trying to set user-early, perm-early etc. here is useless because
|
||||||
file system entry is available only past bind() call. */
|
file system entry is available only past bind() call. */
|
||||||
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
||||||
|
}
|
||||||
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
|
|
||||||
@ -166,7 +177,7 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
|
|||||||
if ((result =
|
if ((result =
|
||||||
xioopen_listen(xfd, xioflags,
|
xioopen_listen(xfd, xioflags,
|
||||||
(struct sockaddr *)&us, uslen,
|
(struct sockaddr *)&us, uslen,
|
||||||
opts, opts0, PF_UNIX, socktype, 0))
|
opts, opts0, pf, socktype, protocol))
|
||||||
!= 0)
|
!= 0)
|
||||||
return result;
|
return result;
|
||||||
return 0;
|
return 0;
|
||||||
@ -174,10 +185,13 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
|
|||||||
#endif /* WITH_LISTEN */
|
#endif /* WITH_LISTEN */
|
||||||
|
|
||||||
|
|
||||||
static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) {
|
static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3) {
|
||||||
/* we expect the form: filename */
|
/* we expect the form: filename */
|
||||||
const char *name;
|
const char *name;
|
||||||
struct single *xfd = &xxfd->stream;
|
struct single *xfd = &xxfd->stream;
|
||||||
|
int pf = PF_UNIX;
|
||||||
|
int socktype = SOCK_STREAM;
|
||||||
|
int protocol = 0;
|
||||||
struct sockaddr_un them, us;
|
struct sockaddr_un them, us;
|
||||||
socklen_t themlen, uslen;
|
socklen_t themlen, uslen;
|
||||||
bool tight = true;
|
bool tight = true;
|
||||||
@ -196,9 +210,11 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
|
|||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
themlen = xiosetunix(&them, name, false, tight);
|
themlen = xiosetunix(&them, name, abstract, tight);
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
if (!(ABSTRACT && abstract)) {
|
||||||
|
/* only for non abstract because abstract do not work in file system */
|
||||||
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
|
}
|
||||||
if (retropt_bind(opts, AF_UNIX, socktype, 0, (struct sockaddr *)&us, &uslen, 0, 0, 0)
|
if (retropt_bind(opts, AF_UNIX, socktype, 0, (struct sockaddr *)&us, &uslen, 0, 0, 0)
|
||||||
!= STAT_NOACTION) {
|
!= STAT_NOACTION) {
|
||||||
needbind = true;
|
needbind = true;
|
||||||
@ -219,7 +235,7 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
|
|||||||
xioopen_connect(xfd,
|
xioopen_connect(xfd,
|
||||||
needbind?(struct sockaddr *)&us:NULL, uslen,
|
needbind?(struct sockaddr *)&us:NULL, uslen,
|
||||||
(struct sockaddr *)&them, themlen,
|
(struct sockaddr *)&them, themlen,
|
||||||
opts, PF_UNIX, socktype, 0, false)) != 0) {
|
opts, pf, socktype, protocol, false)) != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if ((result = _xio_openlate(xfd, opts)) < 0) {
|
if ((result = _xio_openlate(xfd, opts)) < 0) {
|
||||||
@ -229,13 +245,16 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) {
|
static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy, int dummy3) {
|
||||||
|
/* we expect the form: filename */
|
||||||
const char *name;
|
const char *name;
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
xiosingle_t *xfd = &xxfd->stream;
|
||||||
|
int pf = PF_UNIX;
|
||||||
|
int socktype = SOCK_DGRAM;
|
||||||
|
int protocol = 0;
|
||||||
union sockaddr_union us;
|
union sockaddr_union us;
|
||||||
socklen_t uslen;
|
socklen_t uslen;
|
||||||
bool tight = true;
|
bool tight = true;
|
||||||
int pf = PF_UNIX;
|
|
||||||
bool needbind = false;
|
bool needbind = false;
|
||||||
bool opt_unlink_close = false;
|
bool opt_unlink_close = false;
|
||||||
|
|
||||||
@ -254,9 +273,12 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i
|
|||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
xfd->salen = xiosetunix(&xfd->peersa.un, name, false, tight);
|
xfd->salen = xiosetunix(&xfd->peersa.un, name, abstract, tight);
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
if (!(ABSTRACT && abstract)) {
|
||||||
|
/* only for non abstract because abstract do not work in file system */
|
||||||
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
|
}
|
||||||
|
|
||||||
xfd->dtype = XIODATA_RECVFROM;
|
xfd->dtype = XIODATA_RECVFROM;
|
||||||
|
|
||||||
@ -277,15 +299,21 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i
|
|||||||
|
|
||||||
return
|
return
|
||||||
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
||||||
opts, xioflags, xfd, groups, pf, socktype, 0);
|
opts, xioflags, xfd, groups,
|
||||||
|
pf, socktype, protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
|
int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
|
||||||
int xioflags, xiofile_t *xfd, unsigned groups,
|
int xioflags, xiofile_t *xxfd, unsigned groups,
|
||||||
int pf, int socktype, int dummy3) {
|
int abstract, int dummy2, int dummy3) {
|
||||||
|
/* we expect the form: filename */
|
||||||
const char *name;
|
const char *name;
|
||||||
|
xiosingle_t *xfd = &xxfd->stream;
|
||||||
|
int pf = PF_UNIX;
|
||||||
|
int socktype = SOCK_DGRAM;
|
||||||
|
int protocol = 0;
|
||||||
struct sockaddr_un us;
|
struct sockaddr_un us;
|
||||||
socklen_t uslen;
|
socklen_t uslen;
|
||||||
bool tight = true;
|
bool tight = true;
|
||||||
@ -303,45 +331,53 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
|
|||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
uslen = xiosetunix(&us, name, false, tight);
|
uslen = xiosetunix(&us, name, abstract, tight);
|
||||||
|
|
||||||
xfd->stream.howtoend = END_NONE;
|
xfd->howtoend = END_NONE;
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
retropt_bind(opts, pf, socktype, 0, (struct sockaddr *)&us, &uslen, 1, 0, 0);
|
retropt_bind(opts, pf, socktype, 0, (struct sockaddr *)&us, &uslen, 1, 0, 0);
|
||||||
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
|
||||||
|
|
||||||
if (opt_unlink_close) {
|
if (!(ABSTRACT && abstract)) {
|
||||||
if ((xfd->stream.unlink_close = strdup(name)) == NULL) {
|
/* only for non abstract because abstract do not work in file system */
|
||||||
Error1("strdup(\"%s\"): out of memory", name);
|
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
||||||
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
|
if (opt_unlink_close) {
|
||||||
|
if ((xfd->unlink_close = strdup(name)) == NULL) {
|
||||||
|
Error1("strdup(\"%s\"): out of memory", name);
|
||||||
|
}
|
||||||
|
xfd->opt_unlink_close = true;
|
||||||
}
|
}
|
||||||
xfd->stream.opt_unlink_close = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opt_unlink_early) {
|
if (opt_unlink_early) {
|
||||||
if (Unlink(name) < 0) {
|
if (Unlink(name) < 0) {
|
||||||
if (errno == ENOENT) {
|
if (errno == ENOENT) {
|
||||||
Warn2("unlink(\"%s\"): %s", name, strerror(errno));
|
Warn2("unlink(\"%s\"): %s", name, strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
Error2("unlink(\"%s\"): %s", name, strerror(errno));
|
Error2("unlink(\"%s\"): %s", name, strerror(errno));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xfd->stream.para.socket.la.soa.sa_family = pf;
|
xfd->para.socket.la.soa.sa_family = pf;
|
||||||
|
|
||||||
xfd->stream.dtype = XIODATA_RECVFROM_ONE;
|
xfd->dtype = XIODATA_RECVFROM_ONE;
|
||||||
return _xioopen_dgram_recvfrom(&xfd->stream, xioflags,
|
return _xioopen_dgram_recvfrom(xfd, xioflags,
|
||||||
needbind?(struct sockaddr *)&us:NULL, uslen,
|
needbind?(struct sockaddr *)&us:NULL, uslen,
|
||||||
opts, pf, socktype, 0, E_ERROR);
|
opts, pf, socktype, protocol, E_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
||||||
int xioflags, xiofile_t *xfd, unsigned groups,
|
int xioflags, xiofile_t *xxfd, unsigned groups,
|
||||||
int pf, int socktype, int ipproto) {
|
int abstract, int dummy2, int dummy3) {
|
||||||
|
/* we expect the form: filename */
|
||||||
const char *name;
|
const char *name;
|
||||||
|
xiosingle_t *xfd = &xxfd->stream;
|
||||||
|
int pf = PF_UNIX;
|
||||||
|
int socktype = SOCK_DGRAM;
|
||||||
|
int protocol = 0;
|
||||||
union sockaddr_union us;
|
union sockaddr_union us;
|
||||||
socklen_t uslen;
|
socklen_t uslen;
|
||||||
bool tight = true;
|
bool tight = true;
|
||||||
@ -361,49 +397,54 @@ int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
|||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
uslen = xiosetunix(&us.un, name, false, tight);
|
uslen = xiosetunix(&us.un, name, abstract, tight);
|
||||||
|
|
||||||
#if 1 /*!!! why bind option? */
|
#if 1 /*!!! why bind option? */
|
||||||
retropt_bind(opts, pf, socktype, ipproto, &us.soa, &uslen, 1, 0, 0);
|
retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen, 1, 0, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
if (!(ABSTRACT && abstract)) {
|
||||||
if (opt_unlink_early) {
|
/* only for non abstract because abstract do not work in file system */
|
||||||
if (Unlink(name) < 0) {
|
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
||||||
if (errno == ENOENT) {
|
if (opt_unlink_early) {
|
||||||
Warn2("unlink(\"%s\"): %s", name, strerror(errno));
|
if (Unlink(name) < 0) {
|
||||||
} else {
|
if (errno == ENOENT) {
|
||||||
Error2("unlink(\"%s\"): %s", name, strerror(errno));
|
Warn2("unlink(\"%s\"): %s", name, strerror(errno));
|
||||||
|
} else {
|
||||||
|
Error2("unlink(\"%s\"): %s", name, strerror(errno));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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 ((xfd->stream.unlink_close = strdup(name)) == NULL) {
|
if ((xfd->unlink_close = strdup(name)) == NULL) {
|
||||||
Error1("strdup(\"%s\"): out of memory", name);
|
Error1("strdup(\"%s\"): out of memory", name);
|
||||||
|
}
|
||||||
|
xfd->opt_unlink_close = true;
|
||||||
}
|
}
|
||||||
xfd->stream.opt_unlink_close = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xfd->stream.para.socket.la.soa.sa_family = pf;
|
xfd->para.socket.la.soa.sa_family = pf;
|
||||||
|
|
||||||
xfd->stream.dtype = XIODATA_RECV;
|
xfd->dtype = XIODATA_RECV;
|
||||||
result = _xioopen_dgram_recv(&xfd->stream, xioflags, &us.soa, uslen,
|
result = _xioopen_dgram_recv(xfd, xioflags, &us.soa, uslen,
|
||||||
opts, pf, socktype, ipproto, E_ERROR);
|
opts, pf, socktype, protocol, E_ERROR);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) {
|
static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3) {
|
||||||
|
/* we expect the form: filename */
|
||||||
const char *name;
|
const char *name;
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
xiosingle_t *xfd = &xxfd->stream;
|
||||||
bool tight = true;
|
|
||||||
int pf = PF_UNIX;
|
int pf = PF_UNIX;
|
||||||
|
int socktype = 0; /* to be determined by server socket type */
|
||||||
|
int protocol = 0;
|
||||||
union sockaddr_union them, us;
|
union sockaddr_union them, us;
|
||||||
socklen_t themlen;
|
socklen_t themlen, uslen;
|
||||||
socklen_t uslen;
|
bool tight = true;
|
||||||
bool needbind = false;
|
bool needbind = false;
|
||||||
bool opt_unlink_close = false;
|
bool opt_unlink_close = false;
|
||||||
int result;
|
int result;
|
||||||
@ -420,9 +461,12 @@ static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, i
|
|||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
themlen = xiosetunix(&them.un, name, false, tight);
|
themlen = xiosetunix(&them.un, name, abstract, tight);
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
if (!(ABSTRACT && abstract)) {
|
||||||
|
/* only for non abstract because abstract do not work in file system */
|
||||||
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
|
}
|
||||||
|
|
||||||
if (retropt_bind(opts, pf, socktype, 0, &us.soa, &uslen, 0, 0, 0)
|
if (retropt_bind(opts, pf, socktype, 0, &us.soa, &uslen, 0, 0, 0)
|
||||||
!= STAT_NOACTION) {
|
!= STAT_NOACTION) {
|
||||||
@ -439,9 +483,10 @@ static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, i
|
|||||||
/* xfd->dtype = DATA_STREAM; // is default */
|
/* xfd->dtype = DATA_STREAM; // is default */
|
||||||
if ((result =
|
if ((result =
|
||||||
xioopen_connect(xfd,
|
xioopen_connect(xfd,
|
||||||
needbind?(struct sockaddr *)&us:NULL, uslen,
|
needbind?(struct sockaddr *)&us:NULL, uslen,
|
||||||
(struct sockaddr *)&them, themlen,
|
(struct sockaddr *)&them, themlen,
|
||||||
opts, PF_UNIX, socktype?socktype:SOCK_STREAM, 0, false)) != 0) {
|
opts, pf, socktype?socktype:SOCK_STREAM, protocol,
|
||||||
|
false)) != 0) {
|
||||||
if (errno == EPROTOTYPE) {
|
if (errno == EPROTOTYPE) {
|
||||||
if (needbind) {
|
if (needbind) {
|
||||||
Unlink(us.un.sun_path);
|
Unlink(us.un.sun_path);
|
||||||
@ -454,8 +499,8 @@ static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, i
|
|||||||
xfd->salen = sizeof(struct sockaddr_un);
|
xfd->salen = sizeof(struct sockaddr_un);
|
||||||
if ((result =
|
if ((result =
|
||||||
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
||||||
opts, xioflags, xfd, groups, pf,
|
opts, xioflags, xfd, groups,
|
||||||
socktype?socktype:SOCK_DGRAM, 0))
|
pf, socktype?socktype:SOCK_DGRAM, protocol))
|
||||||
!= 0) {
|
!= 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -468,277 +513,4 @@ static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, i
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if WITH_ABSTRACT_UNIXSOCKET
|
|
||||||
#if WITH_LISTEN
|
|
||||||
static int xioopen_abstract_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) {
|
|
||||||
/* we expect the form: filename */
|
|
||||||
const char *name;
|
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
|
||||||
bool tight = true;
|
|
||||||
struct sockaddr_un us;
|
|
||||||
socklen_t uslen;
|
|
||||||
struct opt *opts0 = NULL;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
|
||||||
}
|
|
||||||
|
|
||||||
socket_un_init(&us);
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
name = argv[1];
|
|
||||||
uslen = xiosetunix(&us, name, true, tight);
|
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
|
||||||
|
|
||||||
applyopts(-1, opts, PH_INIT);
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
|
||||||
applyopts(-1, opts, PH_EARLY);
|
|
||||||
|
|
||||||
/* trying to set user-early, perm-early etc. here is useless because
|
|
||||||
file system entry is available only past bind() call. */
|
|
||||||
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
|
||||||
|
|
||||||
opts0 = copyopts(opts, GROUP_ALL);
|
|
||||||
|
|
||||||
if ((result =
|
|
||||||
xioopen_listen(xfd, xioflags,
|
|
||||||
(struct sockaddr *)&us, uslen,
|
|
||||||
opts, opts0, PF_UNIX, socktype, 0))
|
|
||||||
!= 0)
|
|
||||||
return result;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* WITH_LISTEN */
|
|
||||||
|
|
||||||
static int xioopen_abstract_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) {
|
|
||||||
/* we expect the form: filename */
|
|
||||||
const char *name;
|
|
||||||
struct single *xfd = &xxfd->stream;
|
|
||||||
bool tight = true;
|
|
||||||
struct sockaddr_un them, us;
|
|
||||||
socklen_t themlen, uslen;
|
|
||||||
bool needbind = false;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
|
||||||
}
|
|
||||||
|
|
||||||
socket_un_init(&us);
|
|
||||||
socket_un_init(&them);
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
name = argv[1];
|
|
||||||
themlen = xiosetunix(&them, name, true, tight);
|
|
||||||
|
|
||||||
if (retropt_bind(opts, AF_UNIX, socktype, 0, (struct sockaddr *)&us, &uslen, 0, 0, 0)
|
|
||||||
!= STAT_NOACTION) {
|
|
||||||
needbind = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
applyopts(-1, opts, PH_INIT);
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
|
||||||
applyopts(-1, opts, PH_EARLY);
|
|
||||||
|
|
||||||
if ((result =
|
|
||||||
xioopen_connect(xfd,
|
|
||||||
needbind?(struct sockaddr *)&us:NULL, uslen,
|
|
||||||
(struct sockaddr *)&them, themlen,
|
|
||||||
opts, PF_UNIX, socktype, 0, false)) != 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if ((result = _xio_openlate(xfd, opts)) < 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int xioopen_abstract_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) {
|
|
||||||
const char *name;
|
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
|
||||||
union sockaddr_union us;
|
|
||||||
socklen_t uslen;
|
|
||||||
bool tight = true;
|
|
||||||
int pf = PF_UNIX;
|
|
||||||
bool needbind = false;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
|
||||||
}
|
|
||||||
|
|
||||||
uslen = socket_init(pf, &us);
|
|
||||||
xfd->salen = socket_init(pf, &xfd->peersa);
|
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
|
||||||
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
name = argv[1];
|
|
||||||
xfd->salen = xiosetunix(&xfd->peersa.un, name, true, tight);
|
|
||||||
|
|
||||||
xfd->dtype = XIODATA_RECVFROM;
|
|
||||||
|
|
||||||
if (retropt_bind(opts, pf, socktype, 0, &us.soa, &uslen, 0, 0, 0)
|
|
||||||
!= STAT_NOACTION) {
|
|
||||||
needbind = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
applyopts(-1, opts, PH_INIT);
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
|
||||||
|
|
||||||
return
|
|
||||||
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
|
||||||
opts, xioflags, xfd, groups, pf, socktype, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static
|
|
||||||
int xioopen_abstract_recvfrom(int argc, const char *argv[], struct opt *opts,
|
|
||||||
int xioflags, xiofile_t *xfd, unsigned groups,
|
|
||||||
int pf, int socktype, int dummy3) {
|
|
||||||
const char *name;
|
|
||||||
struct sockaddr_un us;
|
|
||||||
socklen_t uslen;
|
|
||||||
bool tight = true;
|
|
||||||
bool needbind = true;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
|
||||||
}
|
|
||||||
|
|
||||||
socket_un_init(&us);
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
name = argv[1];
|
|
||||||
uslen = xiosetunix(&us, name, true, tight);
|
|
||||||
|
|
||||||
xfd->stream.howtoend = END_NONE;
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
|
||||||
retropt_bind(opts, pf, socktype, 0, (struct sockaddr *)&us, &uslen, 1, 0, 0);
|
|
||||||
|
|
||||||
xfd->stream.para.socket.la.soa.sa_family = pf;
|
|
||||||
|
|
||||||
xfd->stream.dtype = XIODATA_RECVFROM_ONE;
|
|
||||||
return _xioopen_dgram_recvfrom(&xfd->stream, xioflags,
|
|
||||||
needbind?(struct sockaddr *)&us:NULL, uslen,
|
|
||||||
opts, pf, socktype, 0, E_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static
|
|
||||||
int xioopen_abstract_recv(int argc, const char *argv[], struct opt *opts,
|
|
||||||
int xioflags, xiofile_t *xfd, unsigned groups,
|
|
||||||
int pf, int socktype, int ipproto) {
|
|
||||||
const char *name;
|
|
||||||
union sockaddr_union us;
|
|
||||||
socklen_t uslen;
|
|
||||||
bool tight = true;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
|
||||||
}
|
|
||||||
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
|
||||||
|
|
||||||
socket_un_init(&us.un);
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
name = argv[1];
|
|
||||||
uslen = xiosetunix(&us.un, name, true, tight);
|
|
||||||
|
|
||||||
#if 1 /*!!! why bind option? */
|
|
||||||
retropt_bind(opts, pf, socktype, ipproto, &us.soa, &uslen, 1, 0, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
xfd->stream.para.socket.la.soa.sa_family = pf;
|
|
||||||
|
|
||||||
xfd->stream.dtype = XIODATA_RECV;
|
|
||||||
result = _xioopen_dgram_recv(&xfd->stream, xioflags, &us.soa, uslen,
|
|
||||||
opts, pf, socktype, ipproto, E_ERROR);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int xioopen_abstract_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) {
|
|
||||||
const char *name;
|
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
|
||||||
bool tight = true;
|
|
||||||
int pf = PF_UNIX;
|
|
||||||
union sockaddr_union them, us;
|
|
||||||
socklen_t themlen;
|
|
||||||
socklen_t uslen;
|
|
||||||
bool needbind = false;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
|
||||||
|
|
||||||
uslen = socket_init(pf, &us);
|
|
||||||
themlen = socket_init(pf, &them);
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
name = argv[1];
|
|
||||||
themlen = xiosetunix(&them.un, name, true, tight);
|
|
||||||
|
|
||||||
if (retropt_bind(opts, pf, socktype, 0, &us.soa, &uslen, 0, 0, 0)
|
|
||||||
!= STAT_NOACTION) {
|
|
||||||
needbind = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* xfd->dtype = DATA_STREAM; // is default */
|
|
||||||
if ((result =
|
|
||||||
xioopen_connect(xfd,
|
|
||||||
needbind?(struct sockaddr *)&us:NULL, uslen,
|
|
||||||
(struct sockaddr *)&them, themlen,
|
|
||||||
opts, PF_UNIX, socktype?socktype:SOCK_STREAM, 0, false)) != 0) {
|
|
||||||
if (errno == EPROTOTYPE) {
|
|
||||||
if (needbind) {
|
|
||||||
Unlink(us.un.sun_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ...res_opts[] */
|
|
||||||
applyopts(-1, opts, PH_INIT);
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
|
||||||
|
|
||||||
xfd->peersa = them;
|
|
||||||
xfd->salen = themlen;
|
|
||||||
if ((result =
|
|
||||||
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
|
||||||
opts, xioflags, xfd, groups, pf,
|
|
||||||
socktype?socktype:SOCK_DGRAM, 0))
|
|
||||||
!= 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
xfd->dtype = XIODATA_RECVFROM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((result = _xio_openlate(xfd, opts)) < 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* WITH_ABSTRACT_UNIXSOCKET */
|
|
||||||
|
|
||||||
#endif /* WITH_UNIX */
|
#endif /* WITH_UNIX */
|
||||||
|
16
xio-unix.h
16
xio-unix.h
@ -1,16 +1,16 @@
|
|||||||
/* source: xio-unix.h */
|
/* source: xio-unix.h */
|
||||||
/* Copyright Gerhard Rieger 2001-2007 */
|
/* Copyright Gerhard Rieger 2001-2008 */
|
||||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||||
|
|
||||||
#ifndef __xio_unix_h_included
|
#ifndef __xio_unix_h_included
|
||||||
#define __xio_unix_h_included 1
|
#define __xio_unix_h_included 1
|
||||||
|
|
||||||
extern const struct addrdesc addr_unix_connect;
|
extern const struct addrdesc xioaddr_unix_connect;
|
||||||
extern const struct addrdesc addr_unix_listen;
|
extern const struct addrdesc xioaddr_unix_listen;
|
||||||
extern const struct addrdesc addr_unix_sendto;
|
extern const struct addrdesc xioaddr_unix_sendto;
|
||||||
extern const struct addrdesc addr_unix_recvfrom;
|
extern const struct addrdesc xioaddr_unix_recvfrom;
|
||||||
extern const struct addrdesc addr_unix_recv;
|
extern const struct addrdesc xioaddr_unix_recv;
|
||||||
extern const struct addrdesc addr_unix_client;
|
extern const struct addrdesc xioaddr_unix_client;
|
||||||
extern const struct addrdesc xioaddr_abstract_connect;
|
extern const struct addrdesc xioaddr_abstract_connect;
|
||||||
extern const struct addrdesc xioaddr_abstract_listen;
|
extern const struct addrdesc xioaddr_abstract_listen;
|
||||||
extern const struct addrdesc xioaddr_abstract_sendto;
|
extern const struct addrdesc xioaddr_abstract_sendto;
|
||||||
@ -18,7 +18,7 @@ extern const struct addrdesc xioaddr_abstract_recvfrom;
|
|||||||
extern const struct addrdesc xioaddr_abstract_recv;
|
extern const struct addrdesc xioaddr_abstract_recv;
|
||||||
extern const struct addrdesc xioaddr_abstract_client;
|
extern const struct addrdesc xioaddr_abstract_client;
|
||||||
|
|
||||||
extern const struct optdesc opt_unix_tightsocklen;
|
extern const struct optdesc xioopt_unix_tightsocklen;
|
||||||
|
|
||||||
extern socklen_t
|
extern socklen_t
|
||||||
xiosetunix(struct sockaddr_un *saun,
|
xiosetunix(struct sockaddr_un *saun,
|
||||||
|
22
xioopen.c
22
xioopen.c
@ -1,5 +1,5 @@
|
|||||||
/* source: xioopen.c */
|
/* source: xioopen.c */
|
||||||
/* Copyright Gerhard Rieger 2001-2007 */
|
/* Copyright Gerhard Rieger 2001-2008 */
|
||||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||||
|
|
||||||
/* this is the source file of the extended open function */
|
/* this is the source file of the extended open function */
|
||||||
@ -106,7 +106,7 @@ const struct addrname addressnames[] = {
|
|||||||
#endif
|
#endif
|
||||||
#endif /* WITH_RAWIP */
|
#endif /* WITH_RAWIP */
|
||||||
#if WITH_UNIX
|
#if WITH_UNIX
|
||||||
{ "local", &addr_unix_connect },
|
{ "local", &xioaddr_unix_connect },
|
||||||
#endif
|
#endif
|
||||||
#if WITH_FILE
|
#if WITH_FILE
|
||||||
{ "open", &addr_open },
|
{ "open", &addr_open },
|
||||||
@ -231,19 +231,19 @@ const struct addrname addressnames[] = {
|
|||||||
{ "udp6-sendto", &addr_udp6_sendto },
|
{ "udp6-sendto", &addr_udp6_sendto },
|
||||||
#endif
|
#endif
|
||||||
#if WITH_UNIX
|
#if WITH_UNIX
|
||||||
{ "unix", &addr_unix_client },
|
{ "unix", &xioaddr_unix_client },
|
||||||
{ "unix-client", &addr_unix_client },
|
{ "unix-client", &xioaddr_unix_client },
|
||||||
{ "unix-connect", &addr_unix_connect },
|
{ "unix-connect", &xioaddr_unix_connect },
|
||||||
#endif
|
#endif
|
||||||
#if WITH_UNIX && WITH_LISTEN
|
#if WITH_UNIX && WITH_LISTEN
|
||||||
{ "unix-l", &addr_unix_listen },
|
{ "unix-l", &xioaddr_unix_listen },
|
||||||
{ "unix-listen", &addr_unix_listen },
|
{ "unix-listen", &xioaddr_unix_listen },
|
||||||
#endif
|
#endif
|
||||||
#if WITH_UNIX
|
#if WITH_UNIX
|
||||||
{ "unix-recv", &addr_unix_recv },
|
{ "unix-recv", &xioaddr_unix_recv },
|
||||||
{ "unix-recvfrom", &addr_unix_recvfrom },
|
{ "unix-recvfrom", &xioaddr_unix_recvfrom },
|
||||||
{ "unix-send", &addr_unix_sendto },
|
{ "unix-send", &xioaddr_unix_sendto },
|
||||||
{ "unix-sendto", &addr_unix_sendto },
|
{ "unix-sendto", &xioaddr_unix_sendto },
|
||||||
#endif
|
#endif
|
||||||
#else /* !0 */
|
#else /* !0 */
|
||||||
# if WITH_INTEGRATE
|
# if WITH_INTEGRATE
|
||||||
|
@ -1443,7 +1443,7 @@ const struct optname optionnames[] = {
|
|||||||
#ifdef O_TEXT
|
#ifdef O_TEXT
|
||||||
IF_ANY ("text", &opt_o_text)
|
IF_ANY ("text", &opt_o_text)
|
||||||
#endif
|
#endif
|
||||||
IF_UNIX ("tightsocklen", &opt_unix_tightsocklen)
|
IF_UNIX ("tightsocklen", &xioopt_unix_tightsocklen)
|
||||||
IF_TERMIOS("time", &opt_vtime)
|
IF_TERMIOS("time", &opt_vtime)
|
||||||
IF_TERMIOS("tiocsctty", &opt_tiocsctty)
|
IF_TERMIOS("tiocsctty", &opt_tiocsctty)
|
||||||
#if WITH_EXT2 && defined(EXT2_TOPDIR_FL)
|
#if WITH_EXT2 && defined(EXT2_TOPDIR_FL)
|
||||||
@ -1470,7 +1470,7 @@ const struct optname optionnames[] = {
|
|||||||
IF_NAMED ("uid-e", &opt_user_early)
|
IF_NAMED ("uid-e", &opt_user_early)
|
||||||
IF_ANY ("uid-l", &opt_user_late)
|
IF_ANY ("uid-l", &opt_user_late)
|
||||||
IF_NAMED ("umask", &opt_umask)
|
IF_NAMED ("umask", &opt_umask)
|
||||||
IF_UNIX ("unix-tightsocklen", &opt_unix_tightsocklen)
|
IF_UNIX ("unix-tightsocklen", &xioopt_unix_tightsocklen)
|
||||||
IF_NAMED ("unlink", &opt_unlink)
|
IF_NAMED ("unlink", &opt_unlink)
|
||||||
IF_NAMED ("unlink-close", &opt_unlink_close)
|
IF_NAMED ("unlink-close", &opt_unlink_close)
|
||||||
IF_NAMED ("unlink-early", &opt_unlink_early)
|
IF_NAMED ("unlink-early", &opt_unlink_early)
|
||||||
|
Loading…
Reference in New Issue
Block a user