Coverage report for dbus/dbus-sysdeps-util.c.gcov

        -:    0:Source:dbus-sysdeps-util.c
        -:    0:Graph:.libs/dbus-sysdeps-util.gcno
        -:    0:Data:.libs/dbus-sysdeps-util.gcda
        -:    0:Runs:10868
        -:    0:Programs:3
        -:    1:/* -*- mode: C; c-file-style: "gnu" -*- */
        -:    2:/* dbus-sysdeps-util.c Would be in dbus-sysdeps.c, but not used in libdbus
        -:    3: * 
        -:    4: * Copyright (C) 2002, 2003, 2004, 2005  Red Hat, Inc.
        -:    5: * Copyright (C) 2003 CodeFactory AB
        -:    6: *
        -:    7: * Licensed under the Academic Free License version 2.1
        -:    8: * 
        -:    9: * This program is free software; you can redistribute it and/or modify
        -:   10: * it under the terms of the GNU General Public License as published by
        -:   11: * the Free Software Foundation; either version 2 of the License, or
        -:   12: * (at your option) any later version.
        -:   13: *
        -:   14: * This program is distributed in the hope that it will be useful,
        -:   15: * but WITHOUT ANY WARRANTY; without even the implied warranty of
        -:   16: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        -:   17: * GNU General Public License for more details.
        -:   18: * 
        -:   19: * You should have received a copy of the GNU General Public License
        -:   20: * along with this program; if not, write to the Free Software
        -:   21: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
        -:   22: *
        -:   23: */
        -:   24:#include "dbus-sysdeps.h"
        -:   25:#include "dbus-internals.h"
        -:   26:#include "dbus-protocol.h"
        -:   27:#include "dbus-string.h"
        -:   28:#define DBUS_USERDB_INCLUDES_PRIVATE 1
        -:   29:#include "dbus-userdb.h"
        -:   30:#include "dbus-test.h"
        -:   31:
        -:   32:#include <sys/types.h>
        -:   33:#include <stdlib.h>
        -:   34:#include <string.h>
        -:   35:#include <signal.h>
        -:   36:#include <unistd.h>
        -:   37:#include <stdio.h>
        -:   38:#include <errno.h>
        -:   39:#include <fcntl.h>
        -:   40:#include <sys/stat.h>
        -:   41:#include <grp.h>
        -:   42:#include <sys/socket.h>
        -:   43:#include <dirent.h>
        -:   44:#include <sys/un.h>
        -:   45:
        -:   46:#ifndef O_BINARY
        -:   47:#define O_BINARY 0
        -:   48:#endif
        -:   49:
        -:   50:/**
        -:   51: * @addtogroup DBusInternalsUtils
        -:   52: * @{
        -:   53: */
        -:   54:
        -:   55:/**
        -:   56: * Does the chdir, fork, setsid, etc. to become a daemon process.
        -:   57: *
        -:   58: * @param pidfile #NULL, or pidfile to create
        -:   59: * @param print_pid_fd file descriptor to print daemon's pid to, or -1 for none
        -:   60: * @param error return location for errors
        -:   61: * @returns #FALSE on failure
        -:   62: */
        -:   63:dbus_bool_t
        -:   64:_dbus_become_daemon (const DBusString *pidfile,
        -:   65:		     int               print_pid_fd,
        -:   66:                     DBusError        *error)
function _dbus_become_daemon called 1 returned 100% blocks executed 34%
        1:   67:{
        -:   68:  const char *s;
        -:   69:  pid_t child_pid;
        -:   70:  int dev_null_fd;
        -:   71:
        1:   72:  _dbus_verbose ("Becoming a daemon...\n");
call    0 returned 100%
        -:   73:
        1:   74:  _dbus_verbose ("chdir to /\n");
call    0 returned 100%
        1:   75:  if (chdir ("/") < 0)
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:   76:    {
    #####:   77:      dbus_set_error (error, DBUS_ERROR_FAILED,
call    0 never executed
        -:   78:                      "Could not chdir() to root directory");
    #####:   79:      return FALSE;
        -:   80:    }
        -:   81:
        1:   82:  _dbus_verbose ("forking...\n");
call    0 returned 100%
        1:   83:  switch ((child_pid = fork ()))
call    0 returned 100%
branch  1 taken 0%
branch  2 taken 100%
branch  3 taken 0%
        -:   84:    {
        -:   85:    case -1:
    #####:   86:      _dbus_verbose ("fork failed\n");
call    0 never executed
    #####:   87:      dbus_set_error (error, _dbus_error_from_errno (errno),
call    0 never executed
call    1 never executed
call    2 never executed
call    3 never executed
call    4 never executed
        -:   88:                      "Failed to fork daemon: %s", _dbus_strerror (errno));
    #####:   89:      return FALSE;
        -:   90:      break;
        -:   91:
        -:   92:    case 0:
        1:   93:      _dbus_verbose ("in child, closing std file descriptors\n");
call    0 returned 100%
        -:   94:
        -:   95:      /* silently ignore failures here, if someone
        -:   96:       * doesn't have /dev/null we may as well try
        -:   97:       * to continue anyhow
        -:   98:       */
        -:   99:      
        1:  100:      dev_null_fd = open ("/dev/null", O_RDWR);
