示例#1
0
/* Clears the environment, except for DBUS_STARTER_x,
 * which we hardcode to the system bus.
 */
static dbus_bool_t
clear_environment (DBusError *error)
{
#ifndef ACTIVATION_LAUNCHER_TEST
  /* totally clear the environment */
  if (!_dbus_clearenv ())
    {
      dbus_set_error (error, DBUS_ERROR_SPAWN_SETUP_FAILED,
                      "could not clear environment\n");
      return FALSE;
    }

  /* Ensure the bus is set to system */
  dbus_setenv ("DBUS_STARTER_ADDRESS", DBUS_SYSTEM_BUS_DEFAULT_ADDRESS);
  dbus_setenv ("DBUS_STARTER_BUS_TYPE", "system");
#endif

  return TRUE;
}
int
main (int argc, char **argv)
{
#ifdef DBUS_ENABLE_EMBEDDED_TESTS
  const char *dir;
  DBusString config_file;

  if (argc > 1)
    dir = argv[1];
  else
    dir = _dbus_getenv ("DBUS_TEST_DATA");

  if (dir == NULL)
    {
      fprintf (stderr, "Must specify test data directory as argv[1] or in DBUS_TEST_DATA env variable\n");
      return 1;
    }

  printf ("%s: Running launch helper OOM checks\n", argv[0]);

  if (!_dbus_string_init (&config_file))
    return 1;
  if (!_dbus_string_append (&config_file, dir))
    return 1;
  if (!_dbus_string_append (&config_file, "/valid-config-files-system/debug-allow-all-pass.conf"))
    return 1;

  /* use a config file that will actually work... */
  dbus_setenv ("TEST_LAUNCH_HELPER_CONFIG",
               _dbus_string_get_const_data (&config_file));

  _dbus_string_free (&config_file);

  if (!_dbus_test_oom_handling ("dbus-daemon-launch-helper",
                                bus_activation_helper_oom_test,
                                "org.freedesktop.DBus.TestSuiteEchoService"))
    die ("OOM failed");

  test_post_hook (argv[0]);

  printf ("%s: Success\n", argv[0]);

  return 0;
#else /* DBUS_ENABLE_EMBEDDED_TESTS */

  printf ("Not compiled with test support\n");
  
  return 0;
#endif
}
示例#3
0
int
main (int argc, char **argv)
{
  const char *dir;
  DBusString config_file;

  if (argc > 1 && strcmp (argv[1], "--tap") != 0)
    dir = argv[1];
  else
    dir = _dbus_getenv ("DBUS_TEST_DATA");

  if (dir == NULL)
    _dbus_test_fatal ("Must specify test data directory as argv[1] or in DBUS_TEST_DATA env variable");

  _dbus_test_diag ("%s: Running launch helper OOM checks", argv[0]);

  if (!_dbus_string_init (&config_file) ||
      !_dbus_string_append (&config_file, dir) ||
      !_dbus_string_append (&config_file, "/valid-config-files-system/debug-allow-all-pass.conf"))
    _dbus_test_fatal ("OOM during initialization");

  /* use a config file that will actually work... */
  dbus_setenv ("TEST_LAUNCH_HELPER_CONFIG",
               _dbus_string_get_const_data (&config_file));

  _dbus_string_free (&config_file);

  if (!_dbus_test_oom_handling ("dbus-daemon-launch-helper",
                                bus_activation_helper_oom_test,
                                (char *) "org.freedesktop.DBus.TestSuiteEchoService"))
    _dbus_test_fatal ("OOM test failed");

  /* ... otherwise it must have passed */
  _dbus_test_ok ("%s", argv[0]);

  _dbus_test_check_memleaks (argv[0]);

  return _dbus_test_done_testing ();
}
示例#4
0
DBusServer *
_dbus_server_new_for_launchd (const char *launchd_env_var, DBusError * error)
  {
#ifdef DBUS_ENABLE_LAUNCHD
    DBusServer *server;
    DBusString address;
    int launchd_fd;
    launch_data_t sockets_dict, checkin_response;
    launch_data_t checkin_request;
    launch_data_t listening_fd_array, listening_fd;
    launch_data_t environment_dict, environment_param;
    const char *launchd_socket_path, *display;

    launchd_socket_path = _dbus_getenv (launchd_env_var);
    display = _dbus_getenv ("DISPLAY");

    _DBUS_ASSERT_ERROR_IS_CLEAR (error);

    if (launchd_socket_path == NULL || *launchd_socket_path == '\0')
      {
        dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
                        "launchd's environment variable %s is empty, but should contain a socket path.\n", launchd_env_var);
        return NULL;
      }

    if (!_dbus_string_init (&address))
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        return NULL;
      }
    if (!_dbus_string_append (&address, "unix:path="))
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        goto l_failed_0;
      }
    if (!_dbus_string_append (&address, launchd_socket_path))
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        goto l_failed_0;
      }

    if ((checkin_request = launch_data_new_string (LAUNCH_KEY_CHECKIN)) == NULL)
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
                        "launch_data_new_string(\"%s\") Unable to create string.\n",
                        LAUNCH_KEY_CHECKIN);
        goto l_failed_0;
      }

    if ((checkin_response = launch_msg (checkin_request)) == NULL)
      {
        dbus_set_error (error, DBUS_ERROR_IO_ERROR,
                        "launch_msg(\"%s\") IPC failure: %s\n",
                        LAUNCH_KEY_CHECKIN, strerror (errno));
        goto l_failed_0;
      }

    if (LAUNCH_DATA_ERRNO == launch_data_get_type (checkin_response))
      {
        dbus_set_error (error, DBUS_ERROR_FAILED, "Check-in failed: %s\n",
                        strerror (launch_data_get_errno (checkin_response)));
        goto l_failed_0;
      }

    sockets_dict =
      launch_data_dict_lookup (checkin_response, LAUNCH_JOBKEY_SOCKETS);
    if (NULL == sockets_dict)
      {
        dbus_set_error (error, DBUS_ERROR_IO_ERROR,
                        "No sockets found to answer requests on!\n");
        goto l_failed_0;
      }

    listening_fd_array =
      launch_data_dict_lookup (sockets_dict, "unix_domain_listener");
    if (NULL == listening_fd_array)
      {
        dbus_set_error (error, DBUS_ERROR_IO_ERROR,
                        "No known sockets found to answer requests on!\n");
        goto l_failed_0;
      }

    if (launch_data_array_get_count (listening_fd_array) != 1)
      {
        dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
                        "Expected 1 socket from launchd, got %d.\n",
                        launch_data_array_get_count (listening_fd_array));
        goto l_failed_0;
      }

    listening_fd = launch_data_array_get_index (listening_fd_array, 0);
    launchd_fd = launch_data_get_fd (listening_fd);

    _dbus_fd_set_close_on_exec (launchd_fd);

    if (launchd_fd < 0)
      {
        _DBUS_ASSERT_ERROR_IS_SET (error);
        goto l_failed_0;
  if (display == NULL || *display == '\0')
    {
      environment_dict = launch_data_dict_lookup (checkin_response, LAUNCH_JOBKEY_USERENVIRONMENTVARIABLES);
      if (NULL == environment_dict)
        {
          _dbus_warn ("Unable to retrieve user environment from launchd.");
        }
      else
        {
          environment_param = launch_data_dict_lookup (environment_dict, "DISPLAY");
          if (NULL == environment_param)
            {
              _dbus_warn ("Unable to retrieve DISPLAY from launchd.");
            }
          else
            {
              display = launch_data_get_string(environment_param);
              dbus_setenv ("DISPLAY", display);
            }
        }
    }

      }

    server = _dbus_server_new_for_socket (&launchd_fd, 1, &address, 0);
    if (server == NULL)
      {
        dbus_set_error (error, DBUS_ERROR_NO_SERVER,
                        "Unable to listen on launchd fd %d.", launchd_fd);
        goto l_failed_0;
      }

    _dbus_string_free (&address);

    return server;

  l_failed_0:
    _dbus_string_free (&address);

    return NULL;
