chiark
/
gitweb
/
~ianmdlvl
/
elogind.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
unit-name: fix unit name escaping
[elogind.git]
/
src
/
service.c
diff --git
a/src/service.c
b/src/service.c
index d9e0b209d264f016d8f5dc119963d44b21a03098..116e539d951df7303039759645589b54b0e49342 100644
(file)
--- a/
src/service.c
+++ b/
src/service.c
@@
-178,11
+178,11
@@
static void service_close_socket_fd(Service *s) {
static void service_connection_unref(Service *s) {
assert(s);
static void service_connection_unref(Service *s) {
assert(s);
- if (!s->socket)
+ if (!s->
accept_
socket)
return;
return;
- socket_connection_unref(s->socket);
- s->socket = NULL;
+ socket_connection_unref(s->
accept_
socket);
+ s->
accept_
socket = NULL;
}
static void service_done(Unit *u) {
}
static void service_done(Unit *u) {
@@
-222,6
+222,8
@@
static void service_done(Unit *u) {
service_close_socket_fd(s);
service_connection_unref(s);
service_close_socket_fd(s);
service_connection_unref(s);
+ set_free(s->configured_sockets);
+
unit_unwatch_timer(u, &s->timer_watch);
}
unit_unwatch_timer(u, &s->timer_watch);
}
@@
-250,7
+252,7
@@
static char *sysv_translate_name(const char *name) {
return r;
}
return r;
}
-static int sysv_translate_facility(const char *name, char **_r) {
+static int sysv_translate_facility(const char *name, c
onst char *filename, c
har **_r) {
/* We silently ignore the $ prefix here. According to the LSB
* spec it simply indicates whether something is a
/* We silently ignore the $ prefix here. According to the LSB
* spec it simply indicates whether something is a
@@
-289,28
+291,39
@@
static int sysv_translate_facility(const char *name, char **_r) {
unsigned i;
char *r;
unsigned i;
char *r;
+ const char *n;
- for (i = 0; i < ELEMENTSOF(table); i += 2)
+ assert(name);
+ assert(_r);
- if (streq(table[i], name) ||
- (*name == '$' && streq(table[i], name+1))) {
+ n = *name == '$' ? name + 1 : name;
- if (!table[i+1])
- return 0;
+ for (i = 0; i < ELEMENTSOF(table); i += 2) {
-
if (!(r = strdup(table[i+1])
))
-
return -ENOMEM
;
+
if (!streq(table[i], n
))
+
continue
;
- goto finish;
- }
+ if (!table[i+1])
+ return 0;
+
+ if (!(r = strdup(table[i+1])))
+ return -ENOMEM;
+
+ goto finish;
+ }
/* If we don't know this name, fallback heuristics to figure
* out whether something is a target or an service alias. */
if (*name == '$')
/* If we don't know this name, fallback heuristics to figure
* out whether something is a target or an service alias. */
if (*name == '$')
- r = unit_name_build(name+1, NULL, ".target");
+ /* Facilities starting with $ are most likely targets */
+ r = unit_name_build(n, NULL, ".target");
+ else if (filename && streq(name, filename))
+ /* Names equalling the file name of the services are redundant */
+ return 0;
else
else
- r = sysv_translate_name(name);
+ /* Everything else we assume to be normal service names */
+ r = sysv_translate_name(n);
if (!r)
return -ENOMEM;
if (!r)
return -ENOMEM;
@@
-612,12
+625,7
@@
static int service_load_sysv_path(Service *s, const char *path) {
goto finish;
}
goto finish;
}
- if (streq(n, file_name_from_path(path))) {
- free(n);
- continue;
- }
-
- r = sysv_translate_facility(n, &m);
+ r = sysv_translate_facility(n, file_name_from_path(path), &m);
free(n);
if (r < 0)
free(n);
if (r < 0)
@@
-662,12
+670,7
@@
static int service_load_sysv_path(Service *s, const char *path) {
goto finish;
}
goto finish;
}
- if (streq(n, file_name_from_path(path))) {
- free(n);
- continue;
- }
-
- r = sysv_translate_facility(n, &m);
+ r = sysv_translate_facility(n, file_name_from_path(path), &m);
free(n);
if (r < 0)
free(n);
if (r < 0)
@@
-792,7
+795,7
@@
static int service_load_sysv_path(Service *s, const char *path) {
/* Special setting for all SysV services */
s->type = SERVICE_FORKING;
s->remain_after_exit = true;
/* Special setting for all SysV services */
s->type = SERVICE_FORKING;
s->remain_after_exit = true;
- s->restart = SERVICE_
ONCE
;
+ s->restart = SERVICE_
RESTART_NO
;
s->exec_context.std_output =
(s->meta.manager->sysv_console || s->exec_context.std_input == EXEC_INPUT_TTY)
? EXEC_OUTPUT_TTY : EXEC_OUTPUT_NULL;
s->exec_context.std_output =
(s->meta.manager->sysv_console || s->exec_context.std_input == EXEC_INPUT_TTY)
? EXEC_OUTPUT_TTY : EXEC_OUTPUT_NULL;
@@
-1176,6
+1179,9
@@
static int service_get_sockets(Service *s, Set **_set) {
if (s->socket_fd >= 0)
return 0;
if (s->socket_fd >= 0)
return 0;
+ if (!set_isempty(s->configured_sockets))
+ return 0;
+
/* Collects all Socket objects that belong to this
* service. Note that a service might have multiple sockets
* via multiple names. */
/* Collects all Socket objects that belong to this
* service. Note that a service might have multiple sockets
* via multiple names. */
@@
-1215,23
+1221,30
@@
fail:
static int service_notify_sockets_dead(Service *s) {
Iterator i;
static int service_notify_sockets_dead(Service *s) {
Iterator i;
- Set *set;
+ Set *set
, *free_set = NULL
;
Socket *sock;
int r;
assert(s);
Socket *sock;
int r;
assert(s);
+ /* Notifies all our sockets when we die */
+
if (s->socket_fd >= 0)
return 0;
if (s->socket_fd >= 0)
return 0;
- /* Notifies all our sockets when we die */
- if ((r = service_get_sockets(s, &set)) < 0)
- return r;
+ if (!set_isempty(s->configured_sockets))
+ set = s->configured_sockets;
+ else {
+ if ((r = service_get_sockets(s, &free_set)) < 0)
+ return r;
+
+ set = free_set;
+ }
SET_FOREACH(sock, set, i)
socket_notify_service_dead(sock);
SET_FOREACH(sock, set, i)
socket_notify_service_dead(sock);
- set_free(set);
+ set_free(
free_
set);
return 0;
}
return 0;
}
@@
-1389,7
+1402,7
@@
static int service_collect_fds(Service *s, int **fds, unsigned *n_fds) {
int r;
int *rfds = NULL;
unsigned rn_fds = 0;
int r;
int *rfds = NULL;
unsigned rn_fds = 0;
- Set *set;
+ Set *set
, *free_set = NULL
;
Socket *sock;
assert(s);
Socket *sock;
assert(s);
@@
-1399,8
+1412,14
@@
static int service_collect_fds(Service *s, int **fds, unsigned *n_fds) {
if (s->socket_fd >= 0)
return 0;
if (s->socket_fd >= 0)
return 0;
- if ((r = service_get_sockets(s, &set)) < 0)
- return r;
+ if (!set_isempty(s->configured_sockets))
+ set = s->configured_sockets;
+ else {
+ if ((r = service_get_sockets(s, &free_set)) < 0)
+ return r;
+
+ set = free_set;
+ }
SET_FOREACH(sock, set, i) {
int *cfds;
SET_FOREACH(sock, set, i) {
int *cfds;
@@
-1437,7
+1456,7
@@
static int service_collect_fds(Service *s, int **fds, unsigned *n_fds) {
*fds = rfds;
*n_fds = rn_fds;
*fds = rfds;
*n_fds = rn_fds;
- set_free(set);
+ set_free(
free_
set);
return 0;
return 0;
@@
-2083,14
+2102,6
@@
static int service_start(Unit *u) {
return -ECANCELED;
}
return -ECANCELED;
}
- if ((s->exec_context.std_input == EXEC_INPUT_SOCKET ||
- s->exec_context.std_output == EXEC_OUTPUT_SOCKET ||
- s->exec_context.std_error == EXEC_OUTPUT_SOCKET) &&
- s->socket_fd < 0) {
- log_warning("%s can only be started with a per-connection socket.", u->meta.id);
- return -EINVAL;
- }
-
s->failure = false;
s->main_pid_known = false;
s->forbid_restart = false;
s->failure = false;
s->main_pid_known = false;
s->forbid_restart = false;
@@
-3061,7
+3072,7
@@
int service_set_socket_fd(Service *s, int fd, Socket *sock) {
s->socket_fd = fd;
s->got_socket_fd = true;
s->socket_fd = fd;
s->got_socket_fd = true;
- s->socket = sock;
+ s->
accept_
socket = sock;
return 0;
}
return 0;
}
@@
-3098,9
+3109,9
@@
static const char* const service_state_table[_SERVICE_STATE_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(service_state, ServiceState);
static const char* const service_restart_table[_SERVICE_RESTART_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(service_state, ServiceState);
static const char* const service_restart_table[_SERVICE_RESTART_MAX] = {
- [SERVICE_
ONCE] = "once
",
- [SERVICE_RESTART_ON_SUCCESS] = "
restart-
on-success",
- [SERVICE_RESTART_ALWAYS] = "
restart-
always",
+ [SERVICE_
RESTART_NO] = "no
",
+ [SERVICE_RESTART_ON_SUCCESS] = "on-success",
+ [SERVICE_RESTART_ALWAYS] = "always",
};
DEFINE_STRING_TABLE_LOOKUP(service_restart, ServiceRestart);
};
DEFINE_STRING_TABLE_LOOKUP(service_restart, ServiceRestart);