call    0 returned 100%
        1:  101:      if (dev_null_fd >= 0)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -:  102:        {
        1:  103:          dup2 (dev_null_fd, 0);
call    0 returned 100%
        1:  104:          dup2 (dev_null_fd, 1);
call    0 returned 100%
        -:  105:          
        1:  106:          s = _dbus_getenv ("DBUS_DEBUG_OUTPUT");
call    0 returned 100%
        2:  107:          if (s == NULL || *s == '\0')
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
branch  2 never executed
branch  3 never executed
        1:  108:            dup2 (dev_null_fd, 2);
call    0 returned 100%
        -:  109:          else
    #####:  110:            _dbus_verbose ("keeping stderr open due to DBUS_DEBUG_OUTPUT\n");
call    0 never executed
        -:  111:        }
        -:  112:
        -:  113:      /* Get a predictable umask */
        1:  114:      _dbus_verbose ("setting umask\n");
call    0 returned 100%
        1:  115:      umask (022);
call    0 returned 100%
        -:  116:      break;
        -:  117:
        -:  118:    default:
    #####:  119:      if (pidfile)
branch  0 never executed
branch  1 never executed
        -:  120:        {
    #####:  121:          _dbus_verbose ("parent writing pid file\n");
call    0 never executed
    #####:  122:          if (!_dbus_write_pid_file (pidfile,
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  123:                                     child_pid,
        -:  124:                                     error))
        -:  125:            {
    #####:  126:              _dbus_verbose ("pid file write failed, killing child\n");
call    0 never executed
    #####:  127:              kill (child_pid, SIGTERM);
call    0 never executed
    #####:  128:              return FALSE;
        -:  129:            }
        -:  130:        }
        -:  131:
        -:  132:      /* Write PID if requested */
    #####:  133:      if (print_pid_fd >= 0)
branch  0 never executed
branch  1 never executed
        -:  134:	{
        -:  135:	  DBusString pid;
        -:  136:	  int bytes;
        -:  137:	  
    #####:  138:	  if (!_dbus_string_init (&pid))
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  139:	    {
    #####:  140:	      _DBUS_SET_OOM (error);
call    0 never executed
    #####:  141:              kill (child_pid, SIGTERM);
call    0 never executed
    #####:  142:	      return FALSE;
        -:  143:	    }
        -:  144:	  
    #####:  145:	  if (!_dbus_string_append_int (&pid, child_pid) ||
call    0 never executed
branch  1 never executed
branch  2 never executed
call    3 never executed
branch  4 never executed
branch  5 never executed
        -:  146:	      !_dbus_string_append (&pid, "\n"))
        -:  147:	    {
    #####:  148:	      _dbus_string_free (&pid);
call    0 never executed
    #####:  149:	      _DBUS_SET_OOM (error);
call    0 never executed
    #####:  150:              kill (child_pid, SIGTERM);
call    0 never executed
    #####:  151:	      return FALSE;
        -:  152:	    }
        -:  153:	  
    #####:  154:	  bytes = _dbus_string_get_length (&pid);
call    0 never executed
    #####:  155:	  if (_dbus_write (print_pid_fd, &pid, 0, bytes) != bytes)
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  156:	    {
    #####:  157:	      dbus_set_error (error, DBUS_ERROR_FAILED,
call    0 never executed
call    1 never executed
call    2 never executed
        -:  158:			      "Printing message bus PID: %s\n",
        -:  159:			      _dbus_strerror (errno));
    #####:  160:	      _dbus_string_free (&pid);
call    0 never executed
    #####:  161:              kill (child_pid, SIGTERM);
call    0 never executed
    #####:  162:	      return FALSE;
        -:  163:	    }
        -:  164:	  
    #####:  165:	  _dbus_string_free (&pid);
call    0 never executed
        -:  166:	}
    #####:  167:      _dbus_verbose ("parent exiting\n");
call    0 never executed
    #####:  168:      _exit (0);
call    0 never executed
        -:  169:      break;
        -:  170:    }
        -:  171:
        1:  172:  _dbus_verbose ("calling setsid()\n");
call    0 returned 100%
        1:  173:  if (setsid () == -1)
call    0 returned 100%
branch  1 taken 0%
branch  2 taken 100%
    #####:  174:    _dbus_assert_not_reached ("setsid() failed");
call    0 never executed
        -:  175:  
        1:  176:  return TRUE;
        -:  177:}
        -:  178:
        -:  179:
        -:  180:/**
        -:  181: * Creates a file containing the process ID.
        -:  182: *
        -:  183: * @param filename the filename to write to
        -:  184: * @param pid our process ID
        -:  185: * @param error return location for errors
        -:  186: * @returns #FALSE on failure
        -:  187: */
        -:  188:dbus_bool_t
        -:  189:_dbus_write_pid_file (const DBusString *filename,
        -:  190:                      unsigned long     pid,
        -:  191:		      DBusError        *error)
function _dbus_write_pid_file called 0 returned 0% blocks executed 0%
    #####:  192:{
        -:  193:  const char *cfilename;
        -:  194:  int fd;
        -:  195:  FILE *f;
        -:  196:
    #####:  197:  cfilename = _dbus_string_get_const_data (filename);
call    0 never executed
        -:  198:  
    #####:  199:  fd = open (cfilename, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, 0644);
call    0 never executed
        -:  200:  
    #####:  201:  if (fd < 0)
branch  0 never executed
branch  1 never executed
        -:  202:    {
    #####:  203:      dbus_set_error (error, _dbus_error_from_errno (errno),
call    0 never executed
call    1 never executed
call    2 never executed
call    3 never executed
call    4 never executed
        -:  204:                      "Failed to open \"%s\": %s", cfilename,
        -:  205:                      _dbus_strerror (errno));
    #####:  206:      return FALSE;
        -:  207:    }
        -:  208:
    #####:  209:  if ((f = fdopen (fd, "w")) == NULL)
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  210:    {
    #####:  211:      dbus_set_error (error, _dbus_error_from_errno (errno),
call    0 never executed
call    1 never executed
call    2 never executed
call    3 never executed
call    4 never executed
        -:  212:                      "Failed to fdopen fd %d: %s", fd, _dbus_strerror (errno));
    #####:  213:      close (fd);
