/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright © 2012 Red Hat, Inc.
 * Copyright © 2012-2013 Canonical Limited
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; either version 2 of the licence or (at
 * your option) any later version.
 *
 * See the included COPYING file for more information.
 *
 * Authors: Colin Walters <walters@verbum.org>
 *          Ryan Lortie <desrt@desrt.ca>
 */

/**
 * SECTION:gsubprocesslauncher
 * @title: GSubprocess Launcher
 * @short_description: Environment options for launching a child process
 * @include: gio/gio.h
 *
 * This class contains a set of options for launching child processes,
 * such as where its standard input and output will be directed, the
 * argument list, the environment, and more.
 *
 * While the #GSubprocess class has high level functions covering
 * popular cases, use of this class allows access to more advanced
 * options.  It can also be used to launch multiple subprocesses with
 * a similar configuration.
 *
 * Since: 2.40
 */

#define ALL_STDIN_FLAGS         (G_SUBPROCESS_FLAGS_STDIN_PIPE |        \
                                 G_SUBPROCESS_FLAGS_STDIN_INHERIT)
#define ALL_STDOUT_FLAGS        (G_SUBPROCESS_FLAGS_STDOUT_PIPE |       \
                                 G_SUBPROCESS_FLAGS_STDOUT_SILENCE)
#define ALL_STDERR_FLAGS        (G_SUBPROCESS_FLAGS_STDERR_PIPE |       \
                                 G_SUBPROCESS_FLAGS_STDERR_SILENCE |    \
                                 G_SUBPROCESS_FLAGS_STDERR_MERGE)

#include "config.h"

#include "gsubprocesslauncher-private.h"
#include "gioenumtypes.h"
#include "gsubprocess.h"
#include "ginitable.h"

#ifdef G_OS_UNIX
#include <unistd.h>
#include <fcntl.h>
#endif

typedef GObjectClass GSubprocessLauncherClass;

G_DEFINE_TYPE (GSubprocessLauncher, g_subprocess_launcher, G_TYPE_OBJECT);

static gboolean
verify_disposition (const gchar      *stream_name,
                    GSubprocessFlags  filtered_flags,
                    gint              fd,
                    const gchar      *filename)
{
  guint n_bits;

  if (!filtered_flags)
    n_bits = 0;
  else if (((filtered_flags - 1) & filtered_flags) == 0)
    n_bits = 1;
  else
    n_bits = 2; /* ...or more */

  if (n_bits + (fd >= 0) + (filename != NULL) > 1)
    {
      GString *err;

      err = g_string_new (NULL);
      if (n_bits)
        {
          GFlagsClass *class;
          GFlagsValue *value;

          class = g_type_class_peek (G_TYPE_SUBPROCESS_FLAGS);
          while ((value = g_flags_get_first_value (class, filtered_flags)))
            {
              g_string_append_printf (err, " %s", value->value_name);
              filtered_flags &= value->value;
            }

          g_type_class_unref (class);
        }

      if (fd >= 0)
        g_string_append_printf (err, " g_subprocess_launcher_take_%s_fd()", stream_name);

      if (filename)
        g_string_append_printf (err, " g_subprocess_launcher_set_%s_file_path()", stream_name);

      g_critical ("You may specify at most one disposition for the %s stream, but you specified:%s.",
                  stream_name, err->str);
      g_string_free (err, TRUE);

      return FALSE;
    }

  return TRUE;
}

static gboolean
verify_flags (GSubprocessFlags flags)
{
  return verify_disposition ("stdin", flags & ALL_STDIN_FLAGS, -1, NULL) &&
         verify_disposition ("stdout", flags & ALL_STDOUT_FLAGS, -1, NULL) &&
         verify_disposition ("stderr", flags & ALL_STDERR_FLAGS, -1, NULL);
}

static void
g_subprocess_launcher_set_property (GObject *object, guint prop_id,
                                    const GValue *value, GParamSpec *pspec)
{
  GSubprocessLauncher *launcher = G_SUBPROCESS_LAUNCHER (object);

  g_assert (prop_id == 1);

  if (verify_flags (g_value_get_flags (value)))
    launcher->flags = g_value_get_flags (value);
}

