diff --git a/CHANGES b/CHANGES index e78e07a..2e5a048 100644 --- a/CHANGES +++ b/CHANGES @@ -35,6 +35,9 @@ corrections: replaced the select() calls by poll() to cleanly fix the problems with many file descriptors already open +further changes: + cleanup in xio-unix.c + ####################### V 1.6.0.1: new features: diff --git a/test.sh b/test.sh index 5cbb3ec..aba5733 100755 --- a/test.sh +++ b/test.sh @@ -2364,7 +2364,7 @@ N=$((N+1)) NAME=UNIXSOCKET case "$TESTS" in -*%functions%*|*%$NAME%*) +*%functions%*|*%unix%*|*%$NAME%*) TEST="$NAME: echo via connection to UNIX domain socket" tf="$td/test$N.stdout" te="$td/test$N.stderr" diff --git a/xio-unix.c b/xio-unix.c index b0c6b95..a19ad6c 100644 --- a/xio-unix.c +++ b/xio-unix.c @@ -1,5 +1,5 @@ /* 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 */ /* this file contains the source for opening addresses of UNIX socket type */ @@ -15,52 +15,56 @@ #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); -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); -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); -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); +/* to avoid unneccessary "live" if () conditionals when no abstract support is + compiled in (or at least to give optimizing compilers a good chance) we need + a constant that can be used in C expressions */ +#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 int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, unsigned groups, - int pf, int socktype, int ipproto); + int xioflags, xiofile_t *xxfd, unsigned groups, + int abstract, int dummy2, int dummy3); 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(":") }; +#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(":") }; +#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(":") }; +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(":") }; +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(":") }; +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(":") }; #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); -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); -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); -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); -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); -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); +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(":") }; +#if WITH_LISTEN +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(":") }; +#endif /* WITH_LISTEN */ +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(":") }; +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(":") }; +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(":") }; +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(":") }; #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(":") }; -#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(":") }; -#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(":") }; -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(":") }; -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(":") }; -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(":") }; -#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(":") }; -#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(":") }; -#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(":") }; -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(":") }; -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(":") }; -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(":") }; -#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 }; +const struct optdesc xioopt_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 xiosetunix(struct sockaddr_un *saun, const char *path, @@ -69,22 +73,8 @@ xiosetunix(struct sockaddr_un *saun, size_t pathlen; socklen_t len; - if (!abstract) { - 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)); -#if HAVE_STRUCT_SOCKADDR_SALEN - saun->sun_len = len; -#endif - } else { - len = sizeof(struct sockaddr_un); - } - } else { +#ifdef WITH_ABSTRACT_UNIXSOCKET + if (abstract) { if ((pathlen = strlen(path)) >= sizeof(saun->sun_path)) { Warn2("socket address "F_Zu" characters long, truncating to "F_Zu"", pathlen+1, sizeof(saun->sun_path)); @@ -100,15 +90,32 @@ xiosetunix(struct sockaddr_un *saun, } else { 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; } #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 */ const char *name; xiosingle_t *xfd = &xxfd->stream; + int pf = PF_UNIX; + int socktype = SOCK_STREAM; + int protocol = 0; struct sockaddr_un us; socklen_t uslen; 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); name = argv[1]; - uslen = xiosetunix(&us, name, false, 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; - } + uslen = xiosetunix(&us, name, abstract, tight); 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); if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_EARLY); - if (opt_unlink_early) { - if (Unlink(name) < 0) { - if (errno == ENOENT) { - Warn2("unlink(\"%s\"): %s", name, strerror(errno)); - } else { - Error2("unlink(\"%s\"): %s", name, strerror(errno)); + if (!(ABSTRACT && abstract)) { + if (opt_unlink_early) { + if (Unlink(name) < 0) { + if (errno == ENOENT) { + Warn2("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 - file system entry is available only past bind() call. */ - applyopts_named(name, opts, PH_EARLY); /* umask! */ + /* trying to set user-early, perm-early etc. here is useless because + file system entry is available only past bind() call. */ + applyopts_named(name, opts, PH_EARLY); /* umask! */ + } 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 = xioopen_listen(xfd, xioflags, (struct sockaddr *)&us, uslen, - opts, opts0, PF_UNIX, socktype, 0)) + opts, opts0, pf, socktype, protocol)) != 0) return result; return 0; @@ -174,10 +185,13 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i #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 */ const char *name; struct single *xfd = &xxfd->stream; + int pf = PF_UNIX; + int socktype = SOCK_STREAM; + int protocol = 0; struct sockaddr_un them, us; socklen_t themlen, uslen; 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); name = argv[1]; - themlen = xiosetunix(&them, name, false, tight); - retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); - + themlen = xiosetunix(&them, name, abstract, tight); + 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) != STAT_NOACTION) { needbind = true; @@ -219,7 +235,7 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, xioopen_connect(xfd, needbind?(struct sockaddr *)&us:NULL, uslen, (struct sockaddr *)&them, themlen, - opts, PF_UNIX, socktype, 0, false)) != 0) { + opts, pf, socktype, protocol, false)) != 0) { return result; } 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; xiosingle_t *xfd = &xxfd->stream; + int pf = PF_UNIX; + int socktype = SOCK_DGRAM; + int protocol = 0; union sockaddr_union us; socklen_t uslen; bool tight = true; - int pf = PF_UNIX; bool needbind = 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); 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; @@ -277,15 +299,21 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i return _xioopen_dgram_sendto(needbind?&us:NULL, uslen, - opts, xioflags, xfd, groups, pf, socktype, 0); + opts, xioflags, xfd, groups, + pf, socktype, protocol); } static int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, unsigned groups, - int pf, int socktype, int dummy3) { + int xioflags, xiofile_t *xxfd, unsigned groups, + int abstract, int dummy2, int dummy3) { + /* we expect the form: filename */ const char *name; + xiosingle_t *xfd = &xxfd->stream; + int pf = PF_UNIX; + int socktype = SOCK_DGRAM; + int protocol = 0; struct sockaddr_un us; socklen_t uslen; 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); 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_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 ((xfd->stream.unlink_close = strdup(name)) == NULL) { - Error1("strdup(\"%s\"): out of memory", name); + 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; } - xfd->stream.opt_unlink_close = true; - } - if (opt_unlink_early) { - if (Unlink(name) < 0) { - if (errno == ENOENT) { - Warn2("unlink(\"%s\"): %s", name, strerror(errno)); - } else { - Error2("unlink(\"%s\"): %s", name, strerror(errno)); + if (opt_unlink_early) { + if (Unlink(name) < 0) { + if (errno == ENOENT) { + Warn2("unlink(\"%s\"): %s", name, strerror(errno)); + } else { + 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; - return _xioopen_dgram_recvfrom(&xfd->stream, xioflags, + xfd->dtype = XIODATA_RECVFROM_ONE; + return _xioopen_dgram_recvfrom(xfd, xioflags, needbind?(struct sockaddr *)&us:NULL, uslen, - opts, pf, socktype, 0, E_ERROR); + opts, pf, socktype, protocol, E_ERROR); } static int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, unsigned groups, - int pf, int socktype, int ipproto) { + int xioflags, xiofile_t *xxfd, unsigned groups, + int abstract, int dummy2, int dummy3) { + /* we expect the form: filename */ const char *name; + xiosingle_t *xfd = &xxfd->stream; + int pf = PF_UNIX; + int socktype = SOCK_DGRAM; + int protocol = 0; union sockaddr_union us; socklen_t uslen; 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); name = argv[1]; - uslen = xiosetunix(&us.un, name, false, tight); + uslen = xiosetunix(&us.un, name, abstract, tight); #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 - retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early); - if (opt_unlink_early) { - if (Unlink(name) < 0) { - if (errno == ENOENT) { - Warn2("unlink(\"%s\"): %s", name, strerror(errno)); - } else { - Error2("unlink(\"%s\"): %s", name, strerror(errno)); + if (!(ABSTRACT && abstract)) { + /* only for non abstract because abstract do not work in file system */ + retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early); + if (opt_unlink_early) { + if (Unlink(name) < 0) { + if (errno == ENOENT) { + 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 ((xfd->stream.unlink_close = strdup(name)) == NULL) { - Error1("strdup(\"%s\"): out of memory", name); + 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; } - xfd->stream.para.socket.la.soa.sa_family = pf; + xfd->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); + xfd->dtype = XIODATA_RECV; + result = _xioopen_dgram_recv(xfd, xioflags, &us.soa, uslen, + opts, pf, socktype, protocol, E_ERROR); 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; xiosingle_t *xfd = &xxfd->stream; - bool tight = true; int pf = PF_UNIX; + int socktype = 0; /* to be determined by server socket type */ + int protocol = 0; union sockaddr_union them, us; - socklen_t themlen; - socklen_t uslen; + socklen_t themlen, uslen; + bool tight = true; bool needbind = false; bool opt_unlink_close = false; 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); 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) != 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 */ if ((result = xioopen_connect(xfd, - needbind?(struct sockaddr *)&us:NULL, uslen, + needbind?(struct sockaddr *)&us:NULL, uslen, (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 (needbind) { 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); if ((result = _xioopen_dgram_sendto(needbind?&us:NULL, uslen, - opts, xioflags, xfd, groups, pf, - socktype?socktype:SOCK_DGRAM, 0)) + opts, xioflags, xfd, groups, + pf, socktype?socktype:SOCK_DGRAM, protocol)) != 0) { return result; } @@ -468,277 +513,4 @@ static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, i 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 */ diff --git a/xio-unix.h b/xio-unix.h index 9b09efe..9d9ad51 100644 --- a/xio-unix.h +++ b/xio-unix.h @@ -1,16 +1,16 @@ /* 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 */ #ifndef __xio_unix_h_included #define __xio_unix_h_included 1 -extern const struct addrdesc addr_unix_connect; -extern const struct addrdesc addr_unix_listen; -extern const struct addrdesc addr_unix_sendto; -extern const struct addrdesc addr_unix_recvfrom; -extern const struct addrdesc addr_unix_recv; -extern const struct addrdesc addr_unix_client; +extern const struct addrdesc xioaddr_unix_connect; +extern const struct addrdesc xioaddr_unix_listen; +extern const struct addrdesc xioaddr_unix_sendto; +extern const struct addrdesc xioaddr_unix_recvfrom; +extern const struct addrdesc xioaddr_unix_recv; +extern const struct addrdesc xioaddr_unix_client; extern const struct addrdesc xioaddr_abstract_connect; extern const struct addrdesc xioaddr_abstract_listen; 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_client; -extern const struct optdesc opt_unix_tightsocklen; +extern const struct optdesc xioopt_unix_tightsocklen; extern socklen_t xiosetunix(struct sockaddr_un *saun, diff --git a/xioopen.c b/xioopen.c index f944740..60ff998 100644 --- a/xioopen.c +++ b/xioopen.c @@ -1,5 +1,5 @@ /* 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 */ /* this is the source file of the extended open function */ @@ -106,7 +106,7 @@ const struct addrname addressnames[] = { #endif #endif /* WITH_RAWIP */ #if WITH_UNIX - { "local", &addr_unix_connect }, + { "local", &xioaddr_unix_connect }, #endif #if WITH_FILE { "open", &addr_open }, @@ -231,19 +231,19 @@ const struct addrname addressnames[] = { { "udp6-sendto", &addr_udp6_sendto }, #endif #if WITH_UNIX - { "unix", &addr_unix_client }, - { "unix-client", &addr_unix_client }, - { "unix-connect", &addr_unix_connect }, + { "unix", &xioaddr_unix_client }, + { "unix-client", &xioaddr_unix_client }, + { "unix-connect", &xioaddr_unix_connect }, #endif #if WITH_UNIX && WITH_LISTEN - { "unix-l", &addr_unix_listen }, - { "unix-listen", &addr_unix_listen }, + { "unix-l", &xioaddr_unix_listen }, + { "unix-listen", &xioaddr_unix_listen }, #endif #if WITH_UNIX - { "unix-recv", &addr_unix_recv }, - { "unix-recvfrom", &addr_unix_recvfrom }, - { "unix-send", &addr_unix_sendto }, - { "unix-sendto", &addr_unix_sendto }, + { "unix-recv", &xioaddr_unix_recv }, + { "unix-recvfrom", &xioaddr_unix_recvfrom }, + { "unix-send", &xioaddr_unix_sendto }, + { "unix-sendto", &xioaddr_unix_sendto }, #endif #else /* !0 */ # if WITH_INTEGRATE diff --git a/xioopts.c b/xioopts.c index ad76434..291f3ae 100644 --- a/xioopts.c +++ b/xioopts.c @@ -1443,7 +1443,7 @@ const struct optname optionnames[] = { #ifdef O_TEXT IF_ANY ("text", &opt_o_text) #endif - IF_UNIX ("tightsocklen", &opt_unix_tightsocklen) + IF_UNIX ("tightsocklen", &xioopt_unix_tightsocklen) IF_TERMIOS("time", &opt_vtime) IF_TERMIOS("tiocsctty", &opt_tiocsctty) #if WITH_EXT2 && defined(EXT2_TOPDIR_FL) @@ -1470,7 +1470,7 @@ const struct optname optionnames[] = { IF_NAMED ("uid-e", &opt_user_early) IF_ANY ("uid-l", &opt_user_late) 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-close", &opt_unlink_close) IF_NAMED ("unlink-early", &opt_unlink_early)