call    0 never executed
    #####:  214:      return FALSE;
        -:  215:    }
        -:  216:  
    #####:  217:  if (fprintf (f, "%lu\n", pid) < 0)
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  218:    {
    #####:  219:      dbus_set_error (error, _dbus_error_from_errno (errno),
call    0 never executed
call    1 never executed
call    2 never executed
call    3 never executed
call    4 never executed
        -:  220:                      "Failed to write to \"%s\": %s", cfilename,
        -:  221:                      _dbus_strerror (errno));
    #####:  222:      return FALSE;
        -:  223:    }
        -:  224:
    #####:  225:  if (fclose (f) == EOF)
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  226:    {
    #####:  227:      dbus_set_error (error, _dbus_error_from_errno (errno),
call    0 never executed
call    1 never executed
call    2 never executed
call    3 never executed
call    4 never executed
        -:  228:                      "Failed to close \"%s\": %s", cfilename,
        -:  229:                      _dbus_strerror (errno));
    #####:  230:      return FALSE;
        -:  231:    }
        -:  232:  
    #####:  233:  return TRUE;
        -:  234:}
        -:  235:
        -:  236:
        -:  237:/**
        -:  238: * Changes the user and group the bus is running as.
        -:  239: *
        -:  240: * @param uid the new user ID
        -:  241: * @param gid the new group ID
        -:  242: * @param error return location for errors
        -:  243: * @returns #FALSE on failure
        -:  244: */
        -:  245:dbus_bool_t
        -:  246:_dbus_change_identity  (dbus_uid_t     uid,
        -:  247:                        dbus_gid_t     gid,
        -:  248:                        DBusError     *error)
function _dbus_change_identity called 0 returned 0% blocks executed 0%
    #####:  249:{
        -:  250:  /* setgroups() only works if we are a privileged process,
        -:  251:   * so we don't return error on failure; the only possible
        -:  252:   * failure is that we don't have perms to do it.
        -:  253:   * FIXME not sure this is right, maybe if setuid()
        -:  254:   * is going to work then setgroups() should also work.
        -:  255:   */
    #####:  256:  if (setgroups (0, NULL) < 0)
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  257:    _dbus_warn ("Failed to drop supplementary groups: %s\n",
call    0 never executed
call    1 never executed
call    2 never executed
        -:  258:                _dbus_strerror (errno));
        -:  259:  
        -:  260:  /* Set GID first, or the setuid may remove our permission
        -:  261:   * to change the GID
        -:  262:   */
    #####:  263:  if (setgid (gid) < 0)
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  264:    {
    #####:  265:      dbus_set_error (error, _dbus_error_from_errno (errno),
call    0 never executed
call    1 never executed
call    2 never executed
call    3 never executed
call    4 never executed
        -:  266:                      "Failed to set GID to %lu: %s", gid,
        -:  267:                      _dbus_strerror (errno));
    #####:  268:      return FALSE;
        -:  269:    }
        -:  270:  
    #####:  271:  if (setuid (uid) < 0)
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  272:    {
    #####:  273:      dbus_set_error (error, _dbus_error_from_errno (errno),
call    0 never executed
call    1 never executed
call    2 never executed
call    3 never executed
call    4 never executed
        -:  274:                      "Failed to set UID to %lu: %s", uid,
        -:  275:                      _dbus_strerror (errno));
    #####:  276:      return FALSE;
        -:  277:    }
        -:  278:  
    #####:  279:  return TRUE;
        -:  280:}
        -:  281:
        -:  282:/** Installs a UNIX signal handler
        -:  283: *
        -:  284: * @param sig the signal to handle
        -:  285: * @param handler the handler
        -:  286: */
        -:  287:void
        -:  288:_dbus_set_signal_handler (int               sig,
        -:  289:                          DBusSignalHandler handler)
function _dbus_set_signal_handler called 1529 returned 100% blocks executed 100%
     1529:  290:{
        -:  291:  struct sigaction act;
        -:  292:  sigset_t empty_mask;
        -:  293:  
     1529:  294:  sigemptyset (&empty_mask);
call    0 returned 100%
     1529:  295:  act.sa_handler = handler;
     1529:  296:  act.sa_mask    = empty_mask;
     1529:  297:  act.sa_flags   = 0;
     1529:  298:  sigaction (sig,  &act, 0);
call    0 returned 100%
     1529:  299:}
        -:  300:
        -:  301:
        -:  302:/**
        -:  303: * Removes a directory; Directory must be empty
        -:  304: * 
        -:  305: * @param filename directory filename
        -:  306: * @param error initialized error object
        -:  307: * @returns #TRUE on success
        -:  308: */
        -:  309:dbus_bool_t
        -:  310:_dbus_delete_directory (const DBusString *filename,
        -:  311:			DBusError        *error)
function _dbus_delete_directory called 2 returned 100% blocks executed 53%
        2:  312:{
        -:  313:  const char *filename_c;
        -:  314:  
        2:  315:  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
call    2 never executed
branch  3 never executed
branch  4 never executed
call    5 returned 100%
        -:  316:
        2:  317:  filename_c = _dbus_string_get_const_data (filename);
call    0 returned 100%
        -:  318:
        2:  319:  if (rmdir (filename_c) != 0)
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  320:    {
    #####:  321:      dbus_set_error (error, DBUS_ERROR_FAILED,
call    0 never executed
call    1 never executed
call    2 never executed
        -:  322:		      "Failed to remove directory %s: %s\n",
        -:  323:		      filename_c, _dbus_strerror (errno));
    #####:  324:      return FALSE;
        -:  325:    }
        -:  326:  
        2:  327:  return TRUE;
        -:  328:}
        -:  329:
        -:  330:/** Checks if a file exists
        -:  331:*
        -:  332:* @param file full path to the file
        -:  333:* @returns #TRUE if file exists
        -:  334:*/
        -:  335:dbus_bool_t 
        -:  336:_dbus_file_exists (const char *file)
