Ticket #27555: 0002-add-launchd-implementation.patch

File 0002-add-launchd-implementation.patch, 11.8 KB (added by monty19@…, 14 years ago)

New 0002-add-launchd-implementation.patch

  • dbus/dbus-server-launchd.c

    diff -urN dbus-1.4.0-old/dbus/dbus-server-launchd.c dbus-1.4.0-new/dbus/dbus-server-launchd.c
    old new  
     1/* dbus-server-launchd.c Server methods for interacting with launchd.
     2 * Copyright (C) 2007, Tanner Lovelace <lovelace@wayfarer.org>
     3 * Copyright (C) 2008, Colin Walters <walters@verbum.org>
     4 * Copyright (C) 2008-2009, Benjamin Reed <rangerrick@befunk.com>
     5 * Copyright (C) 2009, Jonas Bähr<jonas.baehr@web.de>
     6 *
     7 * Permission is hereby granted, free of charge, to any person
     8 * obtaining a copy of this software and associated documentation
     9 * files (the "Software"), to deal in the Software without
     10 * restriction, including without limitation the rights to use, copy,
     11 * modify, merge, publish, distribute, sublicense, and/or sell copies
     12 * of the Software, and to permit persons to whom the Software is
     13 * furnished to do so, subject to the following conditions:
     14 *
     15 * The above copyright notice and this permission notice shall be
     16 * included in all copies or substantial portions of the Software.
     17 *
     18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
     22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     25 * DEALINGS IN THE SOFTWARE.
     26 */
     27
     28#include <config.h>
     29#include "dbus-server-launchd.h"
     30
     31/**
     32 * @defgroup DBusServerLaunchd DBusServer implementations for Launchd
     33 * @ingroup  DBusInternals
     34 * @brief Implementation details of DBusServer with Launchd support
     35 *
     36 * @{
     37 */
     38
     39#ifdef DBUS_ENABLE_LAUNCHD
     40#include <launch.h>
     41#include <errno.h>
     42
     43#include "dbus-server-socket.h"
     44
     45/* put other private launchd functions here */
     46
     47#endif /* DBUS_ENABLE_LAUNCHD */
     48
     49/**
     50 * @brief Creates a new server from launchd.
     51 *
     52 * launchd has allocaed a socket for us. We now query launchd for the
     53 * file descriptor of this socket and create a server on it.
     54 * In addition we inherit launchd's environment which holds a variable
     55 * containing the path to the socket. This is used to init the server's
     56 * address which is passed to autolaunched services.
     57 *
     58 * @param launchd_env_var the environment variable which holds the unix path to the socket
     59 * @param error location to store reason for failure.
     60 * @returns the new server, or #NULL on failure.
     61 */
     62
     63DBusServer *
     64_dbus_server_new_for_launchd (const char *launchd_env_var, DBusError * error)
     65  {
     66#ifdef DBUS_ENABLE_LAUNCHD
     67    DBusServer *server;
     68    DBusString address;
     69    int launchd_fd;
     70    launch_data_t sockets_dict, checkin_response;
     71    launch_data_t checkin_request;
     72    launch_data_t listening_fd_array, listening_fd;
     73    launch_data_t environment_dict, environment_param;
     74    const char *launchd_socket_path;
     75 
     76    launchd_socket_path = _dbus_getenv (launchd_env_var);
     77 
     78    _DBUS_ASSERT_ERROR_IS_CLEAR (error);
     79 
     80    if (launchd_socket_path == NULL || *launchd_socket_path == '\0')
     81      {
     82        dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
     83                        "launchd's environment variable %s is empty, but should contain a socket path.\n", launchd_env_var);
     84        return NULL;
     85      }
     86 
     87    if (!_dbus_string_init (&address))
     88      {
     89        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
     90        return NULL;
     91      }
     92    if (!_dbus_string_append (&address, "unix:path="))
     93      {
     94        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
     95        goto l_failed_0;
     96      }
     97    if (!_dbus_string_append (&address, launchd_socket_path))
     98      {
     99        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
     100        goto l_failed_0;
     101      }
     102 
     103    if ((checkin_request = launch_data_new_string (LAUNCH_KEY_CHECKIN)) == NULL)
     104      {
     105        dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
     106                        "launch_data_new_string(\"%s\") Unable to create string.\n",
     107                        LAUNCH_KEY_CHECKIN);
     108        goto l_failed_0;
     109      }
     110 
     111    if ((checkin_response = launch_msg (checkin_request)) == NULL)
     112      {
     113        dbus_set_error (error, DBUS_ERROR_IO_ERROR,
     114                        "launch_msg(\"%s\") IPC failure: %s\n",
     115                        LAUNCH_KEY_CHECKIN, strerror (errno));
     116        goto l_failed_0;
     117      }
     118 
     119    if (LAUNCH_DATA_ERRNO == launch_data_get_type (checkin_response))
     120      {
     121        dbus_set_error (error, DBUS_ERROR_FAILED, "Check-in failed: %s\n",
     122                        strerror (launch_data_get_errno (checkin_response)));
     123        goto l_failed_0;
     124      }
     125 
     126    sockets_dict =
     127      launch_data_dict_lookup (checkin_response, LAUNCH_JOBKEY_SOCKETS);
     128    if (NULL == sockets_dict)
     129      {
     130        dbus_set_error (error, DBUS_ERROR_IO_ERROR,
     131                        "No sockets found to answer requests on!\n");
     132        goto l_failed_0;
     133      }
     134 
     135    listening_fd_array =
     136      launch_data_dict_lookup (sockets_dict, "unix_domain_listener");
     137    if (NULL == listening_fd_array)
     138      {
     139        dbus_set_error (error, DBUS_ERROR_IO_ERROR,
     140                        "No known sockets found to answer requests on!\n");
     141        goto l_failed_0;
     142      }
     143 
     144    if (launch_data_array_get_count (listening_fd_array) != 1)
     145      {
     146        dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
     147                        "Expected 1 socket from launchd, got %d.\n",
     148                        launch_data_array_get_count (listening_fd_array));
     149        goto l_failed_0;
     150      }
     151 
     152    listening_fd = launch_data_array_get_index (listening_fd_array, 0);
     153    launchd_fd = launch_data_get_fd (listening_fd);
     154 
     155    _dbus_fd_set_close_on_exec (launchd_fd);
     156 
     157    if (launchd_fd < 0)
     158      {
     159        _DBUS_ASSERT_ERROR_IS_SET (error);
     160        goto l_failed_0;
     161      }
     162 
     163    server = _dbus_server_new_for_socket (&launchd_fd, 1, &address, NULL);
     164    if (server == NULL)
     165      {
     166        dbus_set_error (error, DBUS_ERROR_NO_SERVER,
     167                        "Unable to listen on launchd fd %d.", launchd_fd);
     168        goto l_failed_0;
     169      }
     170 
     171    _dbus_string_free (&address);
     172 
     173    return server;
     174 
     175  l_failed_0:
     176    _dbus_string_free (&address);
     177 
     178    return NULL;
     179#else /* DBUS_ENABLE_LAUNCHD */
     180    dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
     181                    "address type 'launchd' requested, but launchd support not compiled in");
     182    return NULL;
     183#endif
     184  }
     185
     186/** @} */
  • dbus/dbus-server-launchd.h

    diff -urN dbus-1.4.0-old/dbus/dbus-server-launchd.h dbus-1.4.0-new/dbus/dbus-server-launchd.h
    old new  
     1/* dbus-server-launchd.h Server methods for interacting with launchd.
     2* Copyright (C) 2008, Benjamin Reed <rangerrick@befunk.com>
     3*
     4* Permission is hereby granted, free of charge, to any person
     5* obtaining a copy of this software and associated documentation
     6* files (the "Software"), to deal in the Software without
     7* restriction, including without limitation the rights to use, copy,
     8* modify, merge, publish, distribute, sublicense, and/or sell copies
     9* of the Software, and to permit persons to whom the Software is
     10* furnished to do so, subject to the following conditions:
     11*
     12* The above copyright notice and this permission notice shall be
     13* included in all copies or substantial portions of the Software.
     14*
     15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     16* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     17* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     18* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
     19* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     20* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     22* DEALINGS IN THE SOFTWARE.
     23*/
     24
     25#ifndef DBUS_SERVER_LAUNCHD_H
     26#define DBUS_SERVER_LAUNCHD_H
     27
     28#include <dbus/dbus-internals.h>
     29#include <dbus/dbus-server-protected.h>
     30
     31DBUS_BEGIN_DECLS
     32  DBusServer * _dbus_server_new_for_launchd (const char *launchd_env_var, DBusError * error);
     33
     34DBUS_END_DECLS
     35#endif /* DBUS_SERVER_LAUNCHD_H */
  • dbus/dbus-sysdeps-unix.c

    diff -urN dbus-1.4.0-old/dbus/dbus-sysdeps-unix.c dbus-1.4.0-new/dbus/dbus-sysdeps-unix.c
    old new  
    33143314#define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
    33153315
    33163316/**
     3317 * quries launchd for a specific env var which holds the socket path.
     3318 * @param launchd_env_var the env var to look up
     3319 * @param error a DBusError to store the error in case of failure
     3320 * @return the value of the env var
     3321 */
     3322dbus_bool_t
     3323_dbus_lookup_launchd_socket (DBusString *socket_path,
     3324                             const char *launchd_env_var,
     3325                             DBusError  *error)
     3326{
     3327#ifdef DBUS_ENABLE_LAUNCHD
     3328  char *argv[4];
     3329  int i;
     3330 
     3331  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
     3332
     3333  i = 0;
     3334  argv[i] = "launchctl";
     3335  ++i;
     3336  argv[i] = "getenv";
     3337  ++i;
     3338  argv[i] = (char*)launchd_env_var;
     3339  ++i;
     3340  argv[i] = NULL;
     3341  ++i;
     3342
     3343  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
     3344
     3345  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
     3346    {
     3347      return FALSE;
     3348    }
     3349
     3350  /* no error, but no result either */
     3351  if (_dbus_string_get_length(socket_path) == 0)
     3352    {
     3353      return FALSE;
     3354    }
     3355
     3356  /* strip the carriage-return */
     3357  _dbus_string_shorten(socket_path, 1);
     3358  return TRUE;
     3359#else /* DBUS_ENABLE_LAUNCHD */
     3360  dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
     3361                "can't lookup socket from launchd; launchd support not compiled in");
     3362  return FALSE;
     3363#endif
     3364}
     3365
     3366static dbus_bool_t
     3367_dbus_lookup_session_address_launchd (DBusString *address, DBusError  *error)
     3368{
     3369  dbus_bool_t valid_socket;
     3370  DBusString socket_path;
     3371
     3372  if (!_dbus_string_init (&socket_path))
     3373    {
     3374      _DBUS_SET_OOM (error);
     3375      return FALSE;
     3376    }
     3377
     3378  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
     3379
     3380  if (dbus_error_is_set(error))
     3381    {
     3382      _dbus_string_free(&socket_path);
     3383      return FALSE;
     3384    }
     3385
     3386  if (!valid_socket)
     3387    {
     3388      dbus_set_error(error, "no socket path",
     3389                "launchd did not provide a socket path, "
     3390                "verify that org.freedesktop.dbus-session.plist is loaded!");
     3391      _dbus_string_free(&socket_path);
     3392      return FALSE;
     3393    }
     3394  if (!_dbus_string_append (address, "unix:path="))
     3395    {
     3396      _DBUS_SET_OOM (error);
     3397      _dbus_string_free(&socket_path);
     3398      return FALSE;
     3399    }
     3400  if (!_dbus_string_copy (&socket_path, 0, address,
     3401                          _dbus_string_get_length (address)))
     3402    {
     3403      _DBUS_SET_OOM (error);
     3404      _dbus_string_free(&socket_path);
     3405      return FALSE;
     3406    }
     3407
     3408  _dbus_string_free(&socket_path);
     3409  return TRUE;
     3410}
     3411
     3412/**
    33173413 * Determines the address of the session bus by querying a
    33183414 * platform-specific method.
    33193415 *
     
    33373433                              DBusString  *address,
    33383434                              DBusError   *error)
    33393435{
     3436#ifdef DBUS_ENABLE_LAUNCHD
     3437  *supported = TRUE;
     3438  return _dbus_lookup_session_address_launchd (address, error);
     3439#else
    33403440  /* On non-Mac Unix platforms, if the session address isn't already
    33413441   * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
    33423442   * fall back to the autolaunch: global default; see
    33433443   * init_session_address in dbus/dbus-bus.c. */
    33443444  *supported = FALSE;
    33453445  return TRUE;
     3446#endif
    33463447}
    33473448
    33483449/**