static void
g_subprocess_launcher_finalize (GObject *object)
{
  GSubprocessLauncher *self = G_SUBPROCESS_LAUNCHER (object);

#ifdef G_OS_UNIX
  guint i;

  g_free (self->stdin_path);
  g_free (self->stdout_path);
  g_free (self->stderr_path);

  if (self->stdin_fd != -1)
    close (self->stdin_fd);

  if (self->stdout_fd != -1)
    close (self->stdout_fd);

  if (self->stderr_fd != -1)
    close (self->stderr_fd);

  if (self->basic_fd_assignments)
    {
      for (i = 0; i < self->basic_fd_assignments->len; i++)
        (void) close (g_array_index (self->basic_fd_assignments, int, i));
      g_array_unref (self->basic_fd_assignments);
    }
  if (self->needdup_fd_assignments)
    {
      for (i = 0; i < self->needdup_fd_assignments->len; i += 2)
        (void) close (g_array_index (self->needdup_fd_assignments, int, i));
      g_array_unref (self->needdup_fd_assignments);
    }

  if (self->child_setup_destroy_notify)
    (* self->child_setup_destroy_notify) (self->child_setup_user_data);
#endif

  g_strfreev (self->envp);
  g_free (self->cwd);

  G_OBJECT_CLASS (g_subprocess_launcher_parent_class)->finalize (object);
}

static void
g_subprocess_launcher_init (GSubprocessLauncher  *self)
{
  self->envp = g_get_environ ();

#ifdef G_OS_UNIX
  self->stdin_fd = -1;
  self->stdout_fd = -1;
  self->stderr_fd = -1;
  self->basic_fd_assignments = g_array_new (FALSE, 0, sizeof (int));
  self->needdup_fd_assignments = g_array_new (FALSE, 0, sizeof (int));
#endif
}

static void
g_subprocess_launcher_class_init (GSubprocessLauncherClass *class)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (class);

  gobject_class->set_property = g_subprocess_launcher_set_property;
  gobject_class->finalize = g_subprocess_launcher_finalize;

  g_object_class_install_property (gobject_class, 1,
                                   g_param_spec_flags ("flags", "Flags", "GSubprocessFlags for launched processes",
                                                       G_TYPE_SUBPROCESS_FLAGS, 0, G_PARAM_WRITABLE |
                                                       G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY));
}

/**
 * g_subprocess_launcher_new:
 * @flags: #GSubprocessFlags
 *
 * Creates a new #GSubprocessLauncher.
 *
 * The launcher is created with the default options.  A copy of the
 * environment of the calling process is made at the time of this call
 * and will be used as the environment that the process is launched in.
 *
 * Since: 2.40
 **/
GSubprocessLauncher *
g_subprocess_launcher_new (GSubprocessFlags flags)
{
  if (!verify_flags (flags))
    return NULL;

  return g_object_new (G_TYPE_SUBPROCESS_LAUNCHER,
                       "flags", flags,
                       NULL);
}

/**
 * g_subprocess_launcher_set_environ:
 * @self: a #GSubprocess
 * @env: the replacement environment
 *
 * Replace the entire environment of processes launched from this
 * launcher with the given 'environ' variable.
 *
 * Typically you will build this variable by using g_listenv() to copy
 * the process 'environ' and using the functions g_environ_setenv(),
 * g_environ_unsetenv(), etc.
 *
 * As an alternative, you can use g_subprocess_launcher_setenv(),
 * g_subprocess_launcher_unsetenv(), etc.
 *
 * On UNIX, all strings in this array can be arbitrary byte strings.
 * On Windows, they should be in UTF-8.
 *
 * Since: 2.40
 **/
void
g_subprocess_launcher_set_environ (GSubprocessLauncher  *self,
                                   gchar               **env)
{
  g_strfreev (self->envp);
  self->envp = g_strdupv (env);
}