function _dbus_file_exists called 6096 returned 100% blocks executed 100%
     6096:  337:{
     6096:  338:  return (access (file, F_OK) == 0);
call    0 returned 100%
        -:  339:}
        -:  340:
        -:  341:/** Checks if user is at the console
        -:  342:*
        -:  343:* @param username user to check
        -:  344:* @param error return location for errors
        -:  345:* @returns #TRUE is the user is at the consolei and there are no errors
        -:  346:*/
        -:  347:dbus_bool_t 
        -:  348:_dbus_user_at_console (const char *username,
        -:  349:                       DBusError  *error)
function _dbus_user_at_console called 6117 returned 100% blocks executed 100%
     6117:  350:{
        -:  351:
        -:  352:  DBusString f;
        -:  353:  dbus_bool_t result;
        -:  354:
     6117:  355:  result = FALSE;
     6117:  356:  if (!_dbus_string_init (&f))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  357:    {
        7:  358:      _DBUS_SET_OOM (error);
call    0 returned 100%
        7:  359:      return FALSE;
        -:  360:    }
        -:  361:
     6110:  362:  if (!_dbus_string_append (&f, DBUS_CONSOLE_AUTH_DIR))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  363:    {
        7:  364:      _DBUS_SET_OOM (error);
call    0 returned 100%
        7:  365:      goto out;
        -:  366:    }
        -:  367:
        -:  368:
     6103:  369:  if (!_dbus_string_append (&f, username))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  370:    {
        7:  371:      _DBUS_SET_OOM (error);
call    0 returned 100%
        7:  372:      goto out;
        -:  373:    }
        -:  374:
     6096:  375:  result = _dbus_file_exists (_dbus_string_get_const_data (&f));
call    0 returned 100%
call    1 returned 100%
        -:  376:
     6110:  377: out:
     6110:  378:  _dbus_string_free (&f);
call    0 returned 100%
        -:  379:
     6110:  380:  return result;
        -:  381:}
        -:  382:
        -:  383:
        -:  384:/**
        -:  385: * Checks whether the filename is an absolute path
        -:  386: *
        -:  387: * @param filename the filename
        -:  388: * @returns #TRUE if an absolute path
        -:  389: */
        -:  390:dbus_bool_t
        -:  391:_dbus_path_is_absolute (const DBusString *filename)
function _dbus_path_is_absolute called 55 returned 100% blocks executed 100%
       55:  392:{
       55:  393:  if (_dbus_string_get_length (filename) > 0)
call    0 returned 100%
branch  1 taken 98% (fallthrough)
branch  2 taken 2%
       54:  394:    return _dbus_string_get_byte (filename, 0) == '/';
call    0 returned 100%
        -:  395:  else
        1:  396:    return FALSE;
        -:  397:}
        -:  398:
        -:  399:/**
        -:  400: * stat() wrapper.
        -:  401: *
        -:  402: * @param filename the filename to stat
        -:  403: * @param statbuf the stat info to fill in
        -:  404: * @param error return location for error
        -:  405: * @returns #FALSE if error was set
        -:  406: */
        -:  407:dbus_bool_t
        -:  408:_dbus_stat (const DBusString *filename,
        -:  409:            DBusStat         *statbuf,
        -:  410:            DBusError        *error)
function _dbus_stat called 7859 returned 100% blocks executed 94%
     7859:  411:{
        -:  412:  const char *filename_c;
        -:  413:  struct stat sb;
        -:  414:
     7859:  415:  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
call    2 returned 100%
branch  3 taken 100% (fallthrough)
branch  4 taken 0%
call    5 returned 100%
        -:  416:  
     7859:  417:  filename_c = _dbus_string_get_const_data (filename);
call    0 returned 100%
        -:  418:
     7859:  419:  if (stat (filename_c, &sb) < 0)
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  420:    {
        1:  421:      dbus_set_error (error, _dbus_error_from_errno (errno),
call    0 returned 100%
call    1 returned 100%
call    2 returned 100%
call    3 returned 100%
call    4 returned 100%
        -:  422:                      "%s", _dbus_strerror (errno));
        1:  423:      return FALSE;
        -:  424:    }
        -:  425:
     7858:  426:  statbuf->mode = sb.st_mode;
     7858:  427:  statbuf->nlink = sb.st_nlink;
     7858:  428:  statbuf->uid = sb.st_uid;
     7858:  429:  statbuf->gid = sb.st_gid;
     7858:  430:  statbuf->size = sb.st_size;
     7858:  431:  statbuf->atime = sb.st_atime;
     7858:  432:  statbuf->mtime = sb.st_mtime;
     7858:  433:  statbuf->ctime = sb.st_ctime;
        -:  434:
     7858:  435:  return TRUE;
        -:  436:}
        -:  437:
        -:  438:
        -:  439:/**
        -:  440: * Internals of directory iterator
        -:  441: */
        -:  442:struct DBusDirIter
        -:  443:{
        -:  444:  DIR *d; /**< The DIR* from opendir() */
        -:  445:  
        -:  446:};
        -:  447:
        -:  448:/**
        -:  449: * Open a directory to iterate over.
        -:  450: *
        -:  451: * @param filename the directory name
        -:  452: * @param error exception return object or #NULL
        -:  453: * @returns new iterator, or #NULL on error
        -:  454: */
        -:  455:DBusDirIter*
        -:  456:_dbus_directory_open (const DBusString *filename,
        -:  457:                      DBusError        *error)
