static char** arg_listen = NULL;
static bool arg_accept = false;
+static bool arg_datagram = false;
static char** arg_args = NULL;
static char** arg_setenv = NULL;
static const char *arg_fdname = NULL;
STRV_FOREACH(address, arg_listen) {
- fd = make_socket_fd(LOG_DEBUG, *address, SOCK_STREAM | (arg_accept*SOCK_CLOEXEC));
+ if (arg_datagram)
+ fd = make_socket_fd(LOG_DEBUG, *address, SOCK_DGRAM, SOCK_CLOEXEC);
+ else
+ fd = make_socket_fd(LOG_DEBUG, *address, SOCK_STREAM, (arg_accept*SOCK_CLOEXEC));
+
if (fd < 0) {
log_open();
return log_error_errno(fd, "Failed to open '%s': %m", *address);
printf("%s [OPTIONS...]\n\n"
"Listen on sockets and launch child on connection.\n\n"
"Options:\n"
+ " -d --datagram Datagram sockets\n"
" -l --listen=ADDR Listen for raw connections at ADDR\n"
" -a --accept Spawn separate child for each connection\n"
" -h --help Show this help and exit\n"
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, ARG_VERSION },
+ { "datagram", no_argument, NULL, 'd' },
{ "listen", required_argument, NULL, 'l' },
{ "accept", no_argument, NULL, 'a' },
{ "setenv", required_argument, NULL, 'E' },
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "+hl:aE:", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "+hl:aEd", options, NULL)) >= 0)
switch(c) {
case 'h':
help();
break;
+ case 'd':
+ arg_datagram = true;
+ break;
+
case 'a':
arg_accept = true;
break;
return -EINVAL;
}
+ if (arg_datagram && arg_accept) {
+ log_error("Datagram sockets do not accept connections. "
+ "The --datagram and --accept options may not be combined.");
+ return -EINVAL;
+ }
+
arg_args = argv + optind;
return 1 /* work to do */;
return r;
}
-int make_socket_fd(int log_level, const char* address, int flags) {
+int make_socket_fd(int log_level, const char* address, int type, int flags) {
SocketAddress a;
int fd, r;
if (r < 0)
return log_error_errno(r, "Failed to parse socket address \"%s\": %m", address);
- fd = socket_address_listen(&a, flags, SOMAXCONN, SOCKET_ADDRESS_DEFAULT,
+ a.type = type;
+
+ fd = socket_address_listen(&a, type | flags, SOMAXCONN, SOCKET_ADDRESS_DEFAULT,
NULL, false, false, false, 0755, 0644, NULL);
if (fd < 0 || log_get_max_level() >= log_level) {
_cleanup_free_ char *p = NULL;
static int setup_raw_socket(RemoteServer *s, const char *address) {
int fd;
- fd = make_socket_fd(LOG_INFO, address, SOCK_STREAM | SOCK_CLOEXEC);
+ fd = make_socket_fd(LOG_INFO, address, SOCK_STREAM, SOCK_CLOEXEC);
if (fd < 0)
return fd;
const char *trust) {
int fd;
- fd = make_socket_fd(LOG_DEBUG, address, SOCK_STREAM | SOCK_CLOEXEC);
+ fd = make_socket_fd(LOG_DEBUG, address, SOCK_STREAM, SOCK_CLOEXEC);
if (fd < 0)
return fd;