/**
 * g_subprocess_launcher_setenv:
 * @self: a #GSubprocess
 * @variable: the environment variable to set, must not contain '='
 * @value: the new value for the variable
 * @overwrite: whether to change the variable if it already exists
 *
 * Sets the environment variable @variable in the environment of
 * processes launched from this launcher.
 *
 * On UNIX, both the variable's name and value can be arbitrary byte
 * strings, except that the variable's name cannot contain '='.
 * On Windows, they should be in UTF-8.
 *
 * Since: 2.40
 **/
void
g_subprocess_launcher_setenv (GSubprocessLauncher *self,
                              const gchar         *variable,
                              const gchar         *value,
                              gboolean             overwrite)
{
  self->envp = g_environ_setenv (self->envp, variable, value, overwrite);
}

/**
 * g_subprocess_launcher_unsetenv:
 * @self: a #GSubprocess
 * @variable: the environment variable to unset, must not contain '='
 *
 * Removes the environment variable @variable from the environment of
 * processes launched from this launcher.
 *
 * On UNIX, the variable's name can be an arbitrary byte string not
 * containing '='. On Windows, it should be in UTF-8.
 *
 * Since: 2.40
 **/
void
g_subprocess_launcher_unsetenv (GSubprocessLauncher *self,
                                const gchar         *variable)
{
  self->envp = g_environ_unsetenv (self->envp, variable);
}

/**
 * g_subprocess_launcher_getenv:
 * @self: a #GSubprocess
 * @variable: the environment variable to get
 *
 * Returns the value of the environment variable @variable in the
 * environment of processes launched from this launcher.
 *
 * On UNIX, the returned string can be an arbitrary byte string.
 * On Windows, it will be UTF-8.
 *
 * Returns: the value of the environment variable, %NULL if unset
 *
 * Since: 2.40
 **/
const gchar *
g_subprocess_launcher_getenv (GSubprocessLauncher *self,
                              const gchar         *variable)
{
  return g_environ_getenv (self->envp, variable);
}

/**
 * g_subprocess_launcher_set_cwd:
 * @self: a #GSubprocess
 * @cwd: the cwd for launched processes
 *
 * Sets the current working directory that processes will be launched
 * with.
 *
 * By default processes are launched with the current working directory
 * of the launching process at the time of launch.
 *
 * Since: 2.40
 **/
void
g_subprocess_launcher_set_cwd (GSubprocessLauncher *self,
                               const gchar         *cwd)
{
  g_free (self->cwd);
  self->cwd = g_strdup (cwd);
}

/**
 * g_subprocess_launcher_set_flags:
 * @self: a #GSubprocessLauncher
 * @flags: #GSubprocessFlags
 *
 * Sets the flags on the launcher.
 *
 * The default flags are %G_SUBPROCESS_FLAGS_NONE.
 *
 * You may not set flags that specify conflicting options for how to
 * handle a particular stdio stream (eg: specifying both
 * %G_SUBPROCESS_FLAGS_STDIN_PIPE and
 * %G_SUBPROCESS_FLAGS_STDIN_INHERIT).
 *
 * You may also not set a flag that conflicts with a previous call to a
 * function like g_subprocess_launcher_set_stdin_file_path() or
 * g_subprocess_launcher_take_stdout_fd().
 *
 * Since: 2.40
 **/
void
g_subprocess_launcher_set_flags (GSubprocessLauncher *self,
                                 GSubprocessFlags     flags)
{
  const gchar *stdin_path = NULL, *stdout_path = NULL, *stderr_path = NULL;
  gint stdin_fd = -1, stdout_fd = -1, stderr_fd = -1;

#ifdef G_OS_UNIX
  stdin_fd = self->stdin_fd;
  stdout_fd = self->stdout_fd;
  stderr_fd = self->stderr_fd;
  stdin_path = self->stdin_path;
  stdout_path = self->stdout_path;
  stderr_path = self->stderr_path;
#endif

  if (verify_disposition ("stdin", flags & ALL_STDIN_FLAGS, stdin_fd, stdin_path) &&
      verify_disposition ("stdout", flags & ALL_STDOUT_FLAGS, stdout_fd, stdout_path) &&
      verify_disposition ("stderr", flags & ALL_STDERR_FLAGS, stderr_fd, stderr_path))
    self->flags = flags;
}