function _dbus_directory_open called 796 returned 100% blocks executed 95%
      796:  458:{
        -:  459:  DIR *d;
        -:  460:  DBusDirIter *iter;
        -:  461:  const char *filename_c;
        -:  462:
      796:  463:  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
branch  0 taken 99% (fallthrough)
branch  1 taken 1%
call    2 returned 100%
branch  3 taken 100% (fallthrough)
branch  4 taken 0%
call    5 returned 100%
        -:  464:  
      796:  465:  filename_c = _dbus_string_get_const_data (filename);
call    0 returned 100%
        -:  466:
      796:  467:  d = opendir (filename_c);
call    0 returned 100%
      796:  468:  if (d == NULL)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        -:  469:    {
       10:  470:      dbus_set_error (error, _dbus_error_from_errno (errno),
call    0 returned 100%
call    1 returned 100%
call    2 returned 100%
call    3 returned 100%
call    4 returned 100%
        -:  471:                      "Failed to read directory \"%s\": %s",
        -:  472:                      filename_c,
        -:  473:                      _dbus_strerror (errno));
       10:  474:      return NULL;
        -:  475:    }
      786:  476:  iter = dbus_new0 (DBusDirIter, 1);
call    0 returned 100%
      786:  477:  if (iter == NULL)
branch  0 taken 2% (fallthrough)
branch  1 taken 98%
        -:  478:    {
       15:  479:      closedir (d);
call    0 returned 100%
       15:  480:      dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
call    0 returned 100%
        -:  481:                      "Could not allocate memory for directory iterator");
       15:  482:      return NULL;
        -:  483:    }
        -:  484:
      771:  485:  iter->d = d;
        -:  486:
      771:  487:  return iter;
        -:  488:}
        -:  489:
        -:  490:/**
        -:  491: * Get next file in the directory. Will not return "." or ".."  on
        -:  492: * UNIX. If an error occurs, the contents of "filename" are
        -:  493: * undefined. The error is never set if the function succeeds.
        -:  494: *
        -:  495: * @todo for thread safety, I think we have to use
        -:  496: * readdir_r(). (GLib has the same issue, should file a bug.)
        -:  497: *
        -:  498: * @param iter the iterator
        -:  499: * @param filename string to be set to the next file in the dir
        -:  500: * @param error return location for error
        -:  501: * @returns #TRUE if filename was filled in with a new filename
        -:  502: */
        -:  503:dbus_bool_t
        -:  504:_dbus_directory_get_next_file (DBusDirIter      *iter,
        -:  505:                               DBusString       *filename,
        -:  506:                               DBusError        *error)
function _dbus_directory_get_next_file called 7888 returned 100% blocks executed 79%
     7888:  507:{
        -:  508:  struct dirent *ent;
        -:  509:
     7888:  510:  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
branch  0 taken 99% (fallthrough)
branch  1 taken 1%
call    2 returned 100%
branch  3 taken 100% (fallthrough)
branch  4 taken 0%
call    5 returned 100%
        -:  511:  
     9250:  512: again:
     9250:  513:  errno = 0;
call    0 returned 100%
     9250:  514:  ent = readdir (iter->d);
call    0 returned 100%
     9250:  515:  if (ent == NULL)
branch  0 taken 6% (fallthrough)
branch  1 taken 94%
        -:  516:    {
      568:  517:      if (errno != 0)
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  518:        dbus_set_error (error,
call    0 never executed
call    1 never executed
call    2 never executed
call    3 never executed
call    4 never executed
        -:  519:                        _dbus_error_from_errno (errno),
        -:  520:                        "%s", _dbus_strerror (errno));
      568:  521:      return FALSE;
        -:  522:    }
     8682:  523:  else if (ent->d_name[0] == '.' &&
branch  0 taken 22% (fallthrough)
branch  1 taken 78%
branch  2 taken 36%
branch  3 taken 64% (fallthrough)
branch  4 taken 55% (fallthrough)
branch  5 taken 45%
branch  6 taken 100%
branch  7 taken 0% (fallthrough)
        -:  524:           (ent->d_name[1] == '\0' ||
        -:  525:            (ent->d_name[1] == '.' && ent->d_name[2] == '\0')))
        -:  526:    goto again;
        -:  527:  else
        -:  528:    {
     7320:  529:      _dbus_string_set_length (filename, 0);
call    0 returned 100%
     7320:  530:      if (!_dbus_string_append (filename, ent->d_name))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  531:        {
       21:  532:          dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
call    0 returned 100%
        -:  533:                          "No memory to read directory entry");
       21:  534:          return FALSE;
        -:  535:        }
        -:  536:      else
     7299:  537:        return TRUE;
        -:  538:    }
        -:  539:}
        -:  540:
        -:  541:/**
        -:  542: * Closes a directory iteration.
        -:  543: */
        -:  544:void
        -:  545:_dbus_directory_close (DBusDirIter *iter)
function _dbus_directory_close called 771 returned 100% blocks executed 100%
      771:  546:{
      771:  547:  closedir (iter->d);
call    0 returned 100%
      771:  548:  dbus_free (iter);
call    0 returned 100%
      771:  549:}
        -:  550:
        -:  551:static dbus_bool_t
        -:  552:fill_user_info_from_group (struct group  *g,
        -:  553:                           DBusGroupInfo *info,
        -:  554:                           DBusError     *error)
