index.html
Main Page
|
modules.html
Modules
|
namespaces.html
Namespace List
|
hierarchy.html
Class Hierarchy
|
annotated.html
Data Structures
|
dirs.html
Directories
|
files.html
File List
|
namespacemembers.html
Namespace Members
|
functions.html
Data Fields
|
pages.html
Related Pages
dir_000004.html
dbus
dbus-sysdeps.c
00001
/* -*- mode: C; c-file-style: "gnu" -*- */
00002
/* dbus-sysdeps.c Wrappers around system/libc features (internal to D-BUS implementation)
00003
*
00004
* Copyright (C) 2002, 2003  Red Hat, Inc.
00005
* Copyright (C) 2003 CodeFactory AB
00006
*
00007
* Licensed under the Academic Free License version 2.1
00008
*
00009
* This program is free software; you can redistribute it and/or modify
00010
* it under the terms of the GNU General Public License as published by
00011
* the Free Software Foundation; either version 2 of the License, or
00012
* (at your option) any later version.
00013
*
00014
* This program is distributed in the hope that it will be useful,
00015
* but WITHOUT ANY WARRANTY; without even the implied warranty of
00016
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017
* GNU General Public License for more details.
00018
*
00019
* You should have received a copy of the GNU General Public License
00020
* along with this program; if not, write to the Free Software
00021
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022
*
00023
*/
00024
00025
#include "dbus-internals.h"
00026
#include "dbus-sysdeps.h"
00027
#include "dbus-threads.h"
00028
#include "dbus-protocol.h"
00029
#include "dbus-string.h"
00030
#include <sys/types.h>
00031
#include <stdlib.h>
00032
#include <string.h>
00033
#include <signal.h>
00034
#include <unistd.h>
00035
#include <stdio.h>
00036
#include <errno.h>
00037
#include <fcntl.h>
00038
#include <sys/socket.h>
00039
#include <dirent.h>
00040
#include <sys/un.h>
00041
#include <pwd.h>
00042
#include <time.h>
00043
#include <locale.h>
00044
#include <sys/time.h>
00045
#include <sys/stat.h>
00046
#include <sys/wait.h>
00047
#include <netinet/in.h>
00048
#include <netdb.h>
00049
#include <grp.h>
00050
00051
#ifdef HAVE_WRITEV
00052
#include <sys/uio.h>
00053
#endif
00054
#ifdef HAVE_POLL
00055
#include <sys/poll.h>
00056
#endif
00057
#ifdef HAVE_BACKTRACE
00058
#include <execinfo.h>
00059
#endif
00060
00061
00062
#ifndef O_BINARY
00063
#define O_BINARY 0
00064
#endif
00065
00066
#ifndef HAVE_SOCKLEN_T
00067
#define socklen_t int
00068
#endif
00069
00074
#ifndef DBUS_DISABLE_ASSERT
00075
00078
void
00079 _dbus_abort (
void
)
00080 {
00081
#ifdef DBUS_ENABLE_VERBOSE_MODE
00082
const
char
*s;
00083   s =
group__DBusInternalsUtils.html#ga57
_dbus_getenv
(
"DBUS_PRINT_BACKTRACE"
);
00084
if
(s && *s)
00085     _dbus_print_backtrace ();
00086
#endif
00087
abort ();
00088   _exit (1);
/* in case someone manages to ignore SIGABRT */
00089 }
00090
#endif
00091
00103
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusInternalsUtils.html#ga56
00104
group__DBusInternalsUtils.html#ga56
_dbus_setenv
(
const
char
*varname,
00105
const
char
*value)
00106 {
00107
group__DBusInternalsUtils.html#ga130
_dbus_assert
(varname !=
group__DBusMacros.html#ga4
NULL
);
00108
00109
if
(value ==
group__DBusMacros.html#ga4
NULL
)
00110     {
00111
#ifdef HAVE_UNSETENV
00112
unsetenv (varname);
00113
return
group__DBusMacros.html#ga2
TRUE
;
00114
#else
00115
char
*putenv_value;
00116       size_t len;
00117
00118       len = strlen (varname);
00119
00120
/* Use system malloc to avoid memleaks that dbus_malloc
00121
* will get upset about.
00122
*/
00123
00124       putenv_value = malloc (len + 1);
00125
if
(putenv_value ==
group__DBusMacros.html#ga4
NULL
)
00126
return
group__DBusMacros.html#ga3
FALSE
;
00127
00128       strcpy (putenv_value, varname);
00129
00130
return
(putenv (putenv_value) == 0);
00131
#endif
00132
}
00133
else
00134     {
00135
#ifdef HAVE_SETENV
00136
return
(setenv (varname, value,
group__DBusMacros.html#ga2
TRUE
) == 0);
00137
#else
00138
char
*putenv_value;
00139       size_t len;
00140       size_t varname_len;
00141       size_t value_len;
00142
00143       varname_len = strlen (varname);
00144       value_len = strlen (value);
00145
00146       len = varname_len + value_len + 1
/* '=' */
;
00147
00148
/* Use system malloc to avoid memleaks that dbus_malloc
00149
* will get upset about.
00150
*/
00151
00152       putenv_value = malloc (len + 1);
00153
if
(putenv_value ==
group__DBusMacros.html#ga4
NULL
)
00154
return
group__DBusMacros.html#ga3
FALSE
;
00155
00156       strcpy (putenv_value, varname);
00157       strcpy (putenv_value + varname_len,
"="
);
00158       strcpy (putenv_value + varname_len + 1, value);
00159
00160
return
(putenv (putenv_value) == 0);
00161
#endif
00162
}
00163 }
00164
00171
const
char
*
group__DBusInternalsUtils.html#ga57
00172
group__DBusInternalsUtils.html#ga57
_dbus_getenv
(
const
char
*varname)
00173 {
00174
return
getenv (varname);
00175 }
00176
00190
int
group__DBusInternalsUtils.html#ga58
00191
group__DBusInternalsUtils.html#ga58
_dbus_read
(
int
fd,
00192
structDBusString.html
DBusString
*buffer,
00193
int
count)
00194 {
00195
int
bytes_read;
00196
int
start;
00197
char
*data;
00198
00199
group__DBusInternalsUtils.html#ga130
_dbus_assert
(count >= 0);
00200
00201   start = _dbus_string_get_length (buffer);
00202
00203
if
(!
group__DBusString.html#ga19
_dbus_string_lengthen
(buffer, count))
00204     {
00205       errno = ENOMEM;
00206
return
-1;
00207     }
00208
00209   data =
group__DBusString.html#ga13
_dbus_string_get_data_len
(buffer, start, count);
00210
00211  again:
00212
00213   bytes_read = read (fd, data, count);
00214
00215
if
(bytes_read < 0)
00216     {
00217
if
(errno == EINTR)
00218
goto
again;
00219
else
00220         {
00221
/* put length back (note that this doesn't actually realloc anything) */
00222
group__DBusString.html#ga21
_dbus_string_set_length
(buffer, start);
00223
return
-1;
00224         }
00225     }
00226
else
00227     {
00228
/* put length back (doesn't actually realloc) */
00229
group__DBusString.html#ga21
_dbus_string_set_length
(buffer, start + bytes_read);
00230
00231
#if 0
00232
if
(bytes_read > 0)
00233
group__DBusMarshal.html#ga44
_dbus_verbose_bytes_of_string
(buffer, start, bytes_read);
00234
#endif
00235
00236
return
bytes_read;
00237     }
00238 }
00239
00250
int
group__DBusInternalsUtils.html#ga59
00251
group__DBusInternalsUtils.html#ga59
_dbus_write
(
int
fd,
00252
const
structDBusString.html
DBusString
*buffer,
00253
int
start,
00254
int
len)
00255 {
00256
const
char
*data;
00257
int
bytes_written;
00258
00259   data = _dbus_string_get_const_data_len (buffer, start, len);
00260
00261  again:
00262
00263   bytes_written = write (fd, data, len);
00264
00265
if
(bytes_written < 0 && errno == EINTR)
00266
goto
again;
00267
00268
#if 0
00269
if
(bytes_written > 0)
00270
group__DBusMarshal.html#ga44
_dbus_verbose_bytes_of_string
(buffer, start, bytes_written);
00271
#endif
00272
00273
return
bytes_written;
00274 }
00275
00296
int
group__DBusInternalsUtils.html#ga60
00297
group__DBusInternalsUtils.html#ga60
_dbus_write_two
(
int
fd,
00298
const
structDBusString.html
DBusString
*buffer1,
00299
int
start1,
00300
int
len1,
00301
const
structDBusString.html
DBusString
*buffer2,
00302
int
start2,
00303
int
len2)
00304 {
00305
group__DBusInternalsUtils.html#ga130
_dbus_assert
(buffer1 !=
group__DBusMacros.html#ga4
NULL
);
00306
group__DBusInternalsUtils.html#ga130
_dbus_assert
(start1 >= 0);
00307
group__DBusInternalsUtils.html#ga130
_dbus_assert
(start2 >= 0);
00308
group__DBusInternalsUtils.html#ga130
_dbus_assert
(len1 >= 0);
00309
group__DBusInternalsUtils.html#ga130
_dbus_assert
(len2 >= 0);
00310
00311
#ifdef HAVE_WRITEV
00312
{
00313
struct
iovec vectors[2];
00314
const
char
*data1;
00315
const
char
*data2;
00316
int
bytes_written;
00317
00318     data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00319
00320
if
(buffer2 !=
group__DBusMacros.html#ga4
NULL
)
00321       data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00322
else
00323       {
00324         data2 =
group__DBusMacros.html#ga4
NULL
;
00325         start2 = 0;
00326         len2 = 0;
00327       }
00328
00329     vectors[0].iov_base = (
char
*) data1;
00330     vectors[0].iov_len = len1;
00331     vectors[1].iov_base = (
char
*) data2;
00332     vectors[1].iov_len = len2;
00333
00334   again:
00335
00336     bytes_written = writev (fd,
00337                             vectors,
00338                             data2 ? 2 : 1);
00339
00340
if
(bytes_written < 0 && errno == EINTR)
00341
goto
again;
00342
00343
return
bytes_written;
00344   }
00345
#else
/* HAVE_WRITEV */
00346   {
00347
int
ret1;
00348
00349     ret1 =
group__DBusInternalsUtils.html#ga59
_dbus_write
(fd, buffer1, start1, len1);
00350
if
(ret1 == len1 && buffer2 !=
group__DBusMacros.html#ga4
NULL
)
00351       {
00352         ret2 =
group__DBusInternalsUtils.html#ga59
_dbus_write
(fd, buffer2, start2, len2);
00353
if
(ret2 < 0)
00354           ret2 = 0;
/* we can't report an error as the first write was OK */
00355
00356
return
ret1 + ret2;
00357       }
00358
else
00359
return
ret1;
00360   }
00361
#endif
/* !HAVE_WRITEV */
00362 }
00363
00364
#define _DBUS_MAX_SUN_PATH_LENGTH 99
00365
00393
int
group__DBusInternalsUtils.html#ga61
00394
group__DBusInternalsUtils.html#ga61
_dbus_connect_unix_socket
(
const
char
*path,
00395
group__DBusTypes.html#ga2
dbus_bool_t
abstract
,
00396
structDBusError.html
DBusError
*error)
00397 {
00398
int
fd;
00399
struct
sockaddr_un addr;
00400
00401   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00402
00403   _dbus_verbose (
"connecting to unix socket %s abstract=%d\n"
,
00404                  path,
abstract
);
00405
00406   fd = socket (PF_UNIX, SOCK_STREAM, 0);
00407
00408
if
(fd < 0)
00409     {
00410
group__DBusErrors.html#ga6
dbus_set_error
(error,
00411
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
00412
"Failed to create socket: %s"
,
00413
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
00414
00415
return
-1;
00416     }
00417
00418
group__DBusInternalsUtils.html#ga135
_DBUS_ZERO
(addr);
00419   addr.sun_family = AF_UNIX;
00420
00421
if
(
abstract
)
00422     {
00423
#ifdef HAVE_ABSTRACT_SOCKETS
00424
/* remember that abstract names aren't nul-terminated so we rely
00425
* on sun_path being filled in with zeroes above.
00426
*/
00427       addr.sun_path[0] =
'\0'
;
/* this is what says "use abstract" */
00428       strncpy (&addr.sun_path[1], path,
group__DBusInternalsUtils.html#ga153
_DBUS_MAX_SUN_PATH_LENGTH
- 2);
00429
/* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
00430
#else
/* HAVE_ABSTRACT_SOCKETS */
00431
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NOT_SUPPORTED,
00432
"Operating system does not support abstract socket namespace\n"
);
00433       close (fd);
00434
return
-1;
00435
#endif
/* ! HAVE_ABSTRACT_SOCKETS */
00436     }
00437
else
00438     {
00439       strncpy (addr.sun_path, path,
group__DBusInternalsUtils.html#ga153
_DBUS_MAX_SUN_PATH_LENGTH
- 1);
00440     }
00441
00442
if
(connect (fd, (
struct
sockaddr*) &addr,
sizeof
(addr)) < 0)
00443     {
00444
group__DBusErrors.html#ga6
dbus_set_error
(error,
00445
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
00446
"Failed to connect to socket %s: %s"
,
00447                       path,
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
00448
00449       close (fd);
00450       fd = -1;
00451
00452
return
-1;
00453     }
00454
00455
if
(!
group__DBusInternalsUtils.html#ga102
_dbus_set_fd_nonblocking
(fd, error))
00456     {
00457       _DBUS_ASSERT_ERROR_IS_SET (error);
00458
00459       close (fd);
00460       fd = -1;
00461
00462
return
-1;
00463     }
00464
00465
return
fd;
00466 }
00467
00483
int
group__DBusInternalsUtils.html#ga62
00484
group__DBusInternalsUtils.html#ga62
_dbus_listen_unix_socket
(
const
char
*path,
00485
group__DBusTypes.html#ga2
dbus_bool_t
abstract
,
00486
structDBusError.html
DBusError
*error)
00487 {
00488
int
listen_fd;
00489
struct
sockaddr_un addr;
00490
00491   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00492
00493   _dbus_verbose (
"listening on unix socket %s abstract=%d\n"
,
00494                  path,
abstract
);
00495
00496   listen_fd = socket (PF_UNIX, SOCK_STREAM, 0);
00497
00498
if
(listen_fd < 0)
00499     {
00500
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
00501
"Failed to create socket \"%s\": %s"
,
00502                       path,
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
00503
return
-1;
00504     }
00505
00506
group__DBusInternalsUtils.html#ga135
_DBUS_ZERO
(addr);
00507   addr.sun_family = AF_UNIX;
00508
00509
if
(
abstract
)
00510     {
00511
#ifdef HAVE_ABSTRACT_SOCKETS
00512
/* remember that abstract names aren't nul-terminated so we rely
00513
* on sun_path being filled in with zeroes above.
00514
*/
00515       addr.sun_path[0] =
'\0'
;
/* this is what says "use abstract" */
00516       strncpy (&addr.sun_path[1], path,
group__DBusInternalsUtils.html#ga153
_DBUS_MAX_SUN_PATH_LENGTH
- 2);
00517
/* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
00518
#else
/* HAVE_ABSTRACT_SOCKETS */
00519
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NOT_SUPPORTED,
00520
"Operating system does not support abstract socket namespace\n"
);
00521       close (listen_fd);
00522
return
-1;
00523
#endif
/* ! HAVE_ABSTRACT_SOCKETS */
00524     }
00525
else
00526     {
00527
/* FIXME discussed security implications of this with Nalin,
00528
* and we couldn't think of where it would kick our ass, but
00529
* it still seems a bit sucky. It also has non-security suckage;
00530
* really we'd prefer to exit if the socket is already in use.
00531
* But there doesn't seem to be a good way to do this.
00532
*
00533
* Just to be extra careful, I threw in the stat() - clearly
00534
* the stat() can't *fix* any security issue, but it at least
00535
* avoids inadvertent/accidental data loss.
00536
*/
00537       {
00538
struct
stat sb;
00539
00540
if
(stat (path, &sb) == 0 &&
00541             S_ISSOCK (sb.st_mode))
00542           unlink (path);
00543       }
00544
00545       strncpy (addr.sun_path, path,
group__DBusInternalsUtils.html#ga153
_DBUS_MAX_SUN_PATH_LENGTH
- 1);
00546     }
00547
00548
if
(bind (listen_fd, (
struct
sockaddr*) &addr,
sizeof
(addr)) < 0)
00549     {
00550
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
00551
"Failed to bind socket \"%s\": %s"
,
00552                       path,
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
00553       close (listen_fd);
00554
return
-1;
00555     }
00556
00557
if
(listen (listen_fd, 30
/* backlog */
) < 0)
00558     {
00559
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
00560
"Failed to listen on socket \"%s\": %s"
,
00561                       path,
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
00562       close (listen_fd);
00563
return
-1;
00564     }
00565
00566
if
(!
group__DBusInternalsUtils.html#ga102
_dbus_set_fd_nonblocking
(listen_fd, error))
00567     {
00568       _DBUS_ASSERT_ERROR_IS_SET (error);
00569       close (listen_fd);
00570
return
-1;
00571     }
00572
00573
/* Try opening up the permissions, but if we can't, just go ahead
00574
* and continue, maybe it will be good enough.
00575
*/
00576
if
(!
abstract
&& chmod (path, 0777) < 0)
00577
group__DBusInternalsUtils.html#ga7
_dbus_warn
(
"Could not set mode 0777 on socket %s\n"
,
00578                 path);
00579
00580
return
listen_fd;
00581 }
00582
00593
int
group__DBusInternalsUtils.html#ga63
00594
group__DBusInternalsUtils.html#ga63
_dbus_connect_tcp_socket
(
const
char
*host,
00595
group__DBusTypes.html#ga3
dbus_uint32_t
port,
00596
structDBusError.html
DBusError
*error)
00597 {
00598
int
fd;
00599
struct
sockaddr_in addr;
00600
struct
hostent *he;
00601
struct
in_addr *haddr;
00602
00603   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00604
00605   fd = socket (AF_INET, SOCK_STREAM, 0);
00606
00607
if
(fd < 0)
00608     {
00609
group__DBusErrors.html#ga6
dbus_set_error
(error,
00610
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
00611
"Failed to create socket: %s"
,
00612
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
00613
00614
return
-1;
00615     }
00616
00617
if
(host ==
group__DBusMacros.html#ga4
NULL
)
00618     host =
"localhost"
;
00619
00620   he = gethostbyname (host);
00621
if
(he ==
group__DBusMacros.html#ga4
NULL
)
00622     {
00623
group__DBusErrors.html#ga6
dbus_set_error
(error,
00624
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
00625
"Failed to lookup hostname: %s"
,
00626                       host);
00627       close (fd);
00628
return
-1;
00629     }
00630
00631   haddr = ((
struct
in_addr *) (he->h_addr_list)[0]);
00632
00633
group__DBusInternalsUtils.html#ga135
_DBUS_ZERO
(addr);
00634   memcpy (&addr.sin_addr, haddr,
sizeof
(
struct
in_addr));
00635   addr.sin_family = AF_INET;
00636   addr.sin_port = htons (port);
00637
00638
if
(connect (fd, (
struct
sockaddr*) &addr,
sizeof
(addr)) < 0)
00639     {
00640
group__DBusErrors.html#ga6
dbus_set_error
(error,
00641
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
00642
"Failed to connect to socket %s: %s:%d"
,
00643                       host,
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno), port);
00644
00645       close (fd);
00646       fd = -1;
00647
00648
return
-1;
00649     }
00650
00651
if
(!
group__DBusInternalsUtils.html#ga102
_dbus_set_fd_nonblocking
(fd, error))
00652     {
00653       close (fd);
00654       fd = -1;
00655
00656
return
-1;
00657     }
00658
00659
return
fd;
00660 }
00661
00672
int
group__DBusInternalsUtils.html#ga64
00673
group__DBusInternalsUtils.html#ga64
_dbus_listen_tcp_socket
(
const
char
*host,
00674
group__DBusTypes.html#ga3
dbus_uint32_t
port,
00675
structDBusError.html
DBusError
*error)
00676 {
00677
int
listen_fd;
00678
struct
sockaddr_in addr;
00679
struct
hostent *he;
00680
struct
in_addr *haddr;
00681
00682   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00683
00684   listen_fd = socket (AF_INET, SOCK_STREAM, 0);
00685
00686
if
(listen_fd < 0)
00687     {
00688
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
00689
"Failed to create socket \"%s:%d\": %s"
,
00690                       host, port,
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
00691
return
-1;
00692     }
00693
00694   he = gethostbyname (host);
00695
if
(he ==
group__DBusMacros.html#ga4
NULL
)
00696     {
00697
group__DBusErrors.html#ga6
dbus_set_error
(error,
00698
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
00699
"Failed to lookup hostname: %s"
,
00700                       host);
00701       close (listen_fd);
00702
return
-1;
00703     }
00704
00705   haddr = ((
struct
in_addr *) (he->h_addr_list)[0]);
00706
00707
group__DBusInternalsUtils.html#ga135
_DBUS_ZERO
(addr);
00708   memcpy (&addr.sin_addr, haddr, sizeof (
struct
in_addr));
00709   addr.sin_family = AF_INET;
00710   addr.sin_port = htons (port);
00711
00712
if
(bind (listen_fd, (
struct
sockaddr*) &addr,
sizeof
(
struct
sockaddr)))
00713     {
00714
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
00715
"Failed to bind socket \"%s:%d\": %s"
,
00716                       host, port,
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
00717       close (listen_fd);
00718
return
-1;
00719     }
00720
00721
if
(listen (listen_fd, 30
/* backlog */
) < 0)
00722     {
00723
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
00724
"Failed to listen on socket \"%s:%d\": %s"
,
00725                       host, port,
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
00726       close (listen_fd);
00727
return
-1;
00728     }
00729
00730
if
(!
group__DBusInternalsUtils.html#ga102
_dbus_set_fd_nonblocking
(listen_fd, error))
00731     {
00732       close (listen_fd);
00733
return
-1;
00734     }
00735
00736
return
listen_fd;
00737 }
00738
00739
static
group__DBusTypes.html#ga2
dbus_bool_t
00740 write_credentials_byte (
int
server_fd,
00741
structDBusError.html
DBusError
*error)
00742 {
00743
int
bytes_written;
00744
char
buf[1] = {
'\0'
};
00745
#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
00746
struct
{
00747
struct
cmsghdr hdr;
00748
struct
cmsgcred cred;
00749   } cmsg;
00750
struct
iovec iov;
00751
struct
msghdr msg;
00752
#endif
00753
00754
#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
00755
iov.iov_base = buf;
00756   iov.iov_len = 1;
00757
00758   memset (&msg, 0,
sizeof
(msg));
00759   msg.msg_iov = &iov;
00760   msg.msg_iovlen = 1;
00761
00762   msg.msg_control = &cmsg;
00763   msg.msg_controllen =
sizeof
(cmsg);
00764   memset (&cmsg, 0,
sizeof
(cmsg));
00765   cmsg.hdr.cmsg_len =
sizeof
(cmsg);
00766   cmsg.hdr.cmsg_level = SOL_SOCKET;
00767   cmsg.hdr.cmsg_type = SCM_CREDS;
00768
#endif
00769
00770   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00771
00772  again:
00773
00774
#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
00775
bytes_written = sendmsg (server_fd, &msg, 0);
00776
#else
00777
bytes_written = write (server_fd, buf, 1);
00778
#endif
00779
00780
if
(bytes_written < 0 && errno == EINTR)
00781
goto
again;
00782
00783
if
(bytes_written < 0)
00784     {
00785
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
00786
"Failed to write credentials byte: %s"
,
00787
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
00788
return
group__DBusMacros.html#ga3
FALSE
;
00789     }
00790
else
if
(bytes_written == 0)
00791     {
00792
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_IO_ERROR,
00793
"wrote zero bytes writing credentials byte"
);
00794
return
group__DBusMacros.html#ga3
FALSE
;
00795     }
00796
else
00797     {
00798
group__DBusInternalsUtils.html#ga130
_dbus_assert
(bytes_written == 1);
00799       _dbus_verbose (
"wrote credentials byte\n"
);
00800
return
group__DBusMacros.html#ga2
TRUE
;
00801     }
00802 }
00803
00822
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusInternalsUtils.html#ga66
00823
group__DBusInternalsUtils.html#ga66
_dbus_read_credentials_unix_socket
(
int
client_fd,
00824
structDBusCredentials.html
DBusCredentials
*credentials,
00825
structDBusError.html
DBusError
*error)
00826 {
00827
struct
msghdr msg;
00828
struct
iovec iov;
00829
char
buf;
00830
00831
#ifdef HAVE_CMSGCRED
00832
struct
{
00833
struct
cmsghdr hdr;
00834
struct
cmsgcred cred;
00835   } cmsg;
00836
#endif
00837
00838   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00839
00840
/* The POSIX spec certainly doesn't promise this, but
00841
* we need these assertions to fail as soon as we're wrong about
00842
* it so we can do the porting fixups
00843
*/
00844
group__DBusInternalsUtils.html#ga130
_dbus_assert
(
sizeof
(pid_t) <=
sizeof
(credentials->
structDBusCredentials.html#o0
pid
));
00845
group__DBusInternalsUtils.html#ga130
_dbus_assert
(
sizeof
(uid_t) <=
sizeof
(credentials->
structDBusCredentials.html#o1
uid
));
00846
group__DBusInternalsUtils.html#ga130
_dbus_assert
(
sizeof
(gid_t) <=
sizeof
(credentials->
structDBusCredentials.html#o2
gid
));
00847
00848
group__DBusInternalsUtils.html#ga74
_dbus_credentials_clear
(credentials);
00849
00850
#if defined(LOCAL_CREDS) && defined(HAVE_CMSGCRED)
00851
/* Set the socket to receive credentials on the next message */
00852   {
00853
int
on = 1;
00854
if
(setsockopt (client_fd, 0, LOCAL_CREDS, &on,
sizeof
(on)) < 0)
00855       {
00856         _dbus_verbose (
"Unable to set LOCAL_CREDS socket option\n"
);
00857
return
group__DBusMacros.html#ga3
FALSE
;
00858       }
00859   }
00860
#endif
00861
00862   iov.iov_base = &buf;
00863   iov.iov_len = 1;
00864
00865   memset (&msg, 0,
sizeof
(msg));
00866   msg.msg_iov = &iov;
00867   msg.msg_iovlen = 1;
00868
00869
#ifdef HAVE_CMSGCRED
00870
memset (&cmsg, 0,
sizeof
(cmsg));
00871   msg.msg_control = &cmsg;
00872   msg.msg_controllen =
sizeof
(cmsg);
00873
#endif
00874
00875  again:
00876
if
(recvmsg (client_fd, &msg, 0) < 0)
00877     {
00878
if
(errno == EINTR)
00879
goto
again;
00880
00881
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
00882
"Failed to read credentials byte: %s"
,
00883
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
00884
return
group__DBusMacros.html#ga3
FALSE
;
00885     }
00886
00887
if
(buf !=
'\0'
)
00888     {
00889
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_FAILED,
00890
"Credentials byte was not nul"
);
00891
return
group__DBusMacros.html#ga3
FALSE
;
00892     }
00893
00894
#ifdef HAVE_CMSGCRED
00895
if
(cmsg->hdr.cmsg_len < sizeof (cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS)
00896     {
00897
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_FAILED,
00898
"Message from recvmsg() was not SCM_CREDS"
);
00899
return
group__DBusMacros.html#ga3
FALSE
;
00900     }
00901
#endif
00902
00903   _dbus_verbose (
"read credentials byte\n"
);
00904
00905   {
00906
#ifdef SO_PEERCRED
00907
struct
ucred cr;
00908
int
cr_len =
sizeof
(cr);
00909
00910
if
(getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
00911         cr_len ==
sizeof
(cr))
00912       {
00913         credentials->
structDBusCredentials.html#o0
pid
= cr.pid;
00914         credentials->
structDBusCredentials.html#o1
uid
= cr.uid;
00915         credentials->
structDBusCredentials.html#o2
gid
= cr.gid;
00916       }
00917
else
00918       {
00919         _dbus_verbose (
"Failed to getsockopt() credentials, returned len %d/%d: %s\n"
,
00920                        cr_len, (
int
)
sizeof
(cr),
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
00921       }
00922
#elif defined(HAVE_CMSGCRED)
00923
credentials->
structDBusCredentials.html#o0
pid
= cmsg.cred.cmcred_pid;
00924     credentials->
structDBusCredentials.html#o1
uid
= cmsg.cred.cmcred_euid;
00925     credentials->
structDBusCredentials.html#o2
gid
= cmsg.cred.cmcred_groups[0];
00926
#else
/* !SO_PEERCRED && !HAVE_CMSGCRED */
00927     _dbus_verbose (
"Socket credentials not supported on this OS\n"
);
00928
#endif
00929
}
00930
00931   _dbus_verbose (
"Credentials:"
00932
"  pid "
DBUS_PID_FORMAT
00933
"  uid "
DBUS_UID_FORMAT
00934
"  gid "
DBUS_GID_FORMAT
"\n"
,
00935                  credentials->
structDBusCredentials.html#o0
pid
,
00936                  credentials->
structDBusCredentials.html#o1
uid
,
00937                  credentials->
structDBusCredentials.html#o2
gid
);
00938
00939
return
group__DBusMacros.html#ga2
TRUE
;
00940 }
00941
00959
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusInternalsUtils.html#ga67
00960
group__DBusInternalsUtils.html#ga67
_dbus_send_credentials_unix_socket
(
int
server_fd,
00961
structDBusError.html
DBusError
*error)
00962 {
00963   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00964
00965
if
(write_credentials_byte (server_fd, error))
00966
return
group__DBusMacros.html#ga2
TRUE
;
00967
else
00968
return
group__DBusMacros.html#ga3
FALSE
;
00969 }
00970
00978
int
group__DBusInternalsUtils.html#ga68
00979
group__DBusInternalsUtils.html#ga68
_dbus_accept
(
int
listen_fd)
00980 {
00981
int
client_fd;
00982
struct
sockaddr addr;
00983   socklen_t addrlen;
00984
00985   addrlen =
sizeof
(addr);
00986
00987  retry:
00988   client_fd = accept (listen_fd, &addr, &addrlen);
00989
00990
if
(client_fd < 0)
00991     {
00992
if
(errno == EINTR)
00993
goto
retry;
00994     }
00995
00996
return
client_fd;
00997 }
00998
01013
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusString.html#ga60
01014
group__DBusString.html#ga60
_dbus_string_append_int
(
structDBusString.html
DBusString
*str,
01015
long
value)
01016 {
01017
/* this calculation is from comp.lang.c faq */
01018
#define MAX_LONG_LEN ((sizeof (long) * 8 + 2) / 3 + 1)
/* +1 for '-' */
01019
int
orig_len;
01020
int
i;
01021
char
*buf;
01022
01023   orig_len = _dbus_string_get_length (str);
01024
01025
if
(!
group__DBusString.html#ga19
_dbus_string_lengthen
(str, MAX_LONG_LEN))
01026
return
group__DBusMacros.html#ga3
FALSE
;
01027
01028   buf =
group__DBusString.html#ga13
_dbus_string_get_data_len
(str, orig_len, MAX_LONG_LEN);
01029
01030   snprintf (buf, MAX_LONG_LEN,
"%ld"
, value);
01031
01032   i = 0;
01033
while
(*buf)
01034     {
01035       ++buf;
01036       ++i;
01037     }
01038
01039
group__DBusString.html#ga20
_dbus_string_shorten
(str, MAX_LONG_LEN - i);
01040
01041
return
group__DBusMacros.html#ga2
TRUE
;
01042 }
01043
01051
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusString.html#ga61
01052
group__DBusString.html#ga61
_dbus_string_append_uint
(
structDBusString.html
DBusString
*str,
01053
unsigned
long
value)
01054 {
01055
/* this is wrong, but definitely on the high side. */
01056
#define MAX_ULONG_LEN (MAX_LONG_LEN * 2)
01057
int
orig_len;
01058
int
i;
01059
char
*buf;
01060
01061   orig_len = _dbus_string_get_length (str);
01062
01063
if
(!
group__DBusString.html#ga19
_dbus_string_lengthen
(str, MAX_ULONG_LEN))
01064
return
group__DBusMacros.html#ga3
FALSE
;
01065
01066   buf =
group__DBusString.html#ga13
_dbus_string_get_data_len
(str, orig_len, MAX_ULONG_LEN);
01067
01068   snprintf (buf, MAX_ULONG_LEN,
"%lu"
, value);
01069
01070   i = 0;
01071
while
(*buf)
01072     {
01073       ++buf;
01074       ++i;
01075     }
01076
01077
group__DBusString.html#ga20
_dbus_string_shorten
(str, MAX_ULONG_LEN - i);
01078
01079
return
group__DBusMacros.html#ga2
TRUE
;
01080 }
01081
01082
#ifdef DBUS_BUILD_TESTS
01083
01090
group__DBusTypes.html#ga2
dbus_bool_t
01091 _dbus_string_append_double (
structDBusString.html
DBusString
*str,
01092
double
value)
01093 {
01094
#define MAX_DOUBLE_LEN 64
/* this is completely made up :-/ */
01095
int
orig_len;
01096
char
*buf;
01097
int
i;
01098
01099   orig_len = _dbus_string_get_length (str);
01100
01101
if
(!
group__DBusString.html#ga19
_dbus_string_lengthen
(str, MAX_DOUBLE_LEN))
01102
return
group__DBusMacros.html#ga3
FALSE
;
01103
01104   buf =
group__DBusString.html#ga13
_dbus_string_get_data_len
(str, orig_len, MAX_DOUBLE_LEN);
01105
01106   snprintf (buf, MAX_LONG_LEN,
"%g"
, value);
01107
01108   i = 0;
01109
while
(*buf)
01110     {
01111       ++buf;
01112       ++i;
01113     }
01114
01115
group__DBusString.html#ga20
_dbus_string_shorten
(str, MAX_DOUBLE_LEN - i);
01116
01117
return
group__DBusMacros.html#ga2
TRUE
;
01118 }
01119
#endif
/* DBUS_BUILD_TESTS */
01120
01133
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusString.html#ga62
01134
group__DBusString.html#ga62
_dbus_string_parse_int
(
const
structDBusString.html
DBusString
*str,
01135
int
start,
01136
long
*value_return,
01137
int
*end_return)
01138 {
01139
long
v;
01140
const
char
*p;
01141
char
*end;
01142
01143   p = _dbus_string_get_const_data_len (str, start,
01144                                        _dbus_string_get_length (str) - start);
01145
01146   end =
group__DBusMacros.html#ga4
NULL
;
01147   errno = 0;
01148   v = strtol (p, &end, 0);
01149
if
(end ==
group__DBusMacros.html#ga4
NULL
|| end == p || errno != 0)
01150
return
group__DBusMacros.html#ga3
FALSE
;
01151
01152
if
(value_return)
01153     *value_return = v;
01154
if
(end_return)
01155     *end_return = start + (end - p);
01156
01157
return
group__DBusMacros.html#ga2
TRUE
;
01158 }
01159
01167
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusString.html#ga63
01168
group__DBusString.html#ga63
_dbus_check_dir_is_private_to_user
(
structDBusString.html
DBusString
*dir,
structDBusError.html
DBusError
*error)
01169 {
01170
const
char
*directory;
01171
struct
stat sb;
01172
01173   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01174
01175   directory = _dbus_string_get_const_data (dir);
01176
01177
if
(stat (directory, &sb) < 0)
01178     {
01179
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
01180
"%s"
,
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
01181
01182
return
group__DBusMacros.html#ga3
FALSE
;
01183     }
01184
01185
if
((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
01186       (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
01187     {
01188
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_FAILED,
01189
"%s directory is not private to the user"
, directory);
01190
return
group__DBusMacros.html#ga3
FALSE
;
01191     }
01192
01193
return
group__DBusMacros.html#ga2
TRUE
;
01194 }
01195
01196
#ifdef DBUS_BUILD_TESTS
01197
/* Not currently used, so only built when tests are enabled */
01210
group__DBusTypes.html#ga2
dbus_bool_t
01211 _dbus_string_parse_uint (
const
structDBusString.html
DBusString
*str,
01212
int
start,
01213
unsigned
long
*value_return,
01214
int
*end_return)
01215 {
01216
unsigned
long
v;
01217
const
char
*p;
01218
char
*end;
01219
01220   p = _dbus_string_get_const_data_len (str, start,
01221                                        _dbus_string_get_length (str) - start);
01222
01223   end =
group__DBusMacros.html#ga4
NULL
;
01224   errno = 0;
01225   v = strtoul (p, &end, 0);
01226
if
(end ==
group__DBusMacros.html#ga4
NULL
|| end == p || errno != 0)
01227
return
group__DBusMacros.html#ga3
FALSE
;
01228
01229
if
(value_return)
01230     *value_return = v;
01231
if
(end_return)
01232     *end_return = start + (end - p);
01233
01234
return
group__DBusMacros.html#ga2
TRUE
;
01235 }
01236
#endif
/* DBUS_BUILD_TESTS */
01237
01238
#ifdef DBUS_BUILD_TESTS
01239
static
group__DBusTypes.html#ga2
dbus_bool_t
01240 ascii_isspace (
char
c)
01241 {
01242
return
(c ==
' '
||
01243           c ==
'\f'
||
01244           c ==
'\n'
||
01245           c ==
'\r'
||
01246           c ==
'\t'
||
01247           c ==
'\v'
);
01248 }
01249
#endif
/* DBUS_BUILD_TESTS */
01250
01251
#ifdef DBUS_BUILD_TESTS
01252
static
group__DBusTypes.html#ga2
dbus_bool_t
01253 ascii_isdigit (
char
c)
01254 {
01255
return
c >=
'0'
&& c <=
'9'
;
01256 }
01257
#endif
/* DBUS_BUILD_TESTS */
01258
01259
#ifdef DBUS_BUILD_TESTS
01260
static
group__DBusTypes.html#ga2
dbus_bool_t
01261 ascii_isxdigit (
char
c)
01262 {
01263
return
(ascii_isdigit (c) ||
01264           (c >=
'a'
&& c <=
'f'
) ||
01265           (c >=
'A'
&& c <=
'F'
));
01266 }
01267
#endif
/* DBUS_BUILD_TESTS */
01268
01269
#ifdef DBUS_BUILD_TESTS
01270
/* Calls strtod in a locale-independent fashion, by looking at
01271
* the locale data and patching the decimal comma to a point.
01272
*
01273
* Relicensed from glib.
01274
*/
01275
static
double
01276 ascii_strtod (
const
char
*nptr,
01277
char
**endptr)
01278 {
01279
char
*fail_pos;
01280
double
val;
01281
struct
lconv *locale_data;
01282
const
char
*decimal_point;
01283
int
decimal_point_len;
01284
const
char
*p, *decimal_point_pos;
01285
const
char
*end =
group__DBusMacros.html#ga4
NULL
;
/* Silence gcc */
01286
01287   fail_pos =
group__DBusMacros.html#ga4
NULL
;
01288
01289   locale_data = localeconv ();
01290   decimal_point = locale_data->decimal_point;
01291   decimal_point_len = strlen (decimal_point);
01292
01293
group__DBusInternalsUtils.html#ga130
_dbus_assert
(decimal_point_len != 0);
01294
01295   decimal_point_pos =
group__DBusMacros.html#ga4
NULL
;
01296
if
(decimal_point[0] !=
'.'
||
01297       decimal_point[1] != 0)
01298     {
01299       p = nptr;
01300
/* Skip leading space */
01301
while
(ascii_isspace (*p))
01302         p++;
01303
01304
/* Skip leading optional sign */
01305
if
(*p ==
'+'
|| *p ==
'-'
)
01306         p++;
01307
01308
if
(p[0] ==
'0'
&&
01309           (p[1] ==
'x'
|| p[1] ==
'X'
))
01310         {
01311           p += 2;
01312
/* HEX - find the (optional) decimal point */
01313
01314
while
(ascii_isxdigit (*p))
01315             p++;
01316
01317
if
(*p ==
'.'
)
01318             {
01319               decimal_point_pos = p++;
01320
01321
while
(ascii_isxdigit (*p))
01322                 p++;
01323
01324
if
(*p ==
'p'
|| *p ==
'P'
)
01325                 p++;
01326
if
(*p ==
'+'
|| *p ==
'-'
)
01327                 p++;
01328
while
(ascii_isdigit (*p))
01329                 p++;
01330               end = p;
01331             }
01332         }
01333
else
01334         {
01335
while
(ascii_isdigit (*p))
01336             p++;
01337
01338
if
(*p ==
'.'
)
01339             {
01340               decimal_point_pos = p++;
01341
01342
while
(ascii_isdigit (*p))
01343                 p++;
01344
01345
if
(*p ==
'e'
|| *p ==
'E'
)
01346                 p++;
01347
if
(*p ==
'+'
|| *p ==
'-'
)
01348                 p++;
01349
while
(ascii_isdigit (*p))
01350                 p++;
01351               end = p;
01352             }
01353         }
01354
/* For the other cases, we need not convert the decimal point */
01355     }
01356
01357
/* Set errno to zero, so that we can distinguish zero results
01358
and underflows */
01359   errno = 0;
01360
01361
if
(decimal_point_pos)
01362     {
01363
char
*copy, *c;
01364
01365
/* We need to convert the '.' to the locale specific decimal point */
01366       copy =
group__DBusMemory.html#ga0
dbus_malloc
(end - nptr + 1 + decimal_point_len);
01367
01368       c = copy;
01369       memcpy (c, nptr, decimal_point_pos - nptr);
01370       c += decimal_point_pos - nptr;
01371       memcpy (c, decimal_point, decimal_point_len);
01372       c += decimal_point_len;
01373       memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1));
01374       c += end - (decimal_point_pos + 1);
01375       *c = 0;
01376
01377       val = strtod (copy, &fail_pos);
01378
01379
if
(fail_pos)
01380         {
01381
if
(fail_pos > decimal_point_pos)
01382             fail_pos = (
char
*)nptr + (fail_pos - copy) - (decimal_point_len - 1);
01383
else
01384             fail_pos = (
char
*)nptr + (fail_pos - copy);
01385         }
01386
01387
group__DBusMemory.html#ga3
dbus_free
(copy);
01388
01389     }
01390
else
01391     val = strtod (nptr, &fail_pos);
01392
01393
if
(endptr)
01394     *endptr = fail_pos;
01395
01396
return
val;
01397 }
01398
#endif
/* DBUS_BUILD_TESTS */
01399
01400
#ifdef DBUS_BUILD_TESTS
01401
01413
group__DBusTypes.html#ga2
dbus_bool_t
01414 _dbus_string_parse_double (
const
structDBusString.html
DBusString
*str,
01415
int
start,
01416
double
*value_return,
01417
int
*end_return)
01418 {
01419
double
v;
01420
const
char
*p;
01421
char
*end;
01422
01423   p = _dbus_string_get_const_data_len (str, start,
01424                                        _dbus_string_get_length (str) - start);
01425
01426   end =
group__DBusMacros.html#ga4
NULL
;
01427   errno = 0;
01428   v = ascii_strtod (p, &end);
01429
if
(end ==
group__DBusMacros.html#ga4
NULL
|| end == p || errno != 0)
01430
return
group__DBusMacros.html#ga3
FALSE
;
01431
01432
if
(value_return)
01433     *value_return = v;
01434
if
(end_return)
01435     *end_return = start + (end - p);
01436
01437
return
group__DBusMacros.html#ga2
TRUE
;
01438 }
01439
#endif
/* DBUS_BUILD_TESTS */
01440
/* DBusString group */
01442
01447
static
group__DBusTypes.html#ga2
dbus_bool_t
01448 fill_user_info_from_passwd (
struct
passwd *p,
01449
structDBusUserInfo.html
DBusUserInfo
*info,
01450
structDBusError.html
DBusError
*error)
01451 {
01452
group__DBusInternalsUtils.html#ga130
_dbus_assert
(p->pw_name !=
group__DBusMacros.html#ga4
NULL
);
01453
group__DBusInternalsUtils.html#ga130
_dbus_assert
(p->pw_dir !=
group__DBusMacros.html#ga4
NULL
);
01454
01455   info->
structDBusUserInfo.html#o0
uid
= p->pw_uid;
01456   info->
structDBusUserInfo.html#o1
primary_gid
= p->pw_gid;
01457   info->
structDBusUserInfo.html#o4
username
=
group__DBusInternalsUtils.html#ga8
_dbus_strdup
(p->pw_name);
01458   info->
structDBusUserInfo.html#o5
homedir
=
group__DBusInternalsUtils.html#ga8
_dbus_strdup
(p->pw_dir);
01459
01460
if
(info->
structDBusUserInfo.html#o4
username
==
group__DBusMacros.html#ga4
NULL
||
01461       info->
structDBusUserInfo.html#o5
homedir
==
group__DBusMacros.html#ga4
NULL
)
01462     {
01463
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
01464
return
group__DBusMacros.html#ga3
FALSE
;
01465     }
01466
01467
return
group__DBusMacros.html#ga2
TRUE
;
01468 }
01469
01470
static
group__DBusTypes.html#ga2
dbus_bool_t
01471 fill_user_info (
structDBusUserInfo.html
DBusUserInfo
*info,
01472                 dbus_uid_t          uid,
01473
const
structDBusString.html
DBusString
*username,
01474
structDBusError.html
DBusError
*error)
01475 {
01476
const
char
*username_c;
01477
01478
/* exactly one of username/uid provided */
01479
group__DBusInternalsUtils.html#ga130
_dbus_assert
(username !=
group__DBusMacros.html#ga4
NULL
|| uid != DBUS_UID_UNSET);
01480
group__DBusInternalsUtils.html#ga130
_dbus_assert
(username ==
group__DBusMacros.html#ga4
NULL
|| uid == DBUS_UID_UNSET);
01481
01482   info->
structDBusUserInfo.html#o0
uid
= DBUS_UID_UNSET;
01483   info->
structDBusUserInfo.html#o1
primary_gid
= DBUS_GID_UNSET;
01484   info->
structDBusUserInfo.html#o2
group_ids
=
group__DBusMacros.html#ga4
NULL
;
01485   info->
structDBusUserInfo.html#o3
n_group_ids
= 0;
01486   info->
structDBusUserInfo.html#o4
username
=
group__DBusMacros.html#ga4
NULL
;
01487   info->
structDBusUserInfo.html#o5
homedir
=
group__DBusMacros.html#ga4
NULL
;
01488
01489
if
(username !=
group__DBusMacros.html#ga4
NULL
)
01490     username_c = _dbus_string_get_const_data (username);
01491
else
01492     username_c =
group__DBusMacros.html#ga4
NULL
;
01493
01494
/* For now assuming that the getpwnam() and getpwuid() flavors
01495
* are always symmetrical, if not we have to add more configure
01496
* checks
01497
*/
01498
01499
#if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
01500
{
01501
struct
passwd *p;
01502
int
result;
01503
char
buf[1024];
01504
struct
passwd p_str;
01505
01506     p =
group__DBusMacros.html#ga4
NULL
;
01507
#ifdef HAVE_POSIX_GETPWNAM_R
01508
if
(uid != DBUS_UID_UNSET)
01509       result = getpwuid_r (uid, &p_str, buf,
sizeof
(buf),
01510                            &p);
01511
else
01512       result = getpwnam_r (username_c, &p_str, buf,
sizeof
(buf),
01513                            &p);
01514
#else
01515
if
(uid != DBUS_UID_UNSET)
01516       p = getpwuid_r (uid, &p_str, buf,
sizeof
(buf));
01517
else
01518       p = getpwnam_r (username_c, &p_str, buf,
sizeof
(buf));
01519     result = 0;
01520
#endif
/* !HAVE_POSIX_GETPWNAM_R */
01521
if
(result == 0 && p == &p_str)
01522       {
01523
if
(!fill_user_info_from_passwd (p, info, error))
01524
return
group__DBusMacros.html#ga3
FALSE
;
01525       }
01526
else
01527       {
01528
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
01529
"User \"%s\" unknown or no memory to allocate password entry\n"
,
01530                         username_c ? username_c :
"???"
);
01531         _dbus_verbose (
"User %s unknown\n"
, username_c ? username_c :
"???"
);
01532
return
group__DBusMacros.html#ga3
FALSE
;
01533       }
01534   }
01535
#else
/* ! HAVE_GETPWNAM_R */
01536   {
01537
/* I guess we're screwed on thread safety here */
01538
struct
passwd *p;
01539
01540
if
(uid != DBUS_UID_UNSET)
01541       p = getpwuid (uid);
01542
else
01543       p = getpwnam (username_c);
01544
01545
if
(p !=
group__DBusMacros.html#ga4
NULL
)
01546       {
01547
if
(!fill_user_info_from_passwd (p, info, error))
01548
return
group__DBusMacros.html#ga3
FALSE
;
01549       }
01550
else
01551       {
01552
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
01553
"User \"%s\" unknown or no memory to allocate password entry\n"
,
01554                         username_c ? username_c :
"???"
);
01555         _dbus_verbose (
"User %s unknown\n"
, username_c ? username_c :
"???"
);
01556
return
group__DBusMacros.html#ga3
FALSE
;
01557       }
01558   }
01559
#endif
/* ! HAVE_GETPWNAM_R */
01560
01561
/* Fill this in so we can use it to get groups */
01562   username_c = info->
structDBusUserInfo.html#o4
username
;
01563
01564
#ifdef HAVE_GETGROUPLIST
01565
{
01566     gid_t *buf;
01567
int
buf_count;
01568
int
i;
01569
01570     buf_count = 17;
01571     buf =
group__DBusMemory.html#ga6
dbus_new
(gid_t, buf_count);
01572
if
(buf ==
group__DBusMacros.html#ga4
NULL
)
01573       {
01574
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
01575
goto
failed;
01576       }
01577
01578
if
(getgrouplist (username_c,
01579                       info->
structDBusUserInfo.html#o1
primary_gid
,
01580                       buf, &buf_count) < 0)
01581       {
01582         gid_t *
new
=
group__DBusMemory.html#ga2
dbus_realloc
(buf, buf_count *
sizeof
(buf[0]));
01583
if
(
new
==
group__DBusMacros.html#ga4
NULL
)
01584           {
01585
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
01586
group__DBusMemory.html#ga3
dbus_free
(buf);
01587
goto
failed;
01588           }
01589
01590         buf =
new
;
01591
01592         errno = 0;
01593
if
(getgrouplist (username_c, info->
structDBusUserInfo.html#o1
primary_gid
, buf, &buf_count) < 0)
01594           {
01595
group__DBusErrors.html#ga6
dbus_set_error
(error,
01596
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
01597
"Failed to get groups for username \"%s\" primary GID "
01598                             DBUS_GID_FORMAT
": %s\n"
,
01599                             username_c, info->
structDBusUserInfo.html#o1
primary_gid
,
01600
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
01601
group__DBusMemory.html#ga3
dbus_free
(buf);
01602
goto
failed;
01603           }
01604       }
01605
01606     info->
structDBusUserInfo.html#o2
group_ids
=
group__DBusMemory.html#ga6
dbus_new
(dbus_gid_t, buf_count);
01607
if
(info->
structDBusUserInfo.html#o2
group_ids
==
group__DBusMacros.html#ga4
NULL
)
01608       {
01609
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
01610
group__DBusMemory.html#ga3
dbus_free
(buf);
01611
goto
failed;
01612       }
01613
01614
for
(i = 0; i < buf_count; ++i)
01615       info->
structDBusUserInfo.html#o2
group_ids
[i] = buf[i];
01616
01617     info->
structDBusUserInfo.html#o3
n_group_ids
= buf_count;
01618
01619
group__DBusMemory.html#ga3
dbus_free
(buf);
01620   }
01621
#else
/* HAVE_GETGROUPLIST */
01622   {
01623
/* We just get the one group ID */
01624     info->
structDBusUserInfo.html#o2
group_ids
=
group__DBusMemory.html#ga6
dbus_new
(dbus_gid_t, 1);
01625
if
(info->
structDBusUserInfo.html#o2
group_ids
==
group__DBusMacros.html#ga4
NULL
)
01626       {
01627
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
01628
goto
failed;
01629       }
01630
01631     info->
structDBusUserInfo.html#o3
n_group_ids
= 1;
01632
01633     (info->
structDBusUserInfo.html#o2
group_ids
)[0] = info->
structDBusUserInfo.html#o1
primary_gid
;
01634   }
01635
#endif
/* HAVE_GETGROUPLIST */
01636
01637   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01638
01639
return
group__DBusMacros.html#ga2
TRUE
;
01640
01641  failed:
01642   _DBUS_ASSERT_ERROR_IS_SET (error);
01643
return
group__DBusMacros.html#ga3
FALSE
;
01644 }
01645
01654
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusInternalsUtils.html#ga71
01655
group__DBusInternalsUtils.html#ga71
_dbus_user_info_fill
(
structDBusUserInfo.html
DBusUserInfo
*info,
01656
const
structDBusString.html
DBusString
*username,
01657
structDBusError.html
DBusError
*error)
01658 {
01659
return
fill_user_info (info, DBUS_UID_UNSET,
01660                          username, error);
01661 }
01662
01671
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusInternalsUtils.html#ga72
01672
group__DBusInternalsUtils.html#ga72
_dbus_user_info_fill_uid
(
structDBusUserInfo.html
DBusUserInfo
*info,
01673                           dbus_uid_t    uid,
01674
structDBusError.html
DBusError
*error)
01675 {
01676
return
fill_user_info (info, uid,
01677
group__DBusMacros.html#ga4
NULL
, error);
01678 }
01679
01685
void
group__DBusInternalsUtils.html#ga73
01686
group__DBusInternalsUtils.html#ga73
_dbus_user_info_free
(
structDBusUserInfo.html
DBusUserInfo
*info)
01687 {
01688
group__DBusMemory.html#ga3
dbus_free
(info->
structDBusUserInfo.html#o2
group_ids
);
01689
group__DBusMemory.html#ga3
dbus_free
(info->
structDBusUserInfo.html#o4
username
);
01690
group__DBusMemory.html#ga3
dbus_free
(info->
structDBusUserInfo.html#o5
homedir
);
01691 }
01692
01699
void
group__DBusInternalsUtils.html#ga74
01700
group__DBusInternalsUtils.html#ga74
_dbus_credentials_clear
(
structDBusCredentials.html
DBusCredentials
*credentials)
01701 {
01702   credentials->
structDBusCredentials.html#o0
pid
= DBUS_PID_UNSET;
01703   credentials->
structDBusCredentials.html#o1
uid
= DBUS_UID_UNSET;
01704   credentials->
structDBusCredentials.html#o2
gid
= DBUS_GID_UNSET;
01705 }
01706
01712
void
group__DBusInternalsUtils.html#ga75
01713
group__DBusInternalsUtils.html#ga75
_dbus_credentials_from_current_process
(
structDBusCredentials.html
DBusCredentials
*credentials)
01714 {
01715
/* The POSIX spec certainly doesn't promise this, but
01716
* we need these assertions to fail as soon as we're wrong about
01717
* it so we can do the porting fixups
01718
*/
01719
group__DBusInternalsUtils.html#ga130
_dbus_assert
(
sizeof
(pid_t) <=
sizeof
(credentials->
structDBusCredentials.html#o0
pid
));
01720
group__DBusInternalsUtils.html#ga130
_dbus_assert
(
sizeof
(uid_t) <=
sizeof
(credentials->
structDBusCredentials.html#o1
uid
));
01721
group__DBusInternalsUtils.html#ga130
_dbus_assert
(
sizeof
(gid_t) <=
sizeof
(credentials->
structDBusCredentials.html#o2
gid
));
01722
01723   credentials->
structDBusCredentials.html#o0
pid
= getpid ();
01724   credentials->
structDBusCredentials.html#o1
uid
= getuid ();
01725   credentials->
structDBusCredentials.html#o2
gid
= getgid ();
01726 }
01727
01736
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusInternalsUtils.html#ga76
01737
group__DBusInternalsUtils.html#ga76
_dbus_credentials_match
(
const
structDBusCredentials.html
DBusCredentials
*expected_credentials,
01738
const
structDBusCredentials.html
DBusCredentials
*provided_credentials)
01739 {
01740
if
(provided_credentials->
structDBusCredentials.html#o1
uid
== DBUS_UID_UNSET)
01741
return
group__DBusMacros.html#ga3
FALSE
;
01742
else
if
(expected_credentials->
structDBusCredentials.html#o1
uid
== DBUS_UID_UNSET)
01743
return
group__DBusMacros.html#ga3
FALSE
;
01744
else
if
(provided_credentials->
structDBusCredentials.html#o1
uid
== 0)
01745
return
group__DBusMacros.html#ga2
TRUE
;
01746
else
if
(provided_credentials->
structDBusCredentials.html#o1
uid
== expected_credentials->
structDBusCredentials.html#o1
uid
)
01747
return
group__DBusMacros.html#ga2
TRUE
;
01748
else
01749
return
group__DBusMacros.html#ga3
FALSE
;
01750 }
01751
01756
unsigned
long
group__DBusInternalsUtils.html#ga77
01757
group__DBusInternalsUtils.html#ga77
_dbus_getpid
(
void
)
01758 {
01759
return
getpid ();
01760 }
01761
01765 dbus_uid_t
group__DBusInternalsUtils.html#ga78
01766
group__DBusInternalsUtils.html#ga78
_dbus_getuid
(
void
)
01767 {
01768
return
getuid ();
01769 }
01770
01771
#ifdef DBUS_BUILD_TESTS
01772
01775 dbus_gid_t
01776 _dbus_getgid (
void
)
01777 {
01778
return
getgid ();
01779 }
01780
#endif
01781
01782
group__DBusInternalsUtils.html#ga146
_DBUS_DEFINE_GLOBAL_LOCK
(atomic);
01783
01784
#ifdef DBUS_USE_ATOMIC_INT_486
01785
/* Taken from CVS version 1.7 of glibc's sysdeps/i386/i486/atomicity.h */
01786
/* Since the asm stuff here is gcc-specific we go ahead and use "inline" also */
01787
static
inline
group__DBusTypes.html#ga4
dbus_int32_t
01788 atomic_exchange_and_add (
structDBusAtomic.html
DBusAtomic
*atomic,
01789
volatile
group__DBusTypes.html#ga4
dbus_int32_t
val)
01790 {
01791
register
group__DBusTypes.html#ga4
dbus_int32_t
result;
01792
01793   __asm__ __volatile__ (
"lock; xaddl %0,%1"
01794                         :
"=r"
(result),
"=m"
(atomic->
structDBusAtomic.html#o0
value
)
01795                         :
"0"
(val),
"m"
(atomic->
structDBusAtomic.html#o0
value
));
01796
return
result;
01797 }
01798
#endif
01799
01808
group__DBusTypes.html#ga4
dbus_int32_t
group__DBusInternalsUtils.html#ga80
01809
group__DBusInternalsUtils.html#ga80
_dbus_atomic_inc
(
structDBusAtomic.html
DBusAtomic
*atomic)
01810 {
01811
#ifdef DBUS_USE_ATOMIC_INT_486
01812
return
atomic_exchange_and_add (atomic, 1);
01813
#else
01814
group__DBusTypes.html#ga4
dbus_int32_t
res;
01815
group__DBusInternalsUtils.html#ga148
_DBUS_LOCK
(atomic);
01816   res = atomic->
structDBusAtomic.html#o0
value
;
01817   atomic->
structDBusAtomic.html#o0
value
+= 1;
01818
group__DBusInternalsUtils.html#ga149
_DBUS_UNLOCK
(atomic);
01819
return
res;
01820
#endif
01821
}
01822
01831
group__DBusTypes.html#ga4
dbus_int32_t
group__DBusInternalsUtils.html#ga81
01832
group__DBusInternalsUtils.html#ga81
_dbus_atomic_dec
(
structDBusAtomic.html
DBusAtomic
*atomic)
01833 {
01834
#ifdef DBUS_USE_ATOMIC_INT_486
01835
return
atomic_exchange_and_add (atomic, -1);
01836
#else
01837
group__DBusTypes.html#ga4
dbus_int32_t
res;
01838
01839
group__DBusInternalsUtils.html#ga148
_DBUS_LOCK
(atomic);
01840   res = atomic->
structDBusAtomic.html#o0
value
;
01841   atomic->
structDBusAtomic.html#o0
value
-= 1;
01842
group__DBusInternalsUtils.html#ga149
_DBUS_UNLOCK
(atomic);
01843
return
res;
01844
#endif
01845
}
01846
01855
int
group__DBusInternalsUtils.html#ga82
01856
group__DBusInternalsUtils.html#ga82
_dbus_poll
(
structDBusPollFD.html
DBusPollFD
*fds,
01857
int
n_fds,
01858
int
timeout_milliseconds)
01859 {
01860
#ifdef HAVE_POLL
01861
/* This big thing is a constant expression and should get optimized
01862
* out of existence. So it's more robust than a configure check at
01863
* no cost.
01864
*/
01865
if
(_DBUS_POLLIN == POLLIN &&
01866       _DBUS_POLLPRI == POLLPRI &&
01867       _DBUS_POLLOUT == POLLOUT &&
01868       _DBUS_POLLERR == POLLERR &&
01869       _DBUS_POLLHUP == POLLHUP &&
01870       _DBUS_POLLNVAL == POLLNVAL &&
01871
sizeof
(
structDBusPollFD.html
DBusPollFD
) ==
sizeof
(
struct
pollfd) &&
01872       _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
01873       _DBUS_STRUCT_OFFSET (
struct
pollfd, fd) &&
01874       _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
01875       _DBUS_STRUCT_OFFSET (
struct
pollfd, events) &&
01876       _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
01877       _DBUS_STRUCT_OFFSET (
struct
pollfd, revents))
01878     {
01879
return
poll ((
struct
pollfd*) fds,
01880                    n_fds,
01881                    timeout_milliseconds);
01882     }
01883
else
01884     {
01885
/* We have to convert the DBusPollFD to an array of
01886
* struct pollfd, poll, and convert back.
01887
*/
01888
group__DBusInternalsUtils.html#ga7
_dbus_warn
(
"didn't implement poll() properly for this system yet\n"
);
01889
return
-1;
01890     }
01891
#else
/* ! HAVE_POLL */
01892
01893   fd_set read_set, write_set, err_set;
01894
int
max_fd = 0;
01895
int
i;
01896
struct
timeval tv;
01897
int
ready;
01898
01899   FD_ZERO (&read_set);
01900   FD_ZERO (&write_set);
01901   FD_ZERO (&err_set);
01902
01903
for
(i = 0; i < n_fds; i++)
01904     {
01905       DBusPollFD *fdp = &fds[i];
01906
01907
if
(fdp->
structDBusPollFD.html#o1
events
& _DBUS_POLLIN)
01908         FD_SET (fdp->
structDBusPollFD.html#o0
fd
, &read_set);
01909
01910
if
(fdp->
structDBusPollFD.html#o1
events
& _DBUS_POLLOUT)
01911         FD_SET (fdp->
structDBusPollFD.html#o0
fd
, &write_set);
01912
01913       FD_SET (fdp->
structDBusPollFD.html#o0
fd
, &err_set);
01914
01915       max_fd = MAX (max_fd, fdp->
structDBusPollFD.html#o0
fd
);
01916     }
01917
01918   tv.tv_sec = timeout_milliseconds / 1000;
01919   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
01920
01921   ready = select (max_fd + 1, &read_set, &write_set, &err_set,
01922                   timeout_milliseconds < 0 ?
group__DBusMacros.html#ga4
NULL
: &tv);
01923
01924
if
(ready > 0)
01925     {
01926
for
(i = 0; i < n_fds; i++)
01927         {
01928           DBusPollFD *fdp = &fds[i];
01929
01930           fdp->
structDBusPollFD.html#o2
revents
= 0;
01931
01932
if
(FD_ISSET (fdp->
structDBusPollFD.html#o0
fd
, &read_set))
01933             fdp->
structDBusPollFD.html#o2
revents
|= _DBUS_POLLIN;
01934
01935
if
(FD_ISSET (fdp->
structDBusPollFD.html#o0
fd
, &write_set))
01936             fdp->
structDBusPollFD.html#o2
revents
|= _DBUS_POLLOUT;
01937
01938
if
(FD_ISSET (fdp->
structDBusPollFD.html#o0
fd
, &err_set))
01939             fdp->
structDBusPollFD.html#o2
revents
|= _DBUS_POLLERR;
01940         }
01941     }
01942
01943
return
ready;
01944
#endif
01945
}
01946
group__DBusInternalsUtils.html#ga154
01948
#define NANOSECONDS_PER_SECOND       1000000000
01949
group__DBusInternalsUtils.html#ga155
01950
#define MICROSECONDS_PER_SECOND      1000000
01951
group__DBusInternalsUtils.html#ga156
01952
#define MILLISECONDS_PER_SECOND      1000
01953
group__DBusInternalsUtils.html#ga157
01954
#define NANOSECONDS_PER_MILLISECOND  1000000
01955
group__DBusInternalsUtils.html#ga158
01956
#define MICROSECONDS_PER_MILLISECOND 1000
01957
01962
void
group__DBusInternalsUtils.html#ga83
01963
group__DBusInternalsUtils.html#ga83
_dbus_sleep_milliseconds
(
int
milliseconds)
01964 {
01965
#ifdef HAVE_NANOSLEEP
01966
struct
timespec req;
01967
struct
timespec rem;
01968
01969   req.tv_sec = milliseconds /
group__DBusInternalsUtils.html#ga156
MILLISECONDS_PER_SECOND
;
01970   req.tv_nsec = (milliseconds %
group__DBusInternalsUtils.html#ga156
MILLISECONDS_PER_SECOND
) *
group__DBusInternalsUtils.html#ga157
NANOSECONDS_PER_MILLISECOND
;
01971   rem.tv_sec = 0;
01972   rem.tv_nsec = 0;
01973
01974
while
(nanosleep (&req, &rem) < 0 && errno == EINTR)
01975     req = rem;
01976
#elif defined (HAVE_USLEEP)
01977
usleep (milliseconds *
group__DBusInternalsUtils.html#ga158
MICROSECONDS_PER_MILLISECOND
);
01978
#else
/* ! HAVE_USLEEP */
01979   sleep (MAX (milliseconds / 1000, 1));
01980
#endif
01981
}
01982
01989
void
group__DBusInternalsUtils.html#ga84
01990
group__DBusInternalsUtils.html#ga84
_dbus_get_current_time
(
long
*tv_sec,
01991
long
*tv_usec)
01992 {
01993
struct
timeval t;
01994
01995   gettimeofday (&t,
group__DBusMacros.html#ga4
NULL
);
01996
01997
if
(tv_sec)
01998     *tv_sec = t.tv_sec;
01999
if
(tv_usec)
02000     *tv_usec = t.tv_usec;
02001 }
02002
02013
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusInternalsUtils.html#ga85
02014
group__DBusInternalsUtils.html#ga85
_dbus_file_get_contents
(
structDBusString.html
DBusString
*str,
02015
const
structDBusString.html
DBusString
*filename,
02016
structDBusError.html
DBusError
*error)
02017 {
02018
int
fd;
02019
struct
stat sb;
02020
int
orig_len;
02021
int
total;
02022
const
char
*filename_c;
02023
02024   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02025
02026   filename_c = _dbus_string_get_const_data (filename);
02027
02028
/* O_BINARY useful on Cygwin */
02029   fd = open (filename_c, O_RDONLY | O_BINARY);
02030
if
(fd < 0)
02031     {
02032
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
02033
"Failed to open \"%s\": %s"
,
02034                       filename_c,
02035
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
02036
return
group__DBusMacros.html#ga3
FALSE
;
02037     }
02038
02039
if
(fstat (fd, &sb) < 0)
02040     {
02041
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
02042
"Failed to stat \"%s\": %s"
,
02043                       filename_c,
02044
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
02045
02046       _dbus_verbose (
"fstat() failed: %s"
,
02047
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
02048
02049       close (fd);
02050
02051
return
group__DBusMacros.html#ga3
FALSE
;
02052     }
02053
02054
if
(sb.st_size > _DBUS_ONE_MEGABYTE)
02055     {
02056
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_FAILED,
02057
"File size %lu of \"%s\" is too large."
,
02058                       (
unsigned
long
) sb.st_size, filename_c);
02059       close (fd);
02060
return
group__DBusMacros.html#ga3
FALSE
;
02061     }
02062
02063   total = 0;
02064   orig_len = _dbus_string_get_length (str);
02065
if
(sb.st_size > 0 && S_ISREG (sb.st_mode))
02066     {
02067
int
bytes_read;
02068
02069
while
(total < (
int
) sb.st_size)
02070         {
02071           bytes_read =
group__DBusInternalsUtils.html#ga58
_dbus_read
(fd, str,
02072                                    sb.st_size - total);
02073
if
(bytes_read <= 0)
02074             {
02075
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
02076
"Error reading \"%s\": %s"
,
02077                               filename_c,
02078
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
02079
02080               _dbus_verbose (
"read() failed: %s"
,
02081
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
02082
02083               close (fd);
02084
group__DBusString.html#ga21
_dbus_string_set_length
(str, orig_len);
02085
return
group__DBusMacros.html#ga3
FALSE
;
02086             }
02087
else
02088             total += bytes_read;
02089         }
02090
02091       close (fd);
02092
return
group__DBusMacros.html#ga2
TRUE
;
02093     }
02094
else
if
(sb.st_size != 0)
02095     {
02096       _dbus_verbose (
"Can only open regular files at the moment.\n"
);
02097
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_FAILED,
02098
"\"%s\" is not a regular file"
,
02099                       filename_c);
02100       close (fd);
02101
return
group__DBusMacros.html#ga3
FALSE
;
02102     }
02103
else
02104     {
02105       close (fd);
02106
return
group__DBusMacros.html#ga2
TRUE
;
02107     }
02108 }
02109
02119
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusInternalsUtils.html#ga86
02120
group__DBusInternalsUtils.html#ga86
_dbus_string_save_to_file
(
const
structDBusString.html
DBusString
*str,
02121
const
structDBusString.html
DBusString
*filename,
02122
structDBusError.html
DBusError
*error)
02123 {
02124
int
fd;
02125
int
bytes_to_write;
02126
const
char
*filename_c;
02127
structDBusString.html
DBusString
tmp_filename;
02128
const
char
*tmp_filename_c;
02129
int
total;
02130
group__DBusTypes.html#ga2
dbus_bool_t
need_unlink;
02131
group__DBusTypes.html#ga2
dbus_bool_t
retval;
02132
02133   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02134
02135   fd = -1;
02136   retval =
group__DBusMacros.html#ga3
FALSE
;
02137   need_unlink =
group__DBusMacros.html#ga3
FALSE
;
02138
02139
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&tmp_filename))
02140     {
02141
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
02142
return
group__DBusMacros.html#ga3
FALSE
;
02143     }
02144
02145
if
(!
group__DBusString.html#ga40
_dbus_string_copy
(filename, 0, &tmp_filename, 0))
02146     {
02147
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
02148
group__DBusString.html#ga9
_dbus_string_free
(&tmp_filename);
02149
return
group__DBusMacros.html#ga3
FALSE
;
02150     }
02151
02152
if
(!
group__DBusString.html#ga27
_dbus_string_append
(&tmp_filename,
"."
))
02153     {
02154
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
02155
group__DBusString.html#ga9
_dbus_string_free
(&tmp_filename);
02156
return
group__DBusMacros.html#ga3
FALSE
;
02157     }
02158
02159
#define N_TMP_FILENAME_RANDOM_BYTES 8
02160
if
(!
group__DBusInternalsUtils.html#ga95
_dbus_generate_random_ascii
(&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
02161     {
02162
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
02163
group__DBusString.html#ga9
_dbus_string_free
(&tmp_filename);
02164
return
group__DBusMacros.html#ga3
FALSE
;
02165     }
02166
02167   filename_c = _dbus_string_get_const_data (filename);
02168   tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
02169
02170   fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
02171              0600);
02172
if
(fd < 0)
02173     {
02174
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
02175
"Could not create %s: %s"
, tmp_filename_c,
02176
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
02177
goto
out;
02178     }
02179
02180   need_unlink =
group__DBusMacros.html#ga2
TRUE
;
02181
02182   total = 0;
02183   bytes_to_write = _dbus_string_get_length (str);
02184
02185
while
(total < bytes_to_write)
02186     {
02187
int
bytes_written;
02188
02189       bytes_written =
group__DBusInternalsUtils.html#ga59
_dbus_write
(fd, str, total,
02190                                    bytes_to_write - total);
02191
02192
if
(bytes_written <= 0)
02193         {
02194
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
02195
"Could not write to %s: %s"
, tmp_filename_c,
02196
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
02197
02198
goto
out;
02199         }
02200
02201       total += bytes_written;
02202     }
02203
02204
if
(close (fd) < 0)
02205     {
02206
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
02207
"Could not close file %s: %s"
,
02208                       tmp_filename_c,
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
02209
02210
goto
out;
02211     }
02212
02213   fd = -1;
02214
02215
if
(rename (tmp_filename_c, filename_c) < 0)
02216     {
02217
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
02218
"Could not rename %s to %s: %s"
,
02219                       tmp_filename_c, filename_c,
02220
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
02221
02222
goto
out;
02223     }
02224
02225   need_unlink =
group__DBusMacros.html#ga3
FALSE
;
02226
02227   retval =
group__DBusMacros.html#ga2
TRUE
;
02228
02229  out:
02230
/* close first, then unlink, to prevent ".nfs34234235" garbage
02231
* files
02232
*/
02233
02234
if
(fd >= 0)
02235     close (fd);
02236
02237
if
(need_unlink && unlink (tmp_filename_c) < 0)
02238     _dbus_verbose (
"Failed to unlink temp file %s: %s\n"
,
02239                    tmp_filename_c,
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
02240
02241
group__DBusString.html#ga9
_dbus_string_free
(&tmp_filename);
02242
02243
if
(!retval)
02244     _DBUS_ASSERT_ERROR_IS_SET (error);
02245
02246
return
retval;
02247 }
02248
02255
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusInternalsUtils.html#ga87
02256
group__DBusInternalsUtils.html#ga87
_dbus_create_file_exclusively
(
const
structDBusString.html
DBusString
*filename,
02257
structDBusError.html
DBusError
*error)
02258 {
02259
int
fd;
02260
const
char
*filename_c;
02261
02262   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02263
02264   filename_c = _dbus_string_get_const_data (filename);
02265
02266   fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
02267              0600);
02268
if
(fd < 0)
02269     {
02270
group__DBusErrors.html#ga6
dbus_set_error
(error,
02271                       DBUS_ERROR_FAILED,
02272
"Could not create file %s: %s\n"
,
02273                       filename_c,
02274
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
02275
return
group__DBusMacros.html#ga3
FALSE
;
02276     }
02277
02278
if
(close (fd) < 0)
02279     {
02280
group__DBusErrors.html#ga6
dbus_set_error
(error,
02281                       DBUS_ERROR_FAILED,
02282
"Could not close file %s: %s\n"
,
02283                       filename_c,
02284
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
02285
return
group__DBusMacros.html#ga3
FALSE
;
02286     }
02287
02288
return
group__DBusMacros.html#ga2
TRUE
;
02289 }
02290
02299
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusInternalsUtils.html#ga88
02300
group__DBusInternalsUtils.html#ga88
_dbus_delete_file
(
const
structDBusString.html
DBusString
*filename,
02301
structDBusError.html
DBusError
*error)
02302 {
02303
const
char
*filename_c;
02304
02305   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02306
02307   filename_c = _dbus_string_get_const_data (filename);
02308
02309
if
(unlink (filename_c) < 0)
02310     {
02311
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_FAILED,
02312
"Failed to delete file %s: %s\n"
,
02313                       filename_c,
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
02314
return
group__DBusMacros.html#ga3
FALSE
;
02315     }
02316
else
02317
return
group__DBusMacros.html#ga2
TRUE
;
02318 }
02319
02328
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusInternalsUtils.html#ga89
02329
group__DBusInternalsUtils.html#ga89
_dbus_create_directory
(
const
structDBusString.html
DBusString
*filename,
02330
structDBusError.html
DBusError
*error)
02331 {
02332
const
char
*filename_c;
02333
02334   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02335
02336   filename_c = _dbus_string_get_const_data (filename);
02337
02338
if
(mkdir (filename_c, 0700) < 0)
02339     {
02340
if
(errno == EEXIST)
02341
return
group__DBusMacros.html#ga2
TRUE
;
02342
02343
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_FAILED,
02344
"Failed to create directory %s: %s\n"
,
02345                       filename_c,
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
02346
return
group__DBusMacros.html#ga3
FALSE
;
02347     }
02348
else
02349
return
group__DBusMacros.html#ga2
TRUE
;
02350 }
02351
02362
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusInternalsUtils.html#ga90
02363
group__DBusInternalsUtils.html#ga90
_dbus_concat_dir_and_file
(
structDBusString.html
DBusString
*dir,
02364
const
structDBusString.html
DBusString
*next_component)
02365 {
02366
group__DBusTypes.html#ga2
dbus_bool_t
dir_ends_in_slash;
02367
group__DBusTypes.html#ga2
dbus_bool_t
file_starts_with_slash;
02368
02369
if
(_dbus_string_get_length (dir) == 0 ||
02370       _dbus_string_get_length (next_component) == 0)
02371
return
group__DBusMacros.html#ga2
TRUE
;
02372
02373   dir_ends_in_slash =
'/'
== _dbus_string_get_byte (dir,
02374                                                     _dbus_string_get_length (dir) - 1);
02375
02376   file_starts_with_slash =
'/'
== _dbus_string_get_byte (next_component, 0);
02377
02378
if
(dir_ends_in_slash && file_starts_with_slash)
02379     {
02380
group__DBusString.html#ga20
_dbus_string_shorten
(dir, 1);
02381     }
02382
else
if
(!(dir_ends_in_slash || file_starts_with_slash))
02383     {
02384
if
(!
group__DBusString.html#ga35
_dbus_string_append_byte
(dir,
'/'
))
02385
return
group__DBusMacros.html#ga3
FALSE
;
02386     }
02387
02388
return
group__DBusString.html#ga40
_dbus_string_copy
(next_component, 0, dir,
02389                             _dbus_string_get_length (dir));
02390 }
02391
02392
static
void
02393 pseudorandom_generate_random_bytes_buffer (
char
*buffer,
02394
int
n_bytes)
02395 {
02396
unsigned
long
tv_usec;
02397
int
i;
02398
02399
/* fall back to pseudorandom */
02400   _dbus_verbose (
"Falling back to pseudorandom for %d bytes\n"
,
02401                  n_bytes);
02402
02403
group__DBusInternalsUtils.html#ga84
_dbus_get_current_time
(
group__DBusMacros.html#ga4
NULL
, &tv_usec);
02404   srand (tv_usec);
02405
02406   i = 0;
02407
while
(i < n_bytes)
02408     {
02409
double
r;
02410
unsigned
int
b;
02411
02412       r = rand ();
02413       b = (r / (double) RAND_MAX) * 255.0;
02414
02415       buffer[i] = b;
02416
02417       ++i;
02418     }
02419 }
02420
02421
static
group__DBusTypes.html#ga2
dbus_bool_t
02422 pseudorandom_generate_random_bytes (
structDBusString.html
DBusString
*str,
02423
int
n_bytes)
02424 {
02425
int
old_len;
02426
char
*p;
02427
02428   old_len = _dbus_string_get_length (str);
02429
02430
if
(!
group__DBusString.html#ga19
_dbus_string_lengthen
(str, n_bytes))
02431
return
group__DBusMacros.html#ga3
FALSE
;
02432
02433   p =
group__DBusString.html#ga13
_dbus_string_get_data_len
(str, old_len, n_bytes);
02434
02435   pseudorandom_generate_random_bytes_buffer (p, n_bytes);
02436
02437
return
group__DBusMacros.html#ga2
TRUE
;
02438 }
02439
02446
void
group__DBusInternalsUtils.html#ga93
02447
group__DBusInternalsUtils.html#ga93
_dbus_generate_random_bytes_buffer
(
char
*buffer,
02448
int
n_bytes)
02449 {
02450
structDBusString.html
DBusString
str;
02451
02452
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&str))
02453     {
02454       pseudorandom_generate_random_bytes_buffer (buffer, n_bytes);
02455
return
;
02456     }
02457
02458
if
(!
group__DBusInternalsUtils.html#ga94
_dbus_generate_random_bytes
(&str, n_bytes))
02459     {
02460
group__DBusString.html#ga9
_dbus_string_free
(&str);
02461       pseudorandom_generate_random_bytes_buffer (buffer, n_bytes);
02462
return
;
02463     }
02464
02465
group__DBusString.html#ga18
_dbus_string_copy_to_buffer
(&str, buffer, n_bytes);
02466
02467
group__DBusString.html#ga9
_dbus_string_free
(&str);
02468 }
02469
02478
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusInternalsUtils.html#ga94
02479
group__DBusInternalsUtils.html#ga94
_dbus_generate_random_bytes
(
structDBusString.html
DBusString
*str,
02480
int
n_bytes)
02481 {
02482
int
old_len;
02483
int
fd;
02484
02485
/* FALSE return means "no memory", if it could
02486
* mean something else then we'd need to return
02487
* a DBusError. So we always fall back to pseudorandom
02488
* if the I/O fails.
02489
*/
02490
02491   old_len = _dbus_string_get_length (str);
02492   fd = -1;
02493
02494
/* note, urandom on linux will fall back to pseudorandom */
02495   fd = open (
"/dev/urandom"
, O_RDONLY);
02496
if
(fd < 0)
02497
return
pseudorandom_generate_random_bytes (str, n_bytes);
02498
02499
if
(
group__DBusInternalsUtils.html#ga58
_dbus_read
(fd, str, n_bytes) != n_bytes)
02500     {
02501       close (fd);
02502
group__DBusString.html#ga21
_dbus_string_set_length
(str, old_len);
02503
return
pseudorandom_generate_random_bytes (str, n_bytes);
02504     }
02505
02506   _dbus_verbose (
"Read %d bytes from /dev/urandom\n"
,
02507                  n_bytes);
02508
02509   close (fd);
02510
02511
return
group__DBusMacros.html#ga2
TRUE
;
02512 }
02513
02522
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusInternalsUtils.html#ga95
02523
group__DBusInternalsUtils.html#ga95
_dbus_generate_random_ascii
(
structDBusString.html
DBusString
*str,
02524
int
n_bytes)
02525 {
02526
static
const
char
letters[] =
02527
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"
;
02528
int
i;
02529
int
len;
02530
02531
if
(!
group__DBusInternalsUtils.html#ga94
_dbus_generate_random_bytes
(str, n_bytes))
02532
return
group__DBusMacros.html#ga3
FALSE
;
02533
02534   len = _dbus_string_get_length (str);
02535   i = len - n_bytes;
02536
while
(i < len)
02537     {
02538       _dbus_string_set_byte (str, i,
02539                              letters[_dbus_string_get_byte (str, i) %
02540                                      (
sizeof
(letters) - 1)]);
02541
02542       ++i;
02543     }
02544
02545
group__DBusInternalsUtils.html#ga130
_dbus_assert
(
group__DBusString.html#ga55
_dbus_string_validate_ascii
(str, len - n_bytes,
02546                                              n_bytes));
02547
02548
return
group__DBusMacros.html#ga2
TRUE
;
02549 }
02550
02558
const
char
*
group__DBusInternalsUtils.html#ga96
02559
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(
int
error_number)
02560 {
02561
const
char
*msg;
02562
02563   msg = strerror (error_number);
02564
if
(msg ==
group__DBusMacros.html#ga4
NULL
)
02565     msg =
"unknown"
;
02566
02567
return
msg;
02568 }
02569
02573
void
group__DBusInternalsUtils.html#ga97
02574
group__DBusInternalsUtils.html#ga97
_dbus_disable_sigpipe
(
void
)
02575 {
02576   signal (SIGPIPE, SIG_IGN);
02577 }
02578
02586
void
group__DBusInternalsUtils.html#ga98
02587
group__DBusInternalsUtils.html#ga98
_dbus_fd_set_close_on_exec
(
int
fd)
02588 {
02589
int
val;
02590
02591   val = fcntl (fd, F_GETFD, 0);
02592
02593
if
(val < 0)
02594
return
;
02595
02596   val |= FD_CLOEXEC;
02597
02598   fcntl (fd, F_SETFD, val);
02599 }
02600
02610
const
char
*
group__DBusInternalsUtils.html#ga99
02611
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(
int
error_number)
02612 {
02613
switch
(error_number)
02614     {
02615
case
0:
02616
return
DBUS_ERROR_FAILED;
02617
02618
#ifdef EPROTONOSUPPORT
02619
case
EPROTONOSUPPORT:
02620
return
DBUS_ERROR_NOT_SUPPORTED;
02621
#endif
02622
#ifdef EAFNOSUPPORT
02623
case
EAFNOSUPPORT:
02624
return
DBUS_ERROR_NOT_SUPPORTED;
02625
#endif
02626
#ifdef ENFILE
02627
case
ENFILE:
02628
return
DBUS_ERROR_LIMITS_EXCEEDED;
/* kernel out of memory */
02629
#endif
02630
#ifdef EMFILE
02631
case
EMFILE:
02632
return
DBUS_ERROR_LIMITS_EXCEEDED;
02633
#endif
02634
#ifdef EACCES
02635
case
EACCES:
02636
return
DBUS_ERROR_ACCESS_DENIED;
02637
#endif
02638
#ifdef EPERM
02639
case
EPERM:
02640
return
DBUS_ERROR_ACCESS_DENIED;
02641
#endif
02642
#ifdef ENOBUFS
02643
case
ENOBUFS:
02644
return
DBUS_ERROR_NO_MEMORY;
02645
#endif
02646
#ifdef ENOMEM
02647
case
ENOMEM:
02648
return
DBUS_ERROR_NO_MEMORY;
02649
#endif
02650
#ifdef EINVAL
02651
case
EINVAL:
02652
return
DBUS_ERROR_FAILED;
02653
#endif
02654
#ifdef EBADF
02655
case
EBADF:
02656
return
DBUS_ERROR_FAILED;
02657
#endif
02658
#ifdef EFAULT
02659
case
EFAULT:
02660
return
DBUS_ERROR_FAILED;
02661
#endif
02662
#ifdef ENOTSOCK
02663
case
ENOTSOCK:
02664
return
DBUS_ERROR_FAILED;
02665
#endif
02666
#ifdef EISCONN
02667
case
EISCONN:
02668
return
DBUS_ERROR_FAILED;
02669
#endif
02670
#ifdef ECONNREFUSED
02671
case
ECONNREFUSED:
02672
return
DBUS_ERROR_NO_SERVER;
02673
#endif
02674
#ifdef ETIMEDOUT
02675
case
ETIMEDOUT:
02676
return
DBUS_ERROR_TIMEOUT;
02677
#endif
02678
#ifdef ENETUNREACH
02679
case
ENETUNREACH:
02680
return
DBUS_ERROR_NO_NETWORK;
02681
#endif
02682
#ifdef EADDRINUSE
02683
case
EADDRINUSE:
02684
return
DBUS_ERROR_ADDRESS_IN_USE;
02685
#endif
02686
#ifdef EEXIST
02687
case
EEXIST:
02688
return
DBUS_ERROR_FILE_NOT_FOUND;
02689
#endif
02690
#ifdef ENOENT
02691
case
ENOENT:
02692
return
DBUS_ERROR_FILE_NOT_FOUND;
02693
#endif
02694
}
02695
02696
return
DBUS_ERROR_FAILED;
02697 }
02698
02704
void
group__DBusInternalsUtils.html#ga100
02705
group__DBusInternalsUtils.html#ga100
_dbus_exit
(
int
code)
02706 {
02707   _exit (code);
02708 }
02709
02717
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusInternalsUtils.html#ga101
02718
group__DBusInternalsUtils.html#ga101
_dbus_close
(
int
fd,
02719
structDBusError.html
DBusError
*error)
02720 {
02721   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02722
02723  again:
02724
if
(close (fd) < 0)
02725     {
02726
if
(errno == EINTR)
02727
goto
again;
02728
02729
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
02730
"Could not close fd %d"
, fd);
02731
return
group__DBusMacros.html#ga3
FALSE
;
02732     }
02733
02734
return
group__DBusMacros.html#ga2
TRUE
;
02735 }
02736
02744
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusInternalsUtils.html#ga102
02745
group__DBusInternalsUtils.html#ga102
_dbus_set_fd_nonblocking
(
int
fd,
02746
structDBusError.html
DBusError
*error)
02747 {
02748
int
val;
02749
02750   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02751
02752   val = fcntl (fd, F_GETFL, 0);
02753
if
(val < 0)
02754     {
02755
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
02756
"Failed to get flags from file descriptor %d: %s"
,
02757                       fd,
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
02758       _dbus_verbose (
"Failed to get flags for fd %d: %s\n"
, fd,
02759
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
02760
return
group__DBusMacros.html#ga3
FALSE
;
02761     }
02762
02763
if
(fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
02764     {
02765
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
02766
"Failed to set nonblocking flag of file descriptor %d: %s"
,
02767                       fd,
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
02768       _dbus_verbose (
"Failed to set fd %d nonblocking: %s\n"
,
02769                      fd,
group__DBusInternalsUtils.html#ga96
_dbus_strerror
(errno));
02770
02771
return
group__DBusMacros.html#ga3
FALSE
;
02772     }
02773
02774
return
group__DBusMacros.html#ga2
TRUE
;
02775 }
02776
02777
#if !defined (DBUS_DISABLE_ASSERT) || defined(DBUS_BUILD_TESTS)
02778
02783
void
02784 _dbus_print_backtrace (
void
)
02785 {
02786
#if defined (HAVE_BACKTRACE) && defined (DBUS_ENABLE_VERBOSE_MODE)
02787
void
*bt[500];
02788
int
bt_size;
02789
int
i;
02790
char
**syms;
02791
02792   bt_size = backtrace (bt, 500);
02793
02794   syms = backtrace_symbols (bt, bt_size);
02795
02796   i = 0;
02797
while
(i < bt_size)
02798     {
02799       _dbus_verbose (
"  %s\n"
, syms[i]);
02800       ++i;
02801     }
02802
02803   free (syms);
02804
#else
02805
_dbus_verbose (
"  D-BUS not compiled with backtrace support\n"
);
02806
#endif
02807
}
02808
#endif
/* asserts or tests enabled */
02809
02810
02818
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusInternalsUtils.html#ga103
02819
group__DBusInternalsUtils.html#ga103
_dbus_parse_uid
(
const
structDBusString.html
DBusString
*uid_str,
02820                  dbus_uid_t            *uid)
02821 {
02822
int
end;
02823
long
val;
02824
02825
if
(_dbus_string_get_length (uid_str) == 0)
02826     {
02827       _dbus_verbose (
"UID string was zero length\n"
);
02828
return
group__DBusMacros.html#ga3
FALSE
;
02829     }
02830
02831   val = -1;
02832   end = 0;
02833
if
(!
group__DBusString.html#ga62
_dbus_string_parse_int
(uid_str, 0, &val,
02834                                &end))
02835     {
02836       _dbus_verbose (
"could not parse string as a UID\n"
);
02837
return
group__DBusMacros.html#ga3
FALSE
;
02838     }
02839
02840
if
(end != _dbus_string_get_length (uid_str))
02841     {
02842       _dbus_verbose (
"string contained trailing stuff after UID\n"
);
02843
return
group__DBusMacros.html#ga3
FALSE
;
02844     }
02845
02846   *uid = val;
02847
02848
return
group__DBusMacros.html#ga2
TRUE
;
02849 }
02850
02866
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusInternalsUtils.html#ga104
02867
group__DBusInternalsUtils.html#ga104
_dbus_full_duplex_pipe
(
int
*fd1,
02868
int
*fd2,
02869
group__DBusTypes.html#ga2
dbus_bool_t
blocking,
02870
structDBusError.html
DBusError
*error)
02871 {
02872
#ifdef HAVE_SOCKETPAIR
02873
int
fds[2];
02874
02875   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02876
02877
if
(socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0)
02878     {
02879
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
02880
"Could not create full-duplex pipe"
);
02881
return
group__DBusMacros.html#ga3
FALSE
;
02882     }
02883
02884
if
(!blocking &&
02885       (!
group__DBusInternalsUtils.html#ga102
_dbus_set_fd_nonblocking
(fds[0],
group__DBusMacros.html#ga4
NULL
) ||
02886        !
group__DBusInternalsUtils.html#ga102
_dbus_set_fd_nonblocking
(fds[1],
group__DBusMacros.html#ga4
NULL
)))
02887     {
02888
group__DBusErrors.html#ga6
dbus_set_error
(error,
group__DBusInternalsUtils.html#ga99
_dbus_error_from_errno
(errno),
02889
"Could not set full-duplex pipe nonblocking"
);
02890
02891       close (fds[0]);
02892       close (fds[1]);
02893
02894
return
group__DBusMacros.html#ga3
FALSE
;
02895     }
02896
02897   *fd1 = fds[0];
02898   *fd2 = fds[1];
02899
02900   _dbus_verbose (
"full-duplex pipe %d <-> %d\n"
,
02901                  *fd1, *fd2);
02902
02903
return
group__DBusMacros.html#ga2
TRUE
;
02904
#else
02905
group__DBusInternalsUtils.html#ga7
_dbus_warn
(
"_dbus_full_duplex_pipe() not implemented on this OS\n"
);
02906
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_FAILED,
02907
"_dbus_full_duplex_pipe() not implemented on this OS"
);
02908
return
group__DBusMacros.html#ga3
FALSE
;
02909
#endif
02910
}
02911
02914
/* tests in dbus-sysdeps-util.c */
Generated on Tue Sep 13 01:28:07 2005 for D-BUS by
http://www.doxygen.org/index.html
doxygen
1.4.4