#ifdef G_OS_UNIX
static void
assign_fd (gint *fd_ptr, gint fd)
{
  gint flags;

  if (*fd_ptr != -1)
    close (*fd_ptr);

  *fd_ptr = fd;

  if (fd != -1)
    {
      /* best effort */
      flags = fcntl (fd, F_GETFD);
      if (~flags & FD_CLOEXEC)
        fcntl (fd, F_SETFD, flags | FD_CLOEXEC);
    }
}

/**
 * g_subprocess_launcher_set_stdin_file_path:
 * @self: a #GSubprocessLauncher
 * @path: a filename or %NULL
 *
 * Sets the file path to use as the stdin for spawned processes.
 *
 * If @path is %NULL then any previously given path is unset.
 *
 * The file must exist or spawning the process will fail.
 *
 * You may not set a stdin file path if a stdin fd is already set or if
 * the launcher flags contain any flags directing stdin elsewhere.
 *
 * This feature is only available on UNIX.
 *
 * Since: 2.40
 **/
void
g_subprocess_launcher_set_stdin_file_path (GSubprocessLauncher *self,
                                           const gchar         *path)
{
  if (verify_disposition ("stdin", self->flags & ALL_STDIN_FLAGS, self->stdin_fd, path))
    {
      g_free (self->stdin_path);
      self->stdin_path = g_strdup (path);
    }
}

/**
 * g_subprocess_launcher_take_stdin_fd:
 * @self: a #GSubprocessLauncher
 * @fd: a file descriptor, or -1
 *
 * Sets the file descriptor to use as the stdin for spawned processes.
 *
 * If @fd is -1 then any previously given fd is unset.
 *
 * Note that if your intention is to have the stdin of the calling
 * process inherited by the child then %G_SUBPROCESS_FLAGS_STDIN_INHERIT
 * is a better way to go about doing that.
 *
 * The passed @fd is noted but will not be touched in the current
 * process.  It is therefore necessary that it be kept open by the
 * caller until the subprocess is spawned.  The file descriptor will
 * also not be explicitly closed on the child side, so it must be marked
 * O_CLOEXEC if that's what you want.
 *
 * You may not set a stdin fd if a stdin file path is already set or if
 * the launcher flags contain any flags directing stdin elsewhere.
 *
 * This feature is only available on UNIX.
 *
 * Since: 2.40
 **/
void
g_subprocess_launcher_take_stdin_fd (GSubprocessLauncher *self,
                                     gint                 fd)
{
  if (verify_disposition ("stdin", self->flags & ALL_STDIN_FLAGS, fd, self->stdin_path))
    assign_fd (&self->stdin_fd, fd);
}

/**
 * g_subprocess_launcher_set_stdout_file_path:
 * @self: a #GSubprocessLauncher
 * @path: a filename or %NULL
 *
 * Sets the file path to use as the stdout for spawned processes.
 *
 * If @path is %NULL then any previously given path is unset.
 *
 * The file will be created or truncated when the process is spawned, as
 * would be the case if using '>' at the shell.
 *
 * You may not set a stdout file path if a stdout fd is already set or
 * if the launcher flags contain any flags directing stdout elsewhere.
 *
 * This feature is only available on UNIX.
 *
 * Since: 2.40
 **/
void
g_subprocess_launcher_set_stdout_file_path (GSubprocessLauncher *self,
                                            const gchar         *path)
{
  if (verify_disposition ("stdout", self->flags & ALL_STDOUT_FLAGS, self->stdout_fd, path))
    {
      g_free (self->stdout_path);
      self->stdout_path = g_strdup (path);
    }
}