function fill_user_info_from_group called 0 returned 0% blocks executed 0%
    #####:  555:{
    #####:  556:  _dbus_assert (g->gr_name != NULL);
call    0 never executed
        -:  557:  
    #####:  558:  info->gid = g->gr_gid;
    #####:  559:  info->groupname = _dbus_strdup (g->gr_name);
call    0 never executed
        -:  560:
        -:  561:  /* info->members = dbus_strdupv (g->gr_mem) */
        -:  562:  
    #####:  563:  if (info->groupname == NULL)
branch  0 never executed
branch  1 never executed
        -:  564:    {
    #####:  565:      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call    0 never executed
    #####:  566:      return FALSE;
        -:  567:    }
        -:  568:
    #####:  569:  return TRUE;
        -:  570:}
        -:  571:
        -:  572:static dbus_bool_t
        -:  573:fill_group_info (DBusGroupInfo    *info,
        -:  574:                 dbus_gid_t        gid,
        -:  575:                 const DBusString *groupname,
        -:  576:                 DBusError        *error)
function fill_group_info called 0 returned 0% blocks executed 0%
    #####:  577:{
        -:  578:  const char *group_c_str;
        -:  579:
    #####:  580:  _dbus_assert (groupname != NULL || gid != DBUS_GID_UNSET);
branch  0 never executed
branch  1 never executed
branch  2 never executed
branch  3 never executed
call    4 never executed
    #####:  581:  _dbus_assert (groupname == NULL || gid == DBUS_GID_UNSET);
branch  0 never executed
branch  1 never executed
branch  2 never executed
branch  3 never executed
call    4 never executed
        -:  582:
    #####:  583:  if (groupname)
branch  0 never executed
branch  1 never executed
    #####:  584:    group_c_str = _dbus_string_get_const_data (groupname);
call    0 never executed
        -:  585:  else
    #####:  586:    group_c_str = NULL;
        -:  587:  
        -:  588:  /* For now assuming that the getgrnam() and getgrgid() flavors
        -:  589:   * always correspond to the pwnam flavors, if not we have
        -:  590:   * to add more configure checks.
        -:  591:   */
        -:  592:  
        -:  593:#if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
        -:  594:  {
        -:  595:    struct group *g;
        -:  596:    int result;
        -:  597:    char buf[1024];
        -:  598:    struct group g_str;
        -:  599:
    #####:  600:    g = NULL;
        -:  601:#ifdef HAVE_POSIX_GETPWNAM_R
        -:  602:
    #####:  603:    if (group_c_str)
branch  0 never executed
branch  1 never executed
    #####:  604:      result = getgrnam_r (group_c_str, &g_str, buf, sizeof (buf),
call    0 never executed
        -:  605:                           &g);
        -:  606:    else
    #####:  607:      result = getgrgid_r (gid, &g_str, buf, sizeof (buf),
call    0 never executed
        -:  608:                           &g);
        -:  609:#else
        -:  610:    g = getgrnam_r (group_c_str, &g_str, buf, sizeof (buf));
        -:  611:    result = 0;
        -:  612:#endif /* !HAVE_POSIX_GETPWNAM_R */
    #####:  613:    if (result == 0 && g == &g_str)
branch  0 never executed
branch  1 never executed
branch  2 never executed
branch  3 never executed
        -:  614:      {
    #####:  615:        return fill_user_info_from_group (g, info, error);
call    0 never executed
        -:  616:      }
        -:  617:    else
        -:  618:      {
    #####:  619:        dbus_set_error (error, _dbus_error_from_errno (errno),
branch  0 never executed
branch  1 never executed
call    2 never executed
call    3 never executed
call    4 never executed
        -:  620:                        "Group %s unknown or failed to look it up\n",
        -:  621:                        group_c_str ? group_c_str : "???");
    #####:  622:        return FALSE;
        -:  623:      }
        -:  624:  }
        -:  625:#else /* ! HAVE_GETPWNAM_R */
        -:  626:  {
        -:  627:    /* I guess we're screwed on thread safety here */
        -:  628:    struct group *g;
        -:  629:
        -:  630:    g = getgrnam (group_c_str);
        -:  631:
        -:  632:    if (g != NULL)
        -:  633:      {
        -:  634:        return fill_user_info_from_group (g, info, error);
        -:  635:      }
        -:  636:    else
        -:  637:      {
        -:  638:        dbus_set_error (error, _dbus_error_from_errno (errno),
        -:  639:                        "Group %s unknown or failed to look it up\n",
        -:  640:                        group_c_str ? group_c_str : "???");
        -:  641:        return FALSE;
        -:  642:      }
        -:  643:  }
        -:  644:#endif  /* ! HAVE_GETPWNAM_R */
        -:  645:}
        -:  646:
        -:  647:/**
        -:  648: * Initializes the given DBusGroupInfo struct
        -:  649: * with information about the given group name.
        -:  650: *
        -:  651: * @param info the group info struct
        -:  652: * @param groupname name of group
        -:  653: * @param error the error return
        -:  654: * @returns #FALSE if error is set
        -:  655: */
        -:  656:dbus_bool_t
        -:  657:_dbus_group_info_fill (DBusGroupInfo    *info,
        -:  658:                       const DBusString *groupname,
        -:  659:                       DBusError        *error)
function _dbus_group_info_fill called 0 returned 0% blocks executed 0%
    #####:  660:{
    #####:  661:  return fill_group_info (info, DBUS_GID_UNSET,