#else /* DBUS_ENABLE_LAUNCHD */
    dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
                    "address type 'launchd' requested, but launchd support not compiled in");
    return NULL;
#endif
  }
示例#5
0
static int
run_session (const char *dbus_daemon,
             const char *config_file,
             char       *bus_address,
             char      **argv,
             int         prog_arg)
{
  pid_t bus_pid;
  pid_t app_pid;
  int bus_address_pipe[2] = { 0, 0 };

  if (pipe (bus_address_pipe) < 0)
    {
      fprintf (stderr, "%s: failed to create pipe: %s\n", me, strerror (errno));
      return 127;
    }

  /* Make sure our output buffers aren't redundantly printed by both the
   * parent and the child */
  fflush (stdout);
  fflush (stderr);

  bus_pid = fork ();

  if (bus_pid < 0)
    {
      fprintf (stderr, "%s: failed to fork: %s\n", me, strerror (errno));
      return 127;
    }

  if (bus_pid == 0)
    {
      /* child */
      exec_dbus_daemon (dbus_daemon, bus_address_pipe, config_file);
      /* not reached */
      return 127;
    }

  close (bus_address_pipe[PIPE_WRITE_END]);

  switch (read_line (bus_address_pipe[PIPE_READ_END], bus_address, MAX_ADDR_LEN))
    {
    case READ_STATUS_OK:
      break;

    case READ_STATUS_EOF:
      fprintf (stderr, "%s: EOF reading address from bus daemon\n", me);
      return 127;
      break;

    case READ_STATUS_ERROR:
      fprintf (stderr, "%s: error reading address from bus daemon: %s\n",
               me, strerror (errno));
      return 127;
      break;

    default:
      _dbus_assert_not_reached ("invalid read result");
    }

  close (bus_address_pipe[PIPE_READ_END]);

  if (!dbus_setenv ("DBUS_SESSION_BUS_ADDRESS", bus_address) ||
      !dbus_setenv ("DBUS_SESSION_BUS_PID", NULL) ||
      !dbus_setenv ("DBUS_SESSION_BUS_WINDOWID", NULL) ||
      !dbus_setenv ("DBUS_STARTER_ADDRESS", NULL) ||
      !dbus_setenv ("DBUS_STARTER_BUS_TYPE", NULL))
    oom ();

  fflush (stdout);
  fflush (stderr);

  app_pid = fork ();

  if (app_pid < 0)
    {
      fprintf (stderr, "%s: failed to fork: %s\n", me, strerror (errno));
      return 127;
    }

  if (app_pid == 0)
    {
      /* child */
      exec_app (prog_arg, argv);
      /* not reached */
      return 127;
    }

  while (1)
    {
      int child_status;
      pid_t child_pid = waitpid (-1, &child_status, 0);

      if (child_pid == (pid_t) -1)
        {
          int errsv = errno;

          if (errsv == EINTR)
            continue;

          /* shouldn't happen: the only other documented errors are ECHILD,
           * which shouldn't happen because we terminate when all our children
           * have died, and EINVAL, which would indicate programming error */
          fprintf (stderr, "%s: waitpid() failed: %s\n", me, strerror (errsv));
          return 127;
        }
      else if (child_pid == bus_pid)
        {
          /* no need to kill it, now */
          bus_pid = 0;

          if (WIFEXITED (child_status))
            fprintf (stderr, "%s: dbus-daemon exited with code %d\n",
                me, WEXITSTATUS (child_status));
          else if (WIFSIGNALED (child_status))
            fprintf (stderr, "%s: dbus-daemon terminated by signal %d\n",
                me, WTERMSIG (child_status));
          else
            fprintf (stderr, "%s: dbus-daemon died or something\n", me);
        }
      else if (child_pid == app_pid)
        {
          if (bus_pid != 0)
            kill (bus_pid, SIGTERM);

          if (WIFEXITED (child_status))
            return WEXITSTATUS (child_status);

          /* if it died from a signal, behave like sh(1) */
          if (WIFSIGNALED (child_status))
            return 128 + WTERMSIG (child_status);

          /* I give up (this should never be reached) */
          fprintf (stderr, "%s: child process died or something\n", me);
          return 127;
        }
      else
        {
          fprintf (stderr, "%s: ignoring unknown child process %ld\n", me,
              (long) child_pid);
        }
    }

  return 0;
}