/**
 * g_subprocess_launcher_take_stdout_fd:
 * @self: a #GSubprocessLauncher
 * @fd: a file descriptor, or -1
 *
 * Sets the file descriptor to use as the stdout for spawned processes.
 *
 * If @fd is -1 then any previously given fd is unset.
 *
 * Note that the default behaviour is to pass stdout through to the
 * stdout of the parent process.
 *
 * The passed @fd is noted but will not be touched in the current
 * process.  It is therefore necessary that it be kept open by the
 * caller until the subprocess is spawned.  The file descriptor will
 * also not be explicitly closed on the child side, so it must be marked
 * O_CLOEXEC if that's what you want.
 *
 * You may not set a stdout fd if a stdout file path is already set or
 * if the launcher flags contain any flags directing stdout elsewhere.
 *
 * This feature is only available on UNIX.
 *
 * Since: 2.40
 **/
void
g_subprocess_launcher_take_stdout_fd (GSubprocessLauncher *self,
                                      gint                 fd)
{
  if (verify_disposition ("stdout", self->flags & ALL_STDOUT_FLAGS, fd, self->stdout_path))
    assign_fd (&self->stdout_fd, fd);
}

/**
 * g_subprocess_launcher_set_stderr_file_path:
 * @self: a #GSubprocessLauncher
 * @path: a filename or %NULL
 *
 * Sets the file path to use as the stderr for spawned processes.
 *
 * If @path is %NULL then any previously given path is unset.
 *
 * The file will be created or truncated when the process is spawned, as
 * would be the case if using '2>' at the shell.
 *
 * If you want to send both stdout and stderr to the same file then use
 * %G_SUBPROCESS_FLAGS_STDERR_MERGE.
 *
 * You may not set a stderr file path if a stderr fd is already set or
 * if the launcher flags contain any flags directing stderr elsewhere.
 *
 * This feature is only available on UNIX.
 *
 * Since: 2.40
 **/
void
g_subprocess_launcher_set_stderr_file_path (GSubprocessLauncher *self,
                                            const gchar         *path)
{
  if (verify_disposition ("stderr", self->flags & ALL_STDERR_FLAGS, self->stderr_fd, path))
    {
      g_free (self->stderr_path);
      self->stderr_path = g_strdup (path);
    }
}

/**
 * g_subprocess_launcher_take_stderr_fd:
 * @self: a #GSubprocessLauncher
 * @fd: a file descriptor, or -1
 *
 * Sets the file descriptor to use as the stderr for spawned processes.
 *
 * If @fd is -1 then any previously given fd is unset.
 *
 * Note that the default behaviour is to pass stderr through to the
 * stderr of the parent process.
 *
 * The passed @fd belongs to the #GSubprocessLauncher.  It will be
 * automatically closed when the launcher is finalized.  The file
 * descriptor will also be closed on the child side when executing the
 * spawned process.
 *
 * You may not set a stderr fd if a stderr file path is already set or
 * if the launcher flags contain any flags directing stderr elsewhere.
 *
 * This feature is only available on UNIX.
 *
 * Since: 2.40
 **/
void
g_subprocess_launcher_take_stderr_fd (GSubprocessLauncher *self,
                                     gint                 fd)
{
  if (verify_disposition ("stderr", self->flags & ALL_STDERR_FLAGS, fd, self->stderr_path))
    assign_fd (&self->stderr_fd, fd);
}

/**
 * g_subprocess_launcher_take_fd:
 * @self: a #GSubprocessLauncher
 * @source_fd: File descriptor in parent process
 * @target_fd: Target descriptor for child process
 *
 * Transfer an arbitrary file descriptor from parent process to the
 * child.  This function takes "ownership" of the fd; it will be closed
 * in the parent when @self is freed.
 *
 * By default, all file descriptors from the parent will be closed.
 * This function allows you to create (for example) a custom pipe() or
 * socketpair() before launching the process, and choose the target
 * descriptor in the child.
 *
 * An example use case is GNUPG, which has a command line argument
 * --passphrase-fd providing a file descriptor number where it expects
 * the passphrase to be written.
 */