call    0 never executed
        -:  662:                          groupname, error);
        -:  663:
        -:  664:}
        -:  665:
        -:  666:/**
        -:  667: * Initializes the given DBusGroupInfo struct
        -:  668: * with information about the given group ID.
        -:  669: *
        -:  670: * @param info the group info struct
        -:  671: * @param gid group ID
        -:  672: * @param error the error return
        -:  673: * @returns #FALSE if error is set
        -:  674: */
        -:  675:dbus_bool_t
        -:  676:_dbus_group_info_fill_gid (DBusGroupInfo *info,
        -:  677:                           dbus_gid_t     gid,
        -:  678:                           DBusError     *error)
function _dbus_group_info_fill_gid called 0 returned 0% blocks executed 0%
    #####:  679:{
    #####:  680:  return fill_group_info (info, gid, NULL, error);
call    0 never executed
        -:  681:}
        -:  682:
        -:  683:/** @} */ /* End of DBusInternalsUtils functions */
        -:  684:
        -:  685:/**
        -:  686: * @addtogroup DBusString
        -:  687: *
        -:  688: * @{
        -:  689: */
        -:  690:/**
        -:  691: * Get the directory name from a complete filename
        -:  692: * @param filename the filename
        -:  693: * @param dirname string to append directory name to
        -:  694: * @returns #FALSE if no memory
        -:  695: */
        -:  696:dbus_bool_t
        -:  697:_dbus_string_get_dirname  (const DBusString *filename,
        -:  698:                           DBusString       *dirname)
function _dbus_string_get_dirname called 63 returned 100% blocks executed 100%
       63:  699:{
        -:  700:  int sep;
        -:  701:  
       63:  702:  _dbus_assert (filename != dirname);
call    0 returned 100%
       63:  703:  _dbus_assert (filename != NULL);
call    0 returned 100%
       63:  704:  _dbus_assert (dirname != NULL);
call    0 returned 100%
        -:  705:
        -:  706:  /* Ignore any separators on the end */
       63:  707:  sep = _dbus_string_get_length (filename);
call    0 returned 100%
       63:  708:  if (sep == 0)
branch  0 taken 2% (fallthrough)
branch  1 taken 98%
        1:  709:    return _dbus_string_append (dirname, "."); /* empty string passed in */
call    0 returned 100%
        -:  710:    
      144:  711:  while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/')
branch  0 taken 98% (fallthrough)
branch  1 taken 2%
call    2 returned 100%
branch  3 taken 25%
branch  4 taken 75% (fallthrough)
       20:  712:    --sep;
        -:  713:
       62:  714:  _dbus_assert (sep >= 0);
call    0 returned 100%
        -:  715:  
       62:  716:  if (sep == 0)
branch  0 taken 3% (fallthrough)
branch  1 taken 97%
        2:  717:    return _dbus_string_append (dirname, "/");
call    0 returned 100%
        -:  718:  
        -:  719:  /* Now find the previous separator */
       60:  720:  _dbus_string_find_byte_backward (filename, sep, '/', &sep);
call    0 returned 100%
       60:  721:  if (sep < 0)
branch  0 taken 2% (fallthrough)
branch  1 taken 98%
        1:  722:    return _dbus_string_append (dirname, ".");
call    0 returned 100%
        -:  723:  
        -:  724:  /* skip multiple separators */
      133:  725:  while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/')
branch  0 taken 97% (fallthrough)
branch  1 taken 3%
call    2 returned 100%
branch  3 taken 21%
branch  4 taken 79% (fallthrough)
       15:  726:    --sep;
        -:  727:
       59:  728:  _dbus_assert (sep >= 0);
call    0 returned 100%
        -:  729:  
       59:  730:  if (sep == 0 &&
branch  0 taken 3% (fallthrough)
branch  1 taken 97%
call    2 returned 100%
branch  3 taken 100% (fallthrough)
branch  4 taken 0%
        -:  731:      _dbus_string_get_byte (filename, 0) == '/')
        2:  732:    return _dbus_string_append (dirname, "/");
call    0 returned 100%
        -:  733:  else
       57:  734:    return _dbus_string_copy_len (filename, 0, sep - 0,
call    0 returned 100%
call    1 returned 100%
        -:  735:                                  dirname, _dbus_string_get_length (dirname));
        -:  736:}
        -:  737:/** @} */ /* DBusString stuff */
        -:  738:
        -:  739:
        -:  740:#ifdef DBUS_BUILD_TESTS
        -:  741:#include <stdlib.h>
        -:  742:static void
        -:  743:check_dirname (const char *filename,
        -:  744:               const char *dirname)
function check_dirname called 18 returned 100% blocks executed 64%
       18:  745:{
        -:  746:  DBusString f, d;
        -:  747:  
       18:  748:  _dbus_string_init_const (&f, filename);
call    0 returned 100%
        -:  749:
       18:  750:  if (!_dbus_string_init (&d))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  751:    _dbus_assert_not_reached ("no memory");
call    0 never executed
        -:  752:
       18:  753:  if (!_dbus_string_get_dirname (&f, &d))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  754:    _dbus_assert_not_reached ("no memory");
call    0 never executed
        -:  755:
       18:  756:  if (!_dbus_string_equal_c_str (&d, dirname))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  757:    {
    #####:  758:      _dbus_warn ("For filename \"%s\" got dirname \"%s\" and expected \"%s\"\n",
call    0 never executed
call    1 never executed
        -:  759:                  filename,
        -:  760:                  _dbus_string_get_const_data (&d),
        -:  761:                  dirname);
    #####:  762:      exit (1);
call    0 never executed
        -:  763:    }
        -:  764:
       18:  765:  _dbus_string_free (&d);
