]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blobdiff - src/process.c
Re-enable SIGPIPE for children so they have default behaviour
[sojka/lightdm.git] / src / process.c
index 4328dcd067df19b4a9b6364f6f649c5aebe87c03..75357db615b99466fe31b0988479cbfb8d102395 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2010-2011 Robert Ancell.
  * Author: Robert Ancell <robert.ancell@canonical.com>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify it under
  * the terms of the GNU General Public License as published by the Free Software
  * Foundation, either version 3 of the License, or (at your option) any later
 #include <fcntl.h>
 #include <signal.h>
 #include <grp.h>
-#include <glib/gstdio.h>
 #include <config.h>
 
+#include "log-file.h"
 #include "process.h"
 
 enum {
     GOT_DATA,
-    GOT_SIGNAL,  
+    GOT_SIGNAL,
     STOPPED,
     LAST_SIGNAL
 };
@@ -39,6 +39,7 @@ struct ProcessPrivate
     /* File to log to */
     gchar *log_file;
     gboolean log_stdout;
+    LogMode log_mode;
 
     /* Command to run */
     gchar *command;
@@ -51,7 +52,7 @@ struct ProcessPrivate
 
     /* Process ID */
     GPid pid;
-  
+
     /* Exit status of process */
     int exit_status;
 
@@ -90,16 +91,18 @@ process_new (ProcessRunFunc run_func, gpointer run_func_data)
     Process *process = g_object_new (PROCESS_TYPE, NULL);
     process->priv->run_func = run_func;
     process->priv->run_func_data = run_func_data;
+    process->priv->log_mode = LOG_MODE_INVALID;
     return process;
 }
 
 void
-process_set_log_file (Process *process, const gchar *path, gboolean log_stdout)
+process_set_log_file (Process *process, const gchar *path, gboolean log_stdout, LogMode log_mode)
 {
     g_return_if_fail (process != NULL);
     g_free (process->priv->log_file);
     process->priv->log_file = g_strdup (path);
     process->priv->log_stdout = log_stdout;
+    process->priv->log_mode = log_mode;
 }
 
 void
@@ -121,7 +124,7 @@ process_set_env (Process *process, const gchar *name, const gchar *value)
 {
     g_return_if_fail (process != NULL);
     g_return_if_fail (name != NULL);
-    g_hash_table_insert (process->priv->env, g_strdup (name), g_strdup (value));  
+    g_hash_table_insert (process->priv->env, g_strdup (name), g_strdup (value));
 }
 
 const gchar *
@@ -163,7 +166,7 @@ process_watch_cb (GPid pid, gint status, gpointer data)
 
     if (process->priv->quit_timeout)
         g_source_remove (process->priv->quit_timeout);
-    process->priv->quit_timeout = 0;  
+    process->priv->quit_timeout = 0;
     process->priv->pid = 0;
     g_hash_table_remove (processes, GINT_TO_POINTER (pid));
 
@@ -183,7 +186,7 @@ process_start (Process *process, gboolean block)
     GError *error = NULL;
 
     g_return_val_if_fail (process != NULL, FALSE);
-    g_return_val_if_fail (process->priv->command != NULL, FALSE);  
+    g_return_val_if_fail (process->priv->command != NULL, FALSE);
     g_return_val_if_fail (process->priv->pid == 0, FALSE);
 
     if (!g_shell_parse_argv (process->priv->command, &argc, &argv, &error))
@@ -193,19 +196,7 @@ process_start (Process *process, gboolean block)
     }
 
     if (process->priv->log_file)
-    {
-        gchar *old_filename;
-
-        /* Move old file out of the way */
-        old_filename = g_strdup_printf ("%s.old", process->priv->log_file);
-        rename (process->priv->log_file, old_filename);
-        g_free (old_filename);
-
-        /* Create new file and log to it */
-        log_fd = g_open (process->priv->log_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);
-        if (log_fd < 0)
-            g_warning ("Failed to open log file %s: %s", process->priv->log_file, g_strerror (errno));
-    }
+        log_fd = log_file_open (process->priv->log_file, process->priv->log_mode);
 
     /* Work out variables to set */
     env_length = g_hash_table_size (process->priv->env);
@@ -244,11 +235,14 @@ process_start (Process *process, gboolean block)
 #endif
         for (i = 0; i < env_length; i++)
             setenv (env_keys[i], env_values[i], TRUE);
-  
+
+        /* Reset SIGPIPE handler so the child has default behaviour (we disabled it at LightDM start) */
+        signal (SIGPIPE, SIG_DFL);
+
         execvp (argv[0], argv);
         _exit (EXIT_FAILURE);
     }
-  
+
     close (log_fd);
     g_strfreev (argv);
     g_free (env_keys);
@@ -269,7 +263,7 @@ process_start (Process *process, gboolean block)
         int exit_status;
         waitpid (process->priv->pid, &exit_status, 0);
         process_watch_cb (process->priv->pid, exit_status, process);
-    }  
+    }
     else
     {
         g_hash_table_insert (processes, GINT_TO_POINTER (process->priv->pid), g_object_ref (process));
@@ -359,9 +353,7 @@ process_stopped (Process *process)
 static void
 process_finalize (GObject *object)
 {
-    Process *self;
-
-    self = PROCESS (object);
+    Process *self = PROCESS (object);
 
     if (self->priv->pid > 0)
         g_hash_table_remove (processes, GINT_TO_POINTER (self->priv->pid));
@@ -402,7 +394,7 @@ handle_signal (GIOChannel *source, GIOCondition condition, gpointer data)
     Process *process;
 
     errno = 0;
-    if (read (signal_pipe[0], &signo, sizeof (int)) != sizeof (int) || 
+    if (read (signal_pipe[0], &signo, sizeof (int)) != sizeof (int) ||
         read (signal_pipe[0], &pid, sizeof (pid_t)) != sizeof (pid_t))
     {
         g_warning ("Error reading from signal pipe: %s", strerror (errno));
@@ -427,20 +419,20 @@ process_class_init (ProcessClass *klass)
     struct sigaction action;
 
     klass->stopped = process_stopped;
-    object_class->finalize = process_finalize;  
+    object_class->finalize = process_finalize;
 
     g_type_class_add_private (klass, sizeof (ProcessPrivate));
 
     signals[GOT_DATA] =
-        g_signal_new ("got-data",
+        g_signal_new (PROCESS_SIGNAL_GOT_DATA,
                       G_TYPE_FROM_CLASS (klass),
                       G_SIGNAL_RUN_LAST,
                       G_STRUCT_OFFSET (ProcessClass, got_data),
                       NULL, NULL,
                       NULL,
-                      G_TYPE_NONE, 0); 
+                      G_TYPE_NONE, 0);
     signals[GOT_SIGNAL] =
-        g_signal_new ("got-signal",
+        g_signal_new (PROCESS_SIGNAL_GOT_SIGNAL,
                       G_TYPE_FROM_CLASS (klass),
                       G_SIGNAL_RUN_LAST,
                       G_STRUCT_OFFSET (ProcessClass, got_signal),
@@ -448,7 +440,7 @@ process_class_init (ProcessClass *klass)
                       NULL,
                       G_TYPE_NONE, 1, G_TYPE_INT);
     signals[STOPPED] =
-        g_signal_new ("stopped",
+        g_signal_new (PROCESS_SIGNAL_STOPPED,
                       G_TYPE_FROM_CLASS (klass),
                       G_SIGNAL_RUN_LAST,
                       G_STRUCT_OFFSET (ProcessClass, stopped),