00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "dbus-sysdeps.h"
00025 #include "dbus-sysdeps-unix.h"
00026 #include "dbus-internals.h"
00027 #include "dbus-protocol.h"
00028 #include "dbus-string.h"
00029 #define DBUS_USERDB_INCLUDES_PRIVATE 1
00030 #include "dbus-userdb.h"
00031 #include "dbus-test.h"
00032
00033 #include <sys/types.h>
00034 #include <stdlib.h>
00035 #include <string.h>
00036 #include <signal.h>
00037 #include <unistd.h>
00038 #include <stdio.h>
00039 #include <errno.h>
00040 #include <fcntl.h>
00041 #include <sys/stat.h>
00042 #include <grp.h>
00043 #include <sys/socket.h>
00044 #include <dirent.h>
00045 #include <sys/un.h>
00046 #include <syslog.h>
00047 #include <syslog.h>
00048
00049 #ifdef HAVE_SYS_SYSLIMITS_H
00050 #include <sys/syslimits.h>
00051 #endif
00052
00053 #ifndef O_BINARY
00054 #define O_BINARY 0
00055 #endif
00056
00072 dbus_bool_t
00073 _dbus_become_daemon (const DBusString *pidfile,
00074 DBusPipe *print_pid_pipe,
00075 DBusError *error,
00076 dbus_bool_t keep_umask)
00077 {
00078 const char *s;
00079 pid_t child_pid;
00080 int dev_null_fd;
00081
00082 _dbus_verbose ("Becoming a daemon...\n");
00083
00084 _dbus_verbose ("chdir to /\n");
00085 if (chdir ("/") < 0)
00086 {
00087 dbus_set_error (error, DBUS_ERROR_FAILED,
00088 "Could not chdir() to root directory");
00089 return FALSE;
00090 }
00091
00092 _dbus_verbose ("forking...\n");
00093 switch ((child_pid = fork ()))
00094 {
00095 case -1:
00096 _dbus_verbose ("fork failed\n");
00097 dbus_set_error (error, _dbus_error_from_errno (errno),
00098 "Failed to fork daemon: %s", _dbus_strerror (errno));
00099 return FALSE;
00100 break;
00101
00102 case 0:
00103 _dbus_verbose ("in child, closing std file descriptors\n");
00104
00105
00106
00107
00108
00109
00110 dev_null_fd = open ("/dev/null", O_RDWR);
00111 if (dev_null_fd >= 0)
00112 {
00113 dup2 (dev_null_fd, 0);
00114 dup2 (dev_null_fd, 1);
00115
00116 s = _dbus_getenv ("DBUS_DEBUG_OUTPUT");
00117 if (s == NULL || *s == '\0')
00118 dup2 (dev_null_fd, 2);
00119 else
00120 _dbus_verbose ("keeping stderr open due to DBUS_DEBUG_OUTPUT\n");
00121 }
00122
00123 if (!keep_umask)
00124 {
00125
00126 _dbus_verbose ("setting umask\n");
00127 umask (022);
00128 }
00129
00130 _dbus_verbose ("calling setsid()\n");
00131 if (setsid () == -1)
00132 _dbus_assert_not_reached ("setsid() failed");
00133
00134 break;
00135
00136 default:
00137 if (!_dbus_write_pid_to_file_and_pipe (pidfile, print_pid_pipe,
00138 child_pid, error))
00139 {
00140 _dbus_verbose ("pid file or pipe write failed: %s\n",
00141 error->message);
00142 kill (child_pid, SIGTERM);
00143 return FALSE;
00144 }
00145
00146 _dbus_verbose ("parent exiting\n");
00147 _exit (0);
00148 break;
00149 }
00150
00151 return TRUE;
00152 }
00153
00154
00163 static dbus_bool_t
00164 _dbus_write_pid_file (const DBusString *filename,
00165 unsigned long pid,
00166 DBusError *error)
00167 {
00168 const char *cfilename;
00169 int fd;
00170 FILE *f;
00171
00172 cfilename = _dbus_string_get_const_data (filename);
00173
00174 fd = open (cfilename, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, 0644);
00175
00176 if (fd < 0)
00177 {
00178 dbus_set_error (error, _dbus_error_from_errno (errno),
00179 "Failed to open \"%s\": %s", cfilename,
00180 _dbus_strerror (errno));
00181 return FALSE;
00182 }
00183
00184 if ((f = fdopen (fd, "w")) == NULL)
00185 {
00186 dbus_set_error (error, _dbus_error_from_errno (errno),
00187 "Failed to fdopen fd %d: %s", fd, _dbus_strerror (errno));
00188 _dbus_close (fd, NULL);
00189 return FALSE;
00190 }
00191
00192 if (fprintf (f, "%lu\n", pid) < 0)
00193 {
00194 dbus_set_error (error, _dbus_error_from_errno (errno),
00195 "Failed to write to \"%s\": %s", cfilename,
00196 _dbus_strerror (errno));
00197
00198 fclose (f);
00199 return FALSE;
00200 }
00201
00202 if (fclose (f) == EOF)
00203 {
00204 dbus_set_error (error, _dbus_error_from_errno (errno),
00205 "Failed to close \"%s\": %s", cfilename,
00206 _dbus_strerror (errno));
00207 return FALSE;
00208 }
00209
00210 return TRUE;
00211 }
00212
00224 dbus_bool_t
00225 _dbus_write_pid_to_file_and_pipe (const DBusString *pidfile,
00226 DBusPipe *print_pid_pipe,
00227 dbus_pid_t pid_to_write,
00228 DBusError *error)
00229 {
00230 if (pidfile)
00231 {
00232 _dbus_verbose ("writing pid file %s\n", _dbus_string_get_const_data (pidfile));
00233 if (!_dbus_write_pid_file (pidfile,
00234 pid_to_write,
00235 error))
00236 {
00237 _dbus_verbose ("pid file write failed\n");
00238 _DBUS_ASSERT_ERROR_IS_SET(error);
00239 return FALSE;
00240 }
00241 }
00242 else
00243 {
00244 _dbus_verbose ("No pid file requested\n");
00245 }
00246
00247 if (print_pid_pipe != NULL && _dbus_pipe_is_valid (print_pid_pipe))
00248 {
00249 DBusString pid;
00250 int bytes;
00251
00252 _dbus_verbose ("writing our pid to pipe %d\n", print_pid_pipe->fd_or_handle);
00253
00254 if (!_dbus_string_init (&pid))
00255 {
00256 _DBUS_SET_OOM (error);
00257 return FALSE;
00258 }
00259
00260 if (!_dbus_string_append_int (&pid, pid_to_write) ||
00261 !_dbus_string_append (&pid, "\n"))
00262 {
00263 _dbus_string_free (&pid);
00264 _DBUS_SET_OOM (error);
00265 return FALSE;
00266 }
00267
00268 bytes = _dbus_string_get_length (&pid);
00269 if (_dbus_pipe_write (print_pid_pipe, &pid, 0, bytes, error) != bytes)
00270 {
00271
00272 if (error != NULL && !dbus_error_is_set(error))
00273 {
00274 dbus_set_error (error, DBUS_ERROR_FAILED,
00275 "Printing message bus PID: did not write enough bytes\n");
00276 }
00277 _dbus_string_free (&pid);
00278 return FALSE;
00279 }
00280
00281 _dbus_string_free (&pid);
00282 }
00283 else
00284 {
00285 _dbus_verbose ("No pid pipe to write to\n");
00286 }
00287
00288 return TRUE;
00289 }
00290
00297 dbus_bool_t
00298 _dbus_verify_daemon_user (const char *user)
00299 {
00300 DBusString u;
00301
00302 _dbus_string_init_const (&u, user);
00303
00304 return _dbus_get_user_id_and_primary_group (&u, NULL, NULL);
00305 }
00306
00307 void
00308 _dbus_init_system_log (void)
00309 {
00310 openlog ("dbus", LOG_PID, LOG_DAEMON);
00311 }
00312
00320 void
00321 _dbus_log_info (const char *msg, va_list args)
00322 {
00323 vsyslog (LOG_DAEMON|LOG_NOTICE, msg, args);
00324 }
00325
00333 void
00334 _dbus_log_security (const char *msg, va_list args)
00335 {
00336 vsyslog (LOG_AUTH|LOG_NOTICE, msg, args);
00337 }
00338
00344 void
00345 _dbus_set_signal_handler (int sig,
00346 DBusSignalHandler handler)
00347 {
00348 struct sigaction act;
00349 sigset_t empty_mask;
00350
00351 sigemptyset (&empty_mask);
00352 act.sa_handler = handler;
00353 act.sa_mask = empty_mask;
00354 act.sa_flags = 0;
00355 sigaction (sig, &act, NULL);
00356 }
00357
00358
00366 dbus_bool_t
00367 _dbus_delete_directory (const DBusString *filename,
00368 DBusError *error)
00369 {
00370 const char *filename_c;
00371
00372 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00373
00374 filename_c = _dbus_string_get_const_data (filename);
00375
00376 if (rmdir (filename_c) != 0)
00377 {
00378 dbus_set_error (error, DBUS_ERROR_FAILED,
00379 "Failed to remove directory %s: %s\n",
00380 filename_c, _dbus_strerror (errno));
00381 return FALSE;
00382 }
00383
00384 return TRUE;
00385 }
00386
00392 dbus_bool_t
00393 _dbus_file_exists (const char *file)
00394 {
00395 return (access (file, F_OK) == 0);
00396 }
00397
00404 dbus_bool_t
00405 _dbus_user_at_console (const char *username,
00406 DBusError *error)
00407 {
00408
00409 DBusString f;
00410 dbus_bool_t result;
00411
00412 result = FALSE;
00413 if (!_dbus_string_init (&f))
00414 {
00415 _DBUS_SET_OOM (error);
00416 return FALSE;
00417 }
00418
00419 if (!_dbus_string_append (&f, DBUS_CONSOLE_AUTH_DIR))
00420 {
00421 _DBUS_SET_OOM (error);
00422 goto out;
00423 }
00424
00425
00426 if (!_dbus_string_append (&f, username))
00427 {
00428 _DBUS_SET_OOM (error);
00429 goto out;
00430 }
00431
00432 result = _dbus_file_exists (_dbus_string_get_const_data (&f));
00433
00434 out:
00435 _dbus_string_free (&f);
00436
00437 return result;
00438 }
00439
00440
00447 dbus_bool_t
00448 _dbus_path_is_absolute (const DBusString *filename)
00449 {
00450 if (_dbus_string_get_length (filename) > 0)
00451 return _dbus_string_get_byte (filename, 0) == '/';
00452 else
00453 return FALSE;
00454 }
00455
00464 dbus_bool_t
00465 _dbus_stat (const DBusString *filename,
00466 DBusStat *statbuf,
00467 DBusError *error)
00468 {
00469 const char *filename_c;
00470 struct stat sb;
00471
00472 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00473
00474 filename_c = _dbus_string_get_const_data (filename);
00475
00476 if (stat (filename_c, &sb) < 0)
00477 {
00478 dbus_set_error (error, _dbus_error_from_errno (errno),
00479 "%s", _dbus_strerror (errno));
00480 return FALSE;
00481 }
00482
00483 statbuf->mode = sb.st_mode;
00484 statbuf->nlink = sb.st_nlink;
00485 statbuf->uid = sb.st_uid;
00486 statbuf->gid = sb.st_gid;
00487 statbuf->size = sb.st_size;
00488 statbuf->atime = sb.st_atime;
00489 statbuf->mtime = sb.st_mtime;
00490 statbuf->ctime = sb.st_ctime;
00491
00492 return TRUE;
00493 }
00494
00495
00499 struct DBusDirIter
00500 {
00501 DIR *d;
00503 };
00504
00512 DBusDirIter*
00513 _dbus_directory_open (const DBusString *filename,
00514 DBusError *error)
00515 {
00516 DIR *d;
00517 DBusDirIter *iter;
00518 const char *filename_c;
00519
00520 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00521
00522 filename_c = _dbus_string_get_const_data (filename);
00523
00524 d = opendir (filename_c);
00525 if (d == NULL)
00526 {
00527 dbus_set_error (error, _dbus_error_from_errno (errno),
00528 "Failed to read directory \"%s\": %s",
00529 filename_c,
00530 _dbus_strerror (errno));
00531 return NULL;
00532 }
00533 iter = dbus_new0 (DBusDirIter, 1);
00534 if (iter == NULL)
00535 {
00536 closedir (d);
00537 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
00538 "Could not allocate memory for directory iterator");
00539 return NULL;
00540 }
00541
00542 iter->d = d;
00543
00544 return iter;
00545 }
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555 static dbus_bool_t
00556 dirent_buf_size(DIR * dirp, size_t *size)
00557 {
00558 long name_max;
00559 # if defined(HAVE_FPATHCONF) && defined(_PC_NAME_MAX)
00560 # if defined(HAVE_DIRFD)
00561 name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX);
00562 # elif defined(HAVE_DDFD)
00563 name_max = fpathconf(dirp->dd_fd, _PC_NAME_MAX);
00564 # else
00565 name_max = fpathconf(dirp->__dd_fd, _PC_NAME_MAX);
00566 # endif
00567 if (name_max == -1)
00568 # if defined(NAME_MAX)
00569 name_max = NAME_MAX;
00570 # else
00571 return FALSE;
00572 # endif
00573 # elif defined(MAXNAMELEN)
00574 name_max = MAXNAMELEN;
00575 # else
00576 # if defined(NAME_MAX)
00577 name_max = NAME_MAX;
00578 # else
00579 # error "buffer size for readdir_r cannot be determined"
00580 # endif
00581 # endif
00582 if (size)
00583 *size = (size_t)offsetof(struct dirent, d_name) + name_max + 1;
00584 else
00585 return FALSE;
00586
00587 return TRUE;
00588 }
00589
00600 dbus_bool_t
00601 _dbus_directory_get_next_file (DBusDirIter *iter,
00602 DBusString *filename,
00603 DBusError *error)
00604 {
00605 struct dirent *d, *ent;
00606 size_t buf_size;
00607 int err;
00608
00609 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00610
00611 if (!dirent_buf_size (iter->d, &buf_size))
00612 {
00613 dbus_set_error (error, DBUS_ERROR_FAILED,
00614 "Can't calculate buffer size when reading directory");
00615 return FALSE;
00616 }
00617
00618 d = (struct dirent *)dbus_malloc (buf_size);
00619 if (!d)
00620 {
00621 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
00622 "No memory to read directory entry");
00623 return FALSE;
00624 }
00625
00626 again:
00627 err = readdir_r (iter->d, d, &ent);
00628 if (err || !ent)
00629 {
00630 if (err != 0)
00631 dbus_set_error (error,
00632 _dbus_error_from_errno (err),
00633 "%s", _dbus_strerror (err));
00634
00635 dbus_free (d);
00636 return FALSE;
00637 }
00638 else if (ent->d_name[0] == '.' &&
00639 (ent->d_name[1] == '\0' ||
00640 (ent->d_name[1] == '.' && ent->d_name[2] == '\0')))
00641 goto again;
00642 else
00643 {
00644 _dbus_string_set_length (filename, 0);
00645 if (!_dbus_string_append (filename, ent->d_name))
00646 {
00647 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
00648 "No memory to read directory entry");
00649 dbus_free (d);
00650 return FALSE;
00651 }
00652 else
00653 {
00654 dbus_free (d);
00655 return TRUE;
00656 }
00657 }
00658 }
00659
00663 void
00664 _dbus_directory_close (DBusDirIter *iter)
00665 {
00666 closedir (iter->d);
00667 dbus_free (iter);
00668 }
00669
00670 static dbus_bool_t
00671 fill_user_info_from_group (struct group *g,
00672 DBusGroupInfo *info,
00673 DBusError *error)
00674 {
00675 _dbus_assert (g->gr_name != NULL);
00676
00677 info->gid = g->gr_gid;
00678 info->groupname = _dbus_strdup (g->gr_name);
00679
00680
00681
00682 if (info->groupname == NULL)
00683 {
00684 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00685 return FALSE;
00686 }
00687
00688 return TRUE;
00689 }
00690
00691 static dbus_bool_t
00692 fill_group_info (DBusGroupInfo *info,
00693 dbus_gid_t gid,
00694 const DBusString *groupname,
00695 DBusError *error)
00696 {
00697 const char *group_c_str;
00698
00699 _dbus_assert (groupname != NULL || gid != DBUS_GID_UNSET);
00700 _dbus_assert (groupname == NULL || gid == DBUS_GID_UNSET);
00701
00702 if (groupname)
00703 group_c_str = _dbus_string_get_const_data (groupname);
00704 else
00705 group_c_str = NULL;
00706
00707
00708
00709
00710
00711
00712 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
00713 {
00714 struct group *g;
00715 int result;
00716 size_t buflen;
00717 char *buf;
00718 struct group g_str;
00719 dbus_bool_t b;
00720
00721
00722 buflen = sysconf (_SC_GETGR_R_SIZE_MAX);
00723
00724
00725
00726
00727
00728 if ((long) buflen <= 0)
00729 buflen = 1024;
00730
00731 result = -1;
00732 while (1)
00733 {
00734 buf = dbus_malloc (buflen);
00735 if (buf == NULL)
00736 {
00737 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00738 return FALSE;
00739 }
00740
00741 g = NULL;
00742 #ifdef HAVE_POSIX_GETPWNAM_R
00743 if (group_c_str)
00744 result = getgrnam_r (group_c_str, &g_str, buf, buflen,
00745 &g);
00746 else
00747 result = getgrgid_r (gid, &g_str, buf, buflen,
00748 &g);
00749 #else
00750 g = getgrnam_r (group_c_str, &g_str, buf, buflen);
00751 result = 0;
00752 #endif
00753
00754
00755
00756 if (result == ERANGE && buflen < 512 * 1024)
00757 {
00758 dbus_free (buf);
00759 buflen *= 2;
00760 }
00761 else
00762 {
00763 break;
00764 }
00765 }
00766
00767 if (result == 0 && g == &g_str)
00768 {
00769 b = fill_user_info_from_group (g, info, error);
00770 dbus_free (buf);
00771 return b;
00772 }
00773 else
00774 {
00775 dbus_set_error (error, _dbus_error_from_errno (errno),
00776 "Group %s unknown or failed to look it up\n",
00777 group_c_str ? group_c_str : "???");
00778 dbus_free (buf);
00779 return FALSE;
00780 }
00781 }
00782 #else
00783 {
00784
00785 struct group *g;
00786
00787 g = getgrnam (group_c_str);
00788
00789 if (g != NULL)
00790 {
00791 return fill_user_info_from_group (g, info, error);
00792 }
00793 else
00794 {
00795 dbus_set_error (error, _dbus_error_from_errno (errno),
00796 "Group %s unknown or failed to look it up\n",
00797 group_c_str ? group_c_str : "???");
00798 return FALSE;
00799 }
00800 }
00801 #endif
00802 }
00803
00813 dbus_bool_t
00814 _dbus_group_info_fill (DBusGroupInfo *info,
00815 const DBusString *groupname,
00816 DBusError *error)
00817 {
00818 return fill_group_info (info, DBUS_GID_UNSET,
00819 groupname, error);
00820
00821 }
00822
00832 dbus_bool_t
00833 _dbus_group_info_fill_gid (DBusGroupInfo *info,
00834 dbus_gid_t gid,
00835 DBusError *error)
00836 {
00837 return fill_group_info (info, gid, NULL, error);
00838 }
00839
00848 dbus_bool_t
00849 _dbus_parse_unix_user_from_config (const DBusString *username,
00850 dbus_uid_t *uid_p)
00851 {
00852 return _dbus_get_user_id (username, uid_p);
00853
00854 }
00855
00864 dbus_bool_t
00865 _dbus_parse_unix_group_from_config (const DBusString *groupname,
00866 dbus_gid_t *gid_p)
00867 {
00868 return _dbus_get_group_id (groupname, gid_p);
00869 }
00870
00881 dbus_bool_t
00882 _dbus_unix_groups_from_uid (dbus_uid_t uid,
00883 dbus_gid_t **group_ids,
00884 int *n_group_ids)
00885 {
00886 return _dbus_groups_from_uid (uid, group_ids, n_group_ids);
00887 }
00888
00898 dbus_bool_t
00899 _dbus_unix_user_is_at_console (dbus_uid_t uid,
00900 DBusError *error)
00901 {
00902 return _dbus_is_console_user (uid, error);
00903
00904 }
00905
00913 dbus_bool_t
00914 _dbus_unix_user_is_process_owner (dbus_uid_t uid)
00915 {
00916 return uid == _dbus_geteuid ();
00917 }
00918
00926 dbus_bool_t
00927 _dbus_windows_user_is_process_owner (const char *windows_sid)
00928 {
00929 return FALSE;
00930 }
00931
00933
00945 dbus_bool_t
00946 _dbus_string_get_dirname (const DBusString *filename,
00947 DBusString *dirname)
00948 {
00949 int sep;
00950
00951 _dbus_assert (filename != dirname);
00952 _dbus_assert (filename != NULL);
00953 _dbus_assert (dirname != NULL);
00954
00955
00956 sep = _dbus_string_get_length (filename);
00957 if (sep == 0)
00958 return _dbus_string_append (dirname, ".");
00959
00960 while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/')
00961 --sep;
00962
00963 _dbus_assert (sep >= 0);
00964
00965 if (sep == 0)
00966 return _dbus_string_append (dirname, "/");
00967
00968
00969 _dbus_string_find_byte_backward (filename, sep, '/', &sep);
00970 if (sep < 0)
00971 return _dbus_string_append (dirname, ".");
00972
00973
00974 while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/')
00975 --sep;
00976
00977 _dbus_assert (sep >= 0);
00978
00979 if (sep == 0 &&
00980 _dbus_string_get_byte (filename, 0) == '/')
00981 return _dbus_string_append (dirname, "/");
00982 else
00983 return _dbus_string_copy_len (filename, 0, sep - 0,
00984 dirname, _dbus_string_get_length (dirname));
00985 }
00987
00988 static void
00989 string_squash_nonprintable (DBusString *str)
00990 {
00991 char *buf;
00992 int i, len;
00993
00994 buf = _dbus_string_get_data (str);
00995 len = _dbus_string_get_length (str);
00996
00997 for (i = 0; i < len; i++)
00998 {
00999 unsigned char c = (unsigned char) buf[i];
01000 if (c == '\0')
01001 c = ' ';
01002 else if (c < 0x20 || c > 127)
01003 c = '?';
01004 }
01005 }
01006
01021 dbus_bool_t
01022 _dbus_command_for_pid (unsigned long pid,
01023 DBusString *str,
01024 int max_len,
01025 DBusError *error)
01026 {
01027
01028 DBusString path;
01029 DBusString cmdline;
01030 int fd;
01031
01032 if (!_dbus_string_init (&path))
01033 {
01034 _DBUS_SET_OOM (error);
01035 return FALSE;
01036 }
01037
01038 if (!_dbus_string_init (&cmdline))
01039 {
01040 _DBUS_SET_OOM (error);
01041 _dbus_string_free (&path);
01042 return FALSE;
01043 }
01044
01045 if (!_dbus_string_append_printf (&path, "/proc/%ld/cmdline", pid))
01046 goto oom;
01047
01048 fd = open (_dbus_string_get_const_data (&path), O_RDONLY);
01049 if (fd < 0)
01050 {
01051 dbus_set_error (error,
01052 _dbus_error_from_errno (errno),
01053 "Failed to open \"%s\": %s",
01054 _dbus_string_get_const_data (&path),
01055 _dbus_strerror (errno));
01056 goto fail;
01057 }
01058
01059 if (!_dbus_read (fd, &cmdline, max_len))
01060 {
01061 dbus_set_error (error,
01062 _dbus_error_from_errno (errno),
01063 "Failed to read from \"%s\": %s",
01064 _dbus_string_get_const_data (&path),
01065 _dbus_strerror (errno));
01066 goto fail;
01067 }
01068
01069 if (!_dbus_close (fd, error))
01070 goto fail;
01071
01072 string_squash_nonprintable (&cmdline);
01073
01074 if (!_dbus_string_copy (&cmdline, 0, str, _dbus_string_get_length (str)))
01075 goto oom;
01076
01077 _dbus_string_free (&cmdline);
01078 _dbus_string_free (&path);
01079 return TRUE;
01080 oom:
01081 _DBUS_SET_OOM (error);
01082 fail:
01083 _dbus_string_free (&cmdline);
01084 _dbus_string_free (&path);
01085 return FALSE;
01086 }