call    0 returned 100%
       18:  766:}
        -:  767:
        -:  768:static void
        -:  769:check_path_absolute (const char *path,
        -:  770:                     dbus_bool_t expected)
function check_path_absolute called 5 returned 100% blocks executed 57%
        5:  771:{
        -:  772:  DBusString p;
        -:  773:
        5:  774:  _dbus_string_init_const (&p, path);
call    0 returned 100%
        -:  775:
        5:  776:  if (_dbus_path_is_absolute (&p) != expected)
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  777:    {
    #####:  778:      _dbus_warn ("For path \"%s\" expected absolute = %d got %d\n",
call    0 never executed
call    1 never executed
        -:  779:                  path, expected, _dbus_path_is_absolute (&p));
    #####:  780:      exit (1);
call    0 never executed
        -:  781:    }
        5:  782:}
        -:  783:
        -:  784:/**
        -:  785: * Unit test for dbus-sysdeps.c.
        -:  786: * 
        -:  787: * @returns #TRUE on success.
        -:  788: */
        -:  789:dbus_bool_t
        -:  790:_dbus_sysdeps_test (void)
function _dbus_sysdeps_test called 1 returned 100% blocks executed 73%
        1:  791:{
        -:  792:  DBusString str;
        -:  793:  double val;
        -:  794:  int pos;
        -:  795:  
        1:  796:  check_dirname ("foo", ".");
call    0 returned 100%
        1:  797:  check_dirname ("foo/bar", "foo");
call    0 returned 100%
        1:  798:  check_dirname ("foo//bar", "foo");
call    0 returned 100%
        1:  799:  check_dirname ("foo///bar", "foo");
call    0 returned 100%
        1:  800:  check_dirname ("foo/bar/", "foo");
call    0 returned 100%
        1:  801:  check_dirname ("foo//bar/", "foo");
call    0 returned 100%
        1:  802:  check_dirname ("foo///bar/", "foo");
call    0 returned 100%
        1:  803:  check_dirname ("foo/bar//", "foo");
call    0 returned 100%
        1:  804:  check_dirname ("foo//bar////", "foo");
call    0 returned 100%
        1:  805:  check_dirname ("foo///bar///////", "foo");
call    0 returned 100%
        1:  806:  check_dirname ("/foo", "/");
call    0 returned 100%
        1:  807:  check_dirname ("////foo", "/");
call    0 returned 100%
        1:  808:  check_dirname ("/foo/bar", "/foo");
call    0 returned 100%
        1:  809:  check_dirname ("/foo//bar", "/foo");
call    0 returned 100%
        1:  810:  check_dirname ("/foo///bar", "/foo");
call    0 returned 100%
        1:  811:  check_dirname ("/", "/");
call    0 returned 100%
        1:  812:  check_dirname ("///", "/");
call    0 returned 100%
        1:  813:  check_dirname ("", ".");  
call    0 returned 100%
        -:  814:
        -:  815:
        1:  816:  _dbus_string_init_const (&str, "3.5");
call    0 returned 100%
        1:  817:  if (!_dbus_string_parse_double (&str,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  818:				  0, &val, &pos))
        -:  819:    {
    #####:  820:      _dbus_warn ("Failed to parse double");
call    0 never executed
    #####:  821:      exit (1);
call    0 never executed
        -:  822:    }
        1:  823:  if (ABS(3.5 - val) > 1e-6)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
branch  2 taken 0% (fallthrough)
branch  3 taken 100%
        -:  824:    {
    #####:  825:      _dbus_warn ("Failed to parse 3.5 correctly, got: %f", val);
call    0 never executed
    #####:  826:      exit (1);
call    0 never executed
        -:  827:    }
        1:  828:  if (pos != 3)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  829:    {
    #####:  830:      _dbus_warn ("_dbus_string_parse_double of \"3.5\" returned wrong position %d", pos);
call    0 never executed
    #####:  831:      exit (1);
call    0 never executed
        -:  832:    }
        -:  833:
        1:  834:  _dbus_string_init_const (&str, "0xff");
call    0 returned 100%
        1:  835:  if (!_dbus_string_parse_double (&str,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  836:				  0, &val, &pos))
        -:  837:    {
    #####:  838:      _dbus_warn ("Failed to parse double");
call    0 never executed
    #####:  839:      exit (1);
call    0 never executed
        -:  840:    }
        1:  841:  if (ABS (0xff - val) > 1e-6)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
branch  2 taken 0% (fallthrough)
branch  3 taken 100%
        -:  842:    {
    #####:  843:      _dbus_warn ("Failed to parse 0xff correctly, got: %f\n", val);
call    0 never executed
    #####:  844:      exit (1);
call    0 never executed
        -:  845:    }
        1:  846:  if (pos != 4)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  847:    {
    #####:  848:      _dbus_warn ("_dbus_string_parse_double of \"0xff\" returned wrong position %d", pos);
call    0 never executed
    #####:  849:      exit (1);
call    0 never executed
        -:  850:    }
        -:  851:  
        1:  852:  check_path_absolute ("/", TRUE);
call    0 returned 100%
        1:  853:  check_path_absolute ("/foo", TRUE);
call    0 returned 100%
        1:  854:  check_path_absolute ("", FALSE);
call    0 returned 100%
        1:  855:  check_path_absolute ("foo", FALSE);
call    0 returned 100%
        1:  856:  check_path_absolute ("foo/bar", FALSE);
call    0 returned 100%
        -:  857:  
        1:  858:  return TRUE;
        -:  859:}
        -:  860:#endif /* DBUS_BUILD_TESTS */