aboutsummaryrefslogtreecommitdiff
path: root/src/ctl.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2016-02-18 15:23:30 +0200
committerSergey Poznyakoff <gray@gnu.org>2016-02-18 15:33:34 +0200
commit0a55965bcc28928ae17ca39e3b8e35adf11ea09c (patch)
treeed8f6543999caef2d81b517fb90182be4a984fda /src/ctl.c
parentd5302613a00915076b945b25b50eb6b376121955 (diff)
downloadpies-0a55965bcc28928ae17ca39e3b8e35adf11ea09c.tar.gz
pies-0a55965bcc28928ae17ca39e3b8e35adf11ea09c.tar.bz2
Fix activation/deactivation of network listeners.
* src/ctl.c (prog_active): New function. (prog_serialize): Use prog_active to report prog's activity state. For listener components, return also their service and tcpmux master names, if applicable. (fun_stop): Stop listeners as well. (fun_start): Start listeners. (ctlio_end): Don't close fd: this is done by deregister_socket * src/inetd-bi.c (tcpmux_help): Don't list inactive components. * src/prog.h (prog_activate_listener) (prog_deactivate_listener): New protos. * src/progman.c (prog_lookup_by_tag) (prog_lookup_by_service): Remove. (progman_cleanup): Fix coredump (premature free). (progman_stop_component): If component is a listener, deactivate it. (prog_activate_listener) (prog_deactivate_listener): New functions. * src/socket.c (delete_sockinst): Close the socket descriptor. * src/sysvinit.c (sysvinit_fifo_handler, create_fifo): Don't close fd, leave that to deregister_socket.
Diffstat (limited to 'src/ctl.c')
-rw-r--r--src/ctl.c67
1 files changed, 51 insertions, 16 deletions
diff --git a/src/ctl.c b/src/ctl.c
index 6e162e5..54282a2 100644
--- a/src/ctl.c
+++ b/src/ctl.c
@@ -529,13 +529,12 @@ ctlio_reset (struct ctlio *io)
}
static int
ctlio_end (int fd, struct ctlio *io)
{
deregister_socket (fd);
- close (fd);
ctlio_destroy (io);
return 1;
}
static char const *
http_text (int code)
@@ -1813,12 +1812,30 @@ selector (struct prog *prog, void *data)
else
env->noperm_count++;
}
return 0;
}
+/* Return true if PROG is active. For TCPMUX progs, this takes into account
+ the state of the master listener.
+ FIXME: Ideally all TCPMUXen must form a list attached to their master
+ listener. When this is fixed, this function will disappear. */
+static int
+prog_active (struct prog *prog)
+{
+ if (prog->v.p.active)
+ {
+ if (ISCF_TCPMUX (prog->v.p.comp->flags))
+ {
+ prog = progman_locate (prog->v.p.comp->tcpmux);
+ return prog && prog->v.p.active;
+ }
+ }
+ return prog->v.p.active;
+}
+
static struct json_value *
prog_serialize (struct json_value *ret, struct prog *prog)
{
struct json_value *v;
size_t i;
@@ -1826,20 +1843,29 @@ prog_serialize (struct json_value *ret, struct prog *prog)
switch (prog->type)
{
case TYPE_COMPONENT:
FORMAT_IDX (ret, "mode", pies_comp_mode_str, prog->v.p.comp->mode);
FORMAT_IDX (ret, "status", pies_status_str, prog->v.p.status);
- json_object_set_bool (ret, "active", prog->v.p.active);
+ json_object_set_bool (ret, "active", prog_active (prog));
if (prog->pid)
json_object_set_number (ret, "PID", prog->pid);
- else if (prog->v.p.status == status_listener
- && prog->v.p.comp->socket_url)
- json_object_set_string (ret, "URL", "%s",
- prog->v.p.comp->socket_url->string);
+ else if (prog->v.p.status == status_listener)
+ {
+ if (prog->v.p.comp->socket_url)
+ json_object_set_string (ret, "URL", "%s",
+ prog->v.p.comp->socket_url->string);
+ if (prog->v.p.comp->service)
+ json_object_set_string (ret, "service", "%s",
+ prog->v.p.comp->service);
+ if (ISCF_TCPMUX (prog->v.p.comp->flags) && prog->v.p.comp->tcpmux)
+ json_object_set_string (ret, "master", "%s",
+ prog->v.p.comp->tcpmux);
+ }
+
if (prog->v.p.comp->runlevels)
json_object_set_string (ret, "runlevels", "%s",
prog->v.p.comp->runlevels);
if (prog->v.p.status == status_sleeping)
@@ -1869,52 +1895,61 @@ fun_list (struct json_value *result, struct prog *prog)
return 0;
}
static int
fun_stop (struct json_value *result, struct prog *prog)
{
- if (prog->v.p.active && prog->v.p.status == status_stopped)
- {
-
+ if (!prog->v.p.active)
+ {
json_object_set_string (result, "status", "ER");
json_object_set_string (result, "error_message", "already stopped");
return 1;
}
- else
- {
- prog->v.p.active = 0;
- progman_stop_component (&prog);
- json_object_set_string (result, "status", "OK");
- }
+
+ prog->v.p.active = 0;
+ progman_stop_component (&prog);
+ json_object_set_string (result, "status", "OK");
return 0;
}
static int
fun_start (struct json_value *result, struct prog *prog)
{
switch (prog->v.p.status)
{
case status_stopped:
prog->v.p.comp->flags &= ~CF_DISABLED;
- prog->v.p.active = 1;
json_object_set_string (result, "status", "OK");
break;
case status_sleeping:
case status_finished:
prog->v.p.status = status_stopped;
prog->v.p.failcount = 0;
prog->v.p.timestamp = 0;
json_object_set_string (result, "status", "OK");
break;
+
+ case status_listener:
+ if (prog_activate_listener (prog) == 0)
+ json_object_set_string (result, "status", "OK");
+ else
+ {
+ json_object_set_string (result, "status", "ER");
+ /* FIXME: error message */
+ json_object_set_string (result, "error_message",
+ "can't open socket");
+ }
+ break;
default:
json_object_set_string (result, "status", "ER");
json_object_set_string (result, "error_message", "already running");
return 1;
}
+ prog->v.p.active = 1;
return 0;
}
static int
fun_restart (struct json_value *result, struct prog *prog)
{

Return to:

Send suggestions and report system problems to the System administrator.