<commit_before>/* 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: <NAME> <<EMAIL>>
 *          <NAME> <<EMAIL>>
 */

/**
 * 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.",<commit_msg>subprocess: avoid infinite loop in verify_disposition()<commit_after>/* 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: <NAME> <<EMAIL>>
 *          <NAME> <<EMAIL>>
 */

/**
 * 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;
          guint i;

          class = g_type_class_peek (G_TYPE_SUBPROCESS_FLAGS);

          for (i = 0; i < class->n_values; i++)
            {
              const GFlagsValue *value = &class->values[i];

              if (filtered_flags & value->value)
                g_string_append_printf (err, " %s", value->value_name);
            }

          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.",
{'fraction_non_alphanumeric': 0.08517835178351783, 'fraction_numerical': 0.007533825338253383, 'mean_word_length': 2.550764192139738, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7025922', 'n_tokens_mistral': 2091, 'n_tokens_neox': 1968, 'n_words': 578}