void
g_subprocess_launcher_take_fd (GSubprocessLauncher   *self,
                               gint                   source_fd,
                               gint                   target_fd)
{
  if (source_fd == target_fd)
    {
      g_array_append_val (self->basic_fd_assignments, source_fd);
    }
  else
    {
      g_array_append_val (self->needdup_fd_assignments, source_fd);
      g_array_append_val (self->needdup_fd_assignments, target_fd);
    }
}

/**
 * g_subprocess_launcher_set_child_setup:
 * @self: a #GSubprocessLauncher
 * @child_setup: a #GSpawnChildSetupFunc to use as the child setup function
 * @user_data: user data for @child_setup
 * @destroy_notify: a #GDestroyNotify for @user_data
 *
 * Sets up a child setup function.
 *
 * The child setup function will be called after fork() but before
 * exec() on the child's side.
 *
 * @destroy_notify will not be automatically called on the child's side
 * of the fork().  It will only be called when the last reference on the
 * #GSubprocessLauncher is dropped or when a new child setup function is
 * given.
 *
 * %NULL can be given as @child_setup to disable the functionality.
 *
 * Child setup functions are only available on UNIX.
 *
 * Since: 2.40
 **/
void
g_subprocess_launcher_set_child_setup (GSubprocessLauncher  *self,
                                       GSpawnChildSetupFunc  child_setup,
                                       gpointer              user_data,
                                       GDestroyNotify        destroy_notify)
{
  if (self->child_setup_destroy_notify)
    (* self->child_setup_destroy_notify) (self->child_setup_user_data);

  self->child_setup_func = child_setup;
  self->child_setup_user_data = user_data;
  self->child_setup_destroy_notify = destroy_notify;
}
#endif

/**
 * g_subprocess_launcher_spawn:
 * @self: a #GSubprocessLauncher
 * @error: Error
 * @argv0: Command line arguments
 * @...: Continued arguments, %NULL terminated
 *
 * Creates a #GSubprocess given a provided varargs list of arguments.
 *
 * Since: 2.40
 * Returns: (transfer full): A new #GSubprocess, or %NULL on error (and @error will be set)
 **/
GSubprocess *
g_subprocess_launcher_spawn (GSubprocessLauncher  *launcher,
                             GError              **error,
                             const gchar          *argv0,
                             ...)
{
  GSubprocess *result;
  GPtrArray *args;
  const gchar *arg;
  va_list ap;

  g_return_val_if_fail (argv0 != NULL && argv0[0] != '\0', NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  args = g_ptr_array_new ();

  va_start (ap, argv0);
  g_ptr_array_add (args, (gchar *) argv0);
  while ((arg = va_arg (ap, const gchar *)))
    g_ptr_array_add (args, (gchar *) arg);

  g_ptr_array_add (args, NULL);
  va_end (ap);

  result = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);

  g_ptr_array_free (args, TRUE);

  return result;

}

/**
 * g_subprocess_launcher_spawnv:
 * @self: a #GSubprocessLauncher
 * @argv: (array zero-terminated=1) (element-type utf8): Command line arguments
 * @error: Error
 *
 * Creates a #GSubprocess given a provided array of arguments.
 *
 * Since: 2.40
 * Returns: (transfer full): A new #GSubprocess, or %NULL on error (and @error will be set)
 **/
GSubprocess *
g_subprocess_launcher_spawnv (GSubprocessLauncher  *launcher,
                              const gchar * const  *argv,
                              GError              **error)
{
  GSubprocess *subprocess;

  g_return_val_if_fail (argv != NULL && argv[0] != NULL && argv[0][0] != '\0', NULL);

  subprocess = g_object_new (G_TYPE_SUBPROCESS,
                             "argv", argv,
                             "flags", launcher->flags,
                             NULL);
  g_subprocess_set_launcher (subprocess, launcher);

  if (!g_initable_init (G_INITABLE (subprocess), NULL, error))
    {
      g_object_unref (subprocess);
      return NULL;
    }

  return subprocess;
}
