initial windows patch
Peter Kümmel
syntheticpp at gmx.net
Tue Jul 4 00:00:32 PDT 2006
Now I have a patch for the windows port
which is less big then before: 55kB.
Most code I've moved into *-win. files.
Only when the win code is heavily weaved
into the original code, is trivial, or
short, I've not moved it.
uid and gid are also on windows integer
identifiers. The mapping is done internally
and a uid->sid function is provided.
I've not changed the file handling stuff.
ATM I've only one patch, because I think the
splitting is done by moving the most code to
the new files.
I hope it is possible to commit this patch after
a review, because it costs me much time to further
split the code. When someone read the patch he
will see that the linux code is effectively not
touched, and where it is touched it should be
reported as a bug.
The code compiles mith GCC 3.4, 4.0.1, MSVC 8.
Under windows it passes dbub-test (except spwb)
and dbus-daemon starts.
Here I use cmake to build dbus, because when using
msvc be can't use the auto tools and we have to use
something else. And it is no good idea to only support
mingw under windows, because when using msvc you have
a great debugger, which makes developing much easier.
Therefore I would like to add a cmake folder to cvs.
I could place ALL cmake related files into this cmake
directory without cluttering the whole dbus tree.
Best regards,
Peter
-------------- next part --------------
? dbus/dbus-dirent-win.c
? dbus/dbus-dirent-win.h
? dbus/dbus-example.c
? dbus/dbus-sockets-win.h
? dbus/dbus-spawn-win.c
? dbus/dbus-sysdeps-util-win.c
? dbus/dbus-sysdeps-win.c
? dbus/dbus-sysdeps-win.h
Index: bus/activation.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/activation.c,v
retrieving revision 1.41
diff -u -B -b -r1.41 activation.c
--- bus/activation.c 22 Nov 2005 20:37:00 -0000 1.41
+++ bus/activation.c 3 Jul 2006 12:56:20 -0000
@@ -33,7 +33,11 @@
#include <dbus/dbus-shell.h>
#include <dbus/dbus-spawn.h>
#include <dbus/dbus-timeout.h>
+#ifdef DBUS_WIN
+#include <dbus/dbus-dirent-win.h>
+#else
#include <dirent.h>
+#endif
#include <errno.h>
#define DBUS_SERVICE_SECTION "D-BUS Service"
@@ -1305,6 +1309,7 @@
DBusMessage *message;
DBusString service_str;
char **argv;
+ char **envp;
int argc;
dbus_bool_t retval;
DBusHashIter iter;
@@ -1536,6 +1541,9 @@
_dbus_verbose ("Spawning %s ...\n", argv[0]);
if (!_dbus_spawn_async_with_babysitter (&pending_activation->babysitter, argv,
+#ifdef DBUS_WIN
+ envp,
+#endif
child_setup, activation,
error))
{
Index: bus/main.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/main.c,v
retrieving revision 1.31
diff -u -B -b -r1.31 main.c
--- bus/main.c 15 Jun 2005 02:31:38 -0000 1.31
+++ bus/main.c 3 Jul 2006 12:56:24 -0000
@@ -36,6 +36,9 @@
#define RELOAD_READ_END 0
#define RELOAD_WRITE_END 1
+#ifndef SIGHUP
+#define SIGHUP 1
+#endif
static void
signal_handler (int sig)
Index: dbus/dbus-internals.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-internals.c,v
retrieving revision 1.44
diff -u -B -b -r1.44 dbus-internals.c
--- dbus/dbus-internals.c 13 Feb 2005 20:23:30 -0000 1.44
+++ dbus/dbus-internals.c 3 Jul 2006 12:56:29 -0000
@@ -28,7 +28,9 @@
#include <string.h>
#include <sys/types.h>
#include <errno.h>
+#ifndef DBUS_WIN
#include <unistd.h>
+#endif
#include <fcntl.h>
#include <stdlib.h>
@@ -246,7 +248,12 @@
if (!verbose_initted)
{
+#ifdef DBUS_WIN
+ const char *p = _dbus_getenv ("DBUS_VERBOSE");
+ verbose = p != NULL && *p == '1';
+#else
verbose = _dbus_getenv ("DBUS_VERBOSE") != NULL;
+#endif
verbose_initted = TRUE;
if (!verbose)
return;
Index: dbus/dbus-internals.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-internals.h,v
retrieving revision 1.55
diff -u -B -b -r1.55 dbus-internals.h
--- dbus/dbus-internals.h 26 Feb 2005 06:37:46 -0000 1.55
+++ dbus/dbus-internals.h 3 Jul 2006 12:56:29 -0000
@@ -81,9 +81,15 @@
...) _DBUS_GNUC_PRINTF (1, 2);
void _dbus_verbose_reset_real (void);
+#ifdef HAVE_GNUC_VARARGS
+# define _dbus_verbose(format, rest...) _dbus_verbose_real("[%s %d] " format, __FUNCTION__,__LINE__, ## rest)
+#else
# define _dbus_verbose _dbus_verbose_real
+#endif
# define _dbus_verbose_reset _dbus_verbose_reset_real
+
#else
+
# ifdef HAVE_ISO_VARARGS
# define _dbus_verbose(...)
# elif defined (HAVE_GNUC_VARARGS)
@@ -270,6 +276,10 @@
#define _DBUS_LOCK(name) _dbus_mutex_lock (_dbus_lock_##name)
#define _DBUS_UNLOCK(name) _dbus_mutex_unlock (_dbus_lock_##name)
+#ifdef DBUS_WIN
+_DBUS_DECLARE_GLOBAL_LOCK (win32_fds);
+_DBUS_DECLARE_GLOBAL_LOCK (sid_atom_cache);
+#endif
_DBUS_DECLARE_GLOBAL_LOCK (list);
_DBUS_DECLARE_GLOBAL_LOCK (connection_slots);
_DBUS_DECLARE_GLOBAL_LOCK (pending_call_slots);
@@ -281,7 +291,11 @@
_DBUS_DECLARE_GLOBAL_LOCK (system_users);
_DBUS_DECLARE_GLOBAL_LOCK (message_cache);
_DBUS_DECLARE_GLOBAL_LOCK (shared_connections);
+#ifdef DBUS_WIN
+#define _DBUS_N_GLOBAL_LOCKS (13)
+#else
#define _DBUS_N_GLOBAL_LOCKS (11)
+#endif
dbus_bool_t _dbus_threads_init_debug (void);
Index: dbus/dbus-mainloop.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-mainloop.c,v
retrieving revision 1.18
diff -u -B -b -r1.18 dbus-mainloop.c
--- dbus/dbus-mainloop.c 15 Jan 2005 07:15:38 -0000 1.18
+++ dbus/dbus-mainloop.c 3 Jul 2006 12:56:30 -0000
@@ -609,7 +609,7 @@
flags = dbus_watch_get_flags (wcb->watch);
- fds[n_fds].fd = dbus_watch_get_fd (wcb->watch);
+ fds[n_fds].fd = _dbus_re_encapsulate_socket(dbus_watch_get_fd (wcb->watch));
fds[n_fds].revents = 0;
fds[n_fds].events = 0;
if (flags & DBUS_WATCH_READABLE)
Index: dbus/dbus-server-unix.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-server-unix.c,v
retrieving revision 1.29
diff -u -B -b -r1.29 dbus-server-unix.c
--- dbus/dbus-server-unix.c 25 Oct 2005 15:57:13 -0000 1.29
+++ dbus/dbus-server-unix.c 3 Jul 2006 12:56:36 -0000
@@ -27,12 +27,16 @@
#include "dbus-connection-internal.h"
#include "dbus-string.h"
#include <sys/types.h>
+#ifdef DBUS_WIN
+#include "dbus-sockets-win.h"
+#else
#include <unistd.h>
+#endif
/**
- * @defgroup DBusServerUnix DBusServer implementations for UNIX
+ * @defgroup DBusServerUnix DBusServer implementations for UNIX and Winsock
* @ingroup DBusInternals
- * @brief Implementation details of DBusServer on UNIX
+ * @brief Implementation details of DBusServer on UNIX and Winsock
*
* @{
*/
@@ -102,7 +106,7 @@
transport = _dbus_transport_new_for_fd (client_fd, &server->guid_hex, NULL);
if (transport == NULL)
{
- close (client_fd);
+ _dbus_close (client_fd, NULL);
SERVER_UNLOCK (server);
return FALSE;
}
@@ -219,7 +223,7 @@
unix_server->watch = NULL;
}
- close (unix_server->fd);
+ _dbus_close (unix_server->fd, NULL);
unix_server->fd = -1;
if (unix_server->socket_name != NULL)
@@ -303,6 +307,8 @@
return (DBusServer*) unix_server;
}
+#ifndef DBUS_WIN
+
/**
* Creates a new server listening on the given Unix domain socket.
*
@@ -382,11 +388,94 @@
return NULL;
}
+#else /* ifndef DBUS_WIN */
+
+/**
+ * Creates a new server listening on the given Windows named pipe.
+ *
+ * @param path the path for the domain socket.
+ * @param abstract #TRUE to use abstract socket namespace
+ * @param error location to store reason for failure.
+ * @returns the new server, or #NULL on failure.
+ */
+DBusServer*
+_dbus_server_new_for_domain_socket (const char *path,
+ dbus_bool_t abstract,
+ DBusError *error)
+{
+ DBusServer *server;
+ DBusServerUnix *unix_server;
+ int listen_fd;
+ DBusString address;
+ char *path_copy;
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ if (!_dbus_string_init (&address))
+ {
+ _DBUS_SET_OOM (error);
+ return NULL;
+ }
+
+ if ((abstract &&
+ !_dbus_string_append (&address, "unix:abstract=")) ||
+ (!abstract &&
+ !_dbus_string_append (&address, "unix:path=")) ||
+ !_dbus_string_append (&address, path))
+ {
+ _DBUS_SET_OOM (error);
+ goto failed_0;
+ }
+
+ path_copy = _dbus_strdup (path);
+ if (path_copy == NULL)
+ {
+ _DBUS_SET_OOM (error);
+ goto failed_0;
+ }
+
+ listen_fd = _dbus_listen_unix_socket (path, abstract, error);
+
+ if (listen_fd < 0)
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ goto failed_1;
+ }
+
+ _dbus_fd_set_close_on_exec (listen_fd);
+ server = _dbus_server_new_for_fd (listen_fd, &address);
+ if (server == NULL)
+ {
+ _DBUS_SET_OOM (error);
+ goto failed_2;
+ }
+
+ unix_server = (DBusServerUnix*) server;
+ unix_server->socket_name = path_copy;
+
+ _dbus_string_free (&address);
+
+ return server;
+
+ failed_2:
+ _dbus_close (listen_fd, NULL);
+ failed_1:
+ dbus_free (path_copy);
+ failed_0:
+ _dbus_string_free (&address);
+
+ return NULL;
+}
+
+#endif /* ifndef DBUS_WIN */
+
+
/**
- * Creates a new server listening on the given hostname and port.
- * If the hostname is NULL, listens on localhost.
+ * Creates a new server listening on the given hostname and port. If
+ * the hostname is NULL, listens on localhost. If the hostname is an
+ * empty string, listens on any local host address.
*
- * @param host the hostname to listen on.
+ * @param host the hostname for the address to listen.
* @param port the port to listen on.
* @param error location to store reason for failure.
* @returns the new server, or #NULL on failure.
@@ -436,7 +525,7 @@
if (server == NULL)
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
- close (listen_fd);
+ _dbus_close (listen_fd, NULL);
_dbus_string_free (&address);
return NULL;
}
Index: dbus/dbus-spawn.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-spawn.h,v
retrieving revision 1.7
diff -u -B -b -r1.7 dbus-spawn.h
--- dbus/dbus-spawn.h 9 Sep 2004 10:20:17 -0000 1.7
+++ dbus/dbus-spawn.h 3 Jul 2006 12:56:37 -0000
@@ -37,6 +37,9 @@
dbus_bool_t _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
char **argv,
+#ifdef DBUS_WIN
+ char **envp,
+#endif
DBusSpawnChildSetupFunc child_setup,
void *user_data,
DBusError *error);
Index: dbus/dbus-string.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-string.c,v
retrieving revision 1.69
diff -u -B -b -r1.69 dbus-string.c
--- dbus/dbus-string.c 16 Feb 2006 00:43:41 -0000 1.69
+++ dbus/dbus-string.c 3 Jul 2006 12:56:38 -0000
@@ -35,6 +35,10 @@
/* for DBUS_VA_COPY */
#include "dbus-sysdeps.h"
+#ifdef DBUS_WIN
+#include <malloc.h>
+#endif
+
/**
* @defgroup DBusString string class
* @ingroup DBusInternals
@@ -1193,7 +1197,6 @@
va_list args)
{
int len;
- char c;
va_list args_copy;
DBUS_STRING_PREAMBLE (str);
@@ -1201,7 +1204,34 @@
DBUS_VA_COPY (args_copy, args);
/* Measure the message length without terminating nul */
+#ifndef DBUS_WIN
+ {
+ char c;
len = vsnprintf (&c, 1, format, args);
+ }
+#else
+ /* MSVCRT's vsnprintf semantics are a bit different */
+ /* The C library source in the Platform SDK indicates that this
+ * would work, but alas, it doesn't. At least not on Windows
+ * 2000. Presumably those sources correspond to the C library on
+ * some newer or even future Windows version.
+ *
+ len = _vsnprintf (NULL, _DBUS_INT_MAX, format, args);
+ */
+ {
+ char p[1024];
+ len = vsnprintf (p, sizeof(p)-1, format, args);
+ if (len == -1) // try again
+ {
+ char *p;
+ p = malloc (strlen(format)*3);
+ len = vsnprintf (p, sizeof(p)-1, format, args);
+ free(p);
+ }
+ if (len == -1)
+ return FALSE;
+ }
+#endif
if (!_dbus_string_lengthen (str, len))
{
Index: dbus/dbus-sysdeps-util.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-sysdeps-util.c,v
retrieving revision 1.6
diff -u -B -b -r1.6 dbus-sysdeps-util.c
--- dbus/dbus-sysdeps-util.c 24 Feb 2006 16:13:08 -0000 1.6
+++ dbus/dbus-sysdeps-util.c 3 Jul 2006 12:56:39 -0000
@@ -33,15 +33,20 @@
#include <stdlib.h>
#include <string.h>
#include <signal.h>
-#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
-#include <grp.h>
-#include <sys/socket.h>
+#ifdef DBUS_WIN
+#include "dbus-dirent-win.h"
+#include "dbus-sysdeps-win.h"
+#include <aclapi.h>
+#define F_OK 0
+#else
#include <dirent.h>
-#include <sys/un.h>
+#include <unistd.h>
+#include <grp.h>
+#endif
#ifndef O_BINARY
#define O_BINARY 0
@@ -65,6 +70,8 @@
int print_pid_fd,
DBusError *error)
{
+#ifndef DBUS_WIN
+
const char *s;
pid_t child_pid;
int dev_null_fd;
@@ -174,6 +181,14 @@
_dbus_assert_not_reached ("setsid() failed");
return TRUE;
+
+#else /* DBUS_WIN */
+
+ dbus_set_error_const (error, DBUS_ERROR_FAILED,
+ "Not implemented: _dbus_become_daemon\n");
+ return FALSE;
+
+#endif /* DBUS_WIN */
}
@@ -247,6 +262,8 @@
dbus_gid_t gid,
DBusError *error)
{
+#ifndef DBUS_WIN
+
/* setgroups() only works if we are a privileged process,
* so we don't return error on failure; the only possible
* failure is that we don't have perms to do it.
@@ -277,6 +294,15 @@
}
return TRUE;
+
+#else /* DBUS_WIN */
+
+ dbus_set_error_const (error, DBUS_ERROR_FAILED,
+ "Not implemented: _dbus_change_identity\n");
+
+ return FALSE;
+
+#endif /* DBUS_WIN */
}
/** Installs a UNIX signal handler
@@ -288,6 +314,7 @@
_dbus_set_signal_handler (int sig,
DBusSignalHandler handler)
{
+#ifndef DBUS_WIN
struct sigaction act;
sigset_t empty_mask;
@@ -296,6 +323,7 @@
act.sa_mask = empty_mask;
act.sa_flags = 0;
sigaction (sig, &act, 0);
+#endif
}
@@ -348,6 +376,7 @@
_dbus_user_at_console (const char *username,
DBusError *error)
{
+#ifndef DBUS_WIN
DBusString f;
dbus_bool_t result;
@@ -378,6 +407,80 @@
_dbus_string_free (&f);
return result;
+
+#else
+
+ dbus_bool_t retval = FALSE;
+ wchar_t *wusername;
+ DWORD sid_length;
+ PSID user_sid, console_user_sid;
+ HWINSTA winsta;
+
+ wusername = _dbus_win_utf8_to_utf16 (username, error);
+ if (!wusername)
+ return FALSE;
+
+ if (!_dbus_account_to_win_sid (wusername, &user_sid, error))
+ goto out0;
+
+ /* Now we have the SID for username. Get the SID of the
+ * user at the "console" (window station WinSta0)
+ */
+ if (!(winsta = OpenWindowStation ("WinSta0", FALSE, READ_CONTROL)))
+ {
+ _dbus_win_set_error_from_win_error (error, GetLastError ());
+ goto out2;
+ }
+
+ sid_length = 0;
+ GetUserObjectInformation (winsta, UOI_USER_SID,
+ NULL, 0, &sid_length);
+ if (sid_length == 0)
+ {
+ /* Nobody is logged on */
+ goto out2;
+ }
+
+ if (sid_length < 0 || sid_length > 1000)
+ {
+ dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid SID length");
+ goto out3;
+ }
+
+ console_user_sid = dbus_malloc (sid_length);
+ if (!console_user_sid)
+ {
+ _DBUS_SET_OOM (error);
+ goto out3;
+ }
+
+ if (!GetUserObjectInformation (winsta, UOI_USER_SID,
+ console_user_sid, sid_length, &sid_length))
+ {
+ _dbus_win_set_error_from_win_error (error, GetLastError ());
+ goto out4;
+ }
+
+ if (!IsValidSid (console_user_sid))
+ {
+ dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid SID");
+ goto out4;
+ }
+
+ retval = EqualSid (user_sid, console_user_sid);
+
+ out4:
+ dbus_free (console_user_sid);
+ out3:
+ CloseWindowStation (winsta);
+ out2:
+ dbus_free (user_sid);
+ out0:
+ dbus_free (wusername);
+
+ return retval;
+
+#endif
}
@@ -390,10 +493,26 @@
dbus_bool_t
_dbus_path_is_absolute (const DBusString *filename)
{
+#ifndef DBUS_WIN
if (_dbus_string_get_length (filename) > 0)
return _dbus_string_get_byte (filename, 0) == '/';
else
return FALSE;
+#else
+ if (_dbus_string_get_length (filename) > 0 &&
+ (_dbus_string_get_byte (filename, 0) == '/' ||
+ _dbus_string_get_byte (filename, 0) == '\\'))
+ return TRUE;
+
+ if (_dbus_string_get_length (filename) >= 3 &&
+ isalpha (_dbus_string_get_byte (filename, 0)) &&
+ _dbus_string_get_byte (filename, 1) == ':' &&
+ (_dbus_string_get_byte (filename, 2) == '/' ||
+ _dbus_string_get_byte (filename, 2) == '\\'))
+ return TRUE;
+
+ return FALSE;
+#endif
}
/**
@@ -410,12 +529,21 @@
DBusError *error)
{
const char *filename_c;
+#ifndef DBUS_WIN
struct stat sb;
+#else
+ WIN32_FILE_ATTRIBUTE_DATA wfad;
+ char *lastdot;
+ DWORD rc;
+ PSID owner_sid, group_sid;
+ PSECURITY_DESCRIPTOR sd;
+#endif
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
filename_c = _dbus_string_get_const_data (filename);
+#ifndef DBUS_WIN
if (stat (filename_c, &sb) < 0)
{
dbus_set_error (error, _dbus_error_from_errno (errno),
@@ -431,6 +559,66 @@
statbuf->atime = sb.st_atime;
statbuf->mtime = sb.st_mtime;
statbuf->ctime = sb.st_ctime;
+#else
+ if (!GetFileAttributesEx (filename_c, GetFileExInfoStandard, &wfad))
+ {
+ _dbus_win_set_error_from_win_error (error, GetLastError ());
+ return FALSE;
+ }
+
+ if (wfad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ statbuf->mode = _S_IFDIR;
+ else
+ statbuf->mode = _S_IFREG;
+
+ statbuf->mode |= _S_IREAD;
+ if (wfad.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
+ statbuf->mode |= _S_IWRITE;
+
+ lastdot = strrchr (filename_c, '.');
+ if (lastdot && stricmp (lastdot, ".exe") == 0)
+ statbuf->mode |= _S_IEXEC;
+
+ statbuf->mode |= (statbuf->mode & 0700) >> 3;
+ statbuf->mode |= (statbuf->mode & 0700) >> 6;
+
+ statbuf->nlink = 1;
+
+ sd = NULL;
+ rc = GetNamedSecurityInfo ((char *) filename_c, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION,
+ &owner_sid, &group_sid,
+ NULL, NULL,
+ &sd);
+ if (rc != ERROR_SUCCESS)
+ {
+ _dbus_win_set_error_from_win_error (error, rc);
+ if (sd != NULL)
+ LocalFree (sd);
+ return FALSE;
+ }
+
+ statbuf->uid = _dbus_win_sid_to_uid_t (owner_sid);
+ statbuf->gid = _dbus_win_sid_to_uid_t (group_sid);
+
+ LocalFree (sd);
+
+ statbuf->size = ((dbus_int64_t) wfad.nFileSizeHigh << 32) + wfad.nFileSizeLow;
+
+ statbuf->atime =
+ (((dbus_int64_t) wfad.ftLastAccessTime.dwHighDateTime << 32) +
+ wfad.ftLastAccessTime.dwLowDateTime) / 10000000 - DBUS_INT64_CONSTANT (116444736000000000);
+
+ statbuf->mtime =
+ (((dbus_int64_t) wfad.ftLastWriteTime.dwHighDateTime << 32) +
+ wfad.ftLastWriteTime.dwLowDateTime) / 10000000 - DBUS_INT64_CONSTANT (116444736000000000);
+
+ statbuf->ctime =
+ (((dbus_int64_t) wfad.ftCreationTime.dwHighDateTime << 32) +
+ wfad.ftCreationTime.dwLowDateTime) / 10000000 - DBUS_INT64_CONSTANT (116444736000000000);
+
+#endif
return TRUE;
}
@@ -514,7 +702,11 @@
ent = readdir (iter->d);
if (ent == NULL)
{
+#ifdef DBUS_WIN
+ if (errno != 0 && iter->d->finished != 1)
+#else
if (errno != 0)
+#endif
dbus_set_error (error,
_dbus_error_from_errno (errno),
"%s", _dbus_strerror (errno));
@@ -548,6 +740,7 @@
dbus_free (iter);
}
+#ifndef DBUS_WIN
static dbus_bool_t
fill_user_info_from_group (struct group *g,
DBusGroupInfo *info,
@@ -568,6 +761,7 @@
return TRUE;
}
+#endif /* DBUS_WIN */
static dbus_bool_t
fill_group_info (DBusGroupInfo *info,
@@ -585,6 +779,8 @@
else
group_c_str = NULL;
+#ifndef DBUS_WIN
+
/* For now assuming that the getgrnam() and getgrgid() flavors
* always correspond to the pwnam flavors, if not we have
* to add more configure checks.
@@ -642,6 +838,67 @@
}
}
#endif /* ! HAVE_GETPWNAM_R */
+#else /* DBUS_WIN */
+
+ if (group_c_str)
+ {
+ PSID group_sid;
+ wchar_t *wgroupname = _dbus_win_utf8_to_utf16 (group_c_str, error);
+
+ if (!wgroupname)
+ return FALSE;
+
+ if (!_dbus_account_to_win_sid (wgroupname, &group_sid, error))
+ {
+ dbus_free (wgroupname);
+ return FALSE;
+ }
+
+ info->gid = _dbus_win_sid_to_uid_t (group_sid);
+ info->groupname = _dbus_strdup (group_c_str);
+
+ dbus_free (group_sid);
+ dbus_free (wgroupname);
+
+ return TRUE;
+ }
+ else
+ {
+ dbus_bool_t retval = FALSE;
+ wchar_t *wname, *wdomain;
+ char *name, *domain;
+
+ info->gid = gid;
+
+ if (!_dbus_win_sid_to_name_and_domain (gid, &wname, &wdomain, error))
+ return FALSE;
+
+ name = _dbus_win_utf16_to_utf8 (wname, error);
+ if (!name)
+ goto out0;
+
+ domain = _dbus_win_utf16_to_utf8 (wdomain, error);
+ if (!domain)
+ goto out1;
+
+ info->groupname = dbus_malloc (strlen (domain) + 1 + strlen (name) + 1);
+
+ strcpy (info->groupname, domain);
+ strcat (info->groupname, "\\");
+ strcat (info->groupname, name);
+
+ retval = TRUE;
+
+ dbus_free (domain);
+ out1:
+ dbus_free (name);
+ out0:
+ dbus_free (wname);
+ dbus_free (wdomain);
+
+ return retval;
+ }
+#endif /* DBUS_WIN */
}
/**
@@ -708,6 +965,8 @@
if (sep == 0)
return _dbus_string_append (dirname, "."); /* empty string passed in */
+#ifndef DBUS_WIN
+
while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/')
--sep;
@@ -733,6 +992,52 @@
else
return _dbus_string_copy_len (filename, 0, sep - 0,
dirname, _dbus_string_get_length (dirname));
+#else
+
+ while (sep > 0 &&
+ (_dbus_string_get_byte (filename, sep - 1) == '/' ||
+ _dbus_string_get_byte (filename, sep - 1) == '\\'))
+ --sep;
+
+ _dbus_assert (sep >= 0);
+
+ if (sep == 0 ||
+ (sep == 2 &&
+ _dbus_string_get_byte (filename, 1) == ':' &&
+ isalpha (_dbus_string_get_byte (filename, 0))))
+ return _dbus_string_copy_len (filename, 0, sep + 1,
+ dirname, _dbus_string_get_length (dirname));
+
+ {
+ int sep1, sep2;
+ _dbus_string_find_byte_backward (filename, sep, '/', &sep1);
+ _dbus_string_find_byte_backward (filename, sep, '\\', &sep2);
+
+ sep = MAX (sep1, sep2);
+ }
+ if (sep < 0)
+ return _dbus_string_append (dirname, ".");
+
+ while (sep > 0 &&
+ (_dbus_string_get_byte (filename, sep - 1) == '/' ||
+ _dbus_string_get_byte (filename, sep - 1) == '\\'))
+ --sep;
+
+ _dbus_assert (sep >= 0);
+
+ if ((sep == 0 ||
+ (sep == 2 &&
+ _dbus_string_get_byte (filename, 1) == ':' &&
+ isalpha (_dbus_string_get_byte (filename, 0))))
+ &&
+ (_dbus_string_get_byte (filename, sep) == '/' ||
+ _dbus_string_get_byte (filename, sep) == '\\'))
+ return _dbus_string_copy_len (filename, 0, sep + 1,
+ dirname, _dbus_string_get_length (dirname));
+ else
+ return _dbus_string_copy_len (filename, 0, sep - 0,
+ dirname, _dbus_string_get_length (dirname));
+#endif
}
/** @} */ /* DBusString stuff */
@@ -812,6 +1117,26 @@
check_dirname ("///", "/");
check_dirname ("", ".");
+#ifdef DBUS_WIN
+ check_dirname ("foo\\bar", "foo");
+ check_dirname ("foo\\\\bar", "foo");
+ check_dirname ("foo/\\/bar", "foo");
+ check_dirname ("foo\\bar/", "foo");
+ check_dirname ("foo//bar\\", "foo");
+ check_dirname ("foo\\bar/", "foo");
+ check_dirname ("foo/bar\\\\", "foo");
+ check_dirname ("\\foo", "\\");
+ check_dirname ("\\\\foo", "\\");
+ check_dirname ("\\", "\\");
+ check_dirname ("\\\\", "\\");
+ check_dirname ("\\/", "\\");
+ check_dirname ("/\\/", "/");
+ check_dirname ("a:\\foo\\bar", "a:\\foo");
+ check_dirname ("a:\\foo", "a:\\");
+ check_dirname ("a:/foo", "a:/");
+ check_dirname ("a:\\", "a:\\");
+ check_dirname ("a:/", "a:/");
+#endif
_dbus_string_init_const (&str, "3.5");
if (!_dbus_string_parse_double (&str,
@@ -831,6 +1156,7 @@
exit (1);
}
+#ifndef DBUS_WIN
_dbus_string_init_const (&str, "0xff");
if (!_dbus_string_parse_double (&str,
0, &val, &pos))
@@ -848,12 +1174,23 @@
_dbus_warn ("_dbus_string_parse_double of \"0xff\" returned wrong position %d", pos);
exit (1);
}
+#endif
check_path_absolute ("/", TRUE);
check_path_absolute ("/foo", TRUE);
check_path_absolute ("", FALSE);
check_path_absolute ("foo", FALSE);
check_path_absolute ("foo/bar", FALSE);
+#ifdef DBUS_WIN
+ check_path_absolute ("\\", TRUE);
+ check_path_absolute ("\\foo", TRUE);
+ check_path_absolute ("", FALSE);
+ check_path_absolute ("foo\\bar", FALSE);
+ check_path_absolute ("a:\\", TRUE);
+ check_path_absolute ("a:\\foo", TRUE);
+ check_path_absolute ("a:", FALSE);
+ check_path_absolute ("a:foo\\bar", FALSE);
+#endif
return TRUE;
}
Index: dbus/dbus-sysdeps.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-sysdeps.c,v
retrieving revision 1.102
diff -u -B -b -r1.102 dbus-sysdeps.c
--- dbus/dbus-sysdeps.c 30 May 2006 15:34:10 -0000 1.102
+++ dbus/dbus-sysdeps.c 3 Jul 2006 12:56:39 -0000
@@ -3,6 +3,7 @@
*
* Copyright (C) 2002, 2003 Red Hat, Inc.
* Copyright (C) 2003 CodeFactory AB
+ * Copyright (C) 2005 Novell, Inc.
*
* Licensed under the Academic Free License version 2.1
*
@@ -31,22 +32,31 @@
#include <stdlib.h>
#include <string.h>
#include <signal.h>
-#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
+
+#ifdef DBUS_WIN
+#include "dbus-sysdeps-win.h"
+#include "dbus-dirent-win.h"
+#include "dbus-hash.h"
+#include "dbus-sockets-win.h"
+#else
+#include <unistd.h>
#include <sys/socket.h>
#include <dirent.h>
#include <sys/un.h>
#include <pwd.h>
-#include <time.h>
-#include <locale.h>
#include <sys/time.h>
-#include <sys/stat.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <netdb.h>
#include <grp.h>
+#endif
+
+#include <time.h>
+#include <locale.h>
+#include <sys/stat.h>
#ifdef HAVE_WRITEV
#include <sys/uio.h>
@@ -69,6 +79,14 @@
#define socklen_t int
#endif
+#ifndef DBUS_WIN
+#define _dbus_decapsulate_quick(i) (i)
+#define DBUS_SOCKET_IS_INVALID(s) ((s) < 0)
+#define DBUS_SOCKET_API_RETURNS_ERROR(n) ((n) < 0)
+#define DBUS_SOCKET_SET_ERRNO() /* empty */
+#define DBUS_CLOSE_SOCKET(s) close(s)
+#endif
+
/**
* @addtogroup DBusInternalsUtils
* @{
@@ -86,6 +104,10 @@
if (s && *s)
_dbus_print_backtrace ();
#endif
+#if defined (DBUS_WIN) && defined (__GNUC__)
+ if (IsDebuggerPresent ())
+ __asm__ __volatile__ ("int $03");
+#endif
abort ();
_exit (1); /* in case someone manages to ignore SIGABRT */
}
@@ -123,11 +145,18 @@
* will get upset about.
*/
+#ifdef DBUS_WIN
+ putenv_value = malloc (len + 2);
+#else
putenv_value = malloc (len + 1);
+#endif
if (putenv_value == NULL)
return FALSE;
strcpy (putenv_value, varname);
+#ifdef DBUS_WIN
+ strcat (putenv_value, "=");
+#endif
return (putenv (putenv_value) == 0);
#endif
@@ -194,6 +223,9 @@
DBusString *buffer,
int count)
{
+#ifdef DBUS_WIN
+ return _dbus_read_win (fd, buffer, count);
+#else
int bytes_read;
int start;
char *data;
@@ -237,6 +269,7 @@
return bytes_read;
}
+#endif
}
/**
@@ -255,6 +288,9 @@
int start,
int len)
{
+#ifdef DBUS_WIN
+ return _dbus_write_win (fd, buffer, start, len);
+#else
const char *data;
int bytes_written;
@@ -273,6 +309,7 @@
#endif
return bytes_written;
+#endif
}
/**
@@ -310,6 +347,10 @@
_dbus_assert (len1 >= 0);
_dbus_assert (len2 >= 0);
+#ifdef DBUS_WIN
+ return _dbus_write_two_win(fd, buffer1, start1, len1, buffer2, start2, len2);
+#else
+
#ifdef HAVE_WRITEV
{
struct iovec vectors[2];
@@ -361,6 +402,8 @@
return ret1;
}
#endif /* !HAVE_WRITEV */
+
+#endif
}
#define _DBUS_MAX_SUN_PATH_LENGTH 99
@@ -383,6 +426,10 @@
* given path. The connection fd is returned, and is set up as
* nonblocking.
*
+ * On Windows there are no UNIX domain sockets. Instead, connects to a
+ * localhost-bound TCP socket, whose port number is stored in a file
+ * at the given path.
+ *
* Uses abstract sockets instead of filesystem-linked sockets if
* requested (it's possible only on Linux; see "man 7 unix" on Linux).
* On non-Linux abstract socket usage always fails.
@@ -397,6 +444,10 @@
dbus_bool_t abstract,
DBusError *error)
{
+#ifdef DBUS_WIN
+ return _dbus_connect_unix_socket_win(path, abstract, error);
+#else
+
int fd;
size_t path_len;
struct sockaddr_un addr;
@@ -482,6 +533,7 @@
}
return fd;
+#endif
}
/**
@@ -504,6 +556,10 @@
dbus_bool_t abstract,
DBusError *error)
{
+#ifdef DBUS_WIN
+ return _dbus_listen_unix_socket_win(path, abstract,error);
+#else
+
int listen_fd;
struct sockaddr_un addr;
size_t path_len;
@@ -617,6 +673,7 @@
path);
return listen_fd;
+#endif
}
/**
@@ -624,7 +681,7 @@
* and port. The connection fd is returned, and is set up as
* nonblocking.
*
- * @param host the host name to connect to
+ * @param host the host name to connect to, NULL for loopback
* @param port the prot to connect to
* @param error return location for error code
* @returns connection file descriptor or -1 on error
@@ -638,13 +695,21 @@
struct sockaddr_in addr;
struct hostent *he;
struct in_addr *haddr;
+#ifdef DBUS_WIN
+ struct in_addr ina;
+#endif
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
+#ifdef DBUS_WIN
+ _dbus_win_startup_winsock ();
+#endif
+
fd = socket (AF_INET, SOCK_STREAM, 0);
- if (fd < 0)
+ if (DBUS_SOCKET_IS_INVALID (fd))
{
+ DBUS_SOCKET_SET_ERRNO ();
dbus_set_error (error,
_dbus_error_from_errno (errno),
"Failed to create socket: %s",
@@ -654,16 +719,23 @@
}
if (host == NULL)
+ {
host = "localhost";
+#ifdef DBUS_WIN
+ ina.s_addr = htonl (INADDR_LOOPBACK);
+ haddr = &ina;
+#endif
+ }
he = gethostbyname (host);
if (he == NULL)
{
+ DBUS_SOCKET_SET_ERRNO ();
dbus_set_error (error,
_dbus_error_from_errno (errno),
"Failed to lookup hostname: %s",
host);
- close (fd);
+ DBUS_CLOSE_SOCKET (fd);
return -1;
}
@@ -674,22 +747,26 @@
addr.sin_family = AF_INET;
addr.sin_port = htons (port);
- if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0)
+ if (DBUS_SOCKET_API_RETURNS_ERROR
+ (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0))
{
+ DBUS_SOCKET_SET_ERRNO ();
dbus_set_error (error,
_dbus_error_from_errno (errno),
"Failed to connect to socket %s:%d %s",
host, port, _dbus_strerror (errno));
- close (fd);
+ DBUS_CLOSE_SOCKET (fd);
fd = -1;
return -1;
}
+ fd = _dbus_encapsulate_socket (fd);
+
if (!_dbus_set_fd_nonblocking (fd, error))
{
- close (fd);
+ _dbus_close (fd, NULL);
fd = -1;
return -1;
@@ -699,12 +776,12 @@
}
/**
- * Creates a socket and binds it to the given path,
+ * Creates a socket and binds it to the given port,
* then listens on the socket. The socket is
* set to be nonblocking.
*
- * @param host the host name to listen on
- * @param port the prot to listen on
+ * @param host the interface to listen on, NULL for loopback, empty for any
+ * @param port the port to listen on
* @param error return location for errors
* @returns the listening file descriptor or -1 on error
*/
@@ -717,31 +794,58 @@
struct sockaddr_in addr;
struct hostent *he;
struct in_addr *haddr;
+#ifdef DBUS_WIN
+ struct in_addr ina;
+#endif
+
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
+#ifdef DBUS_WIN
+ _dbus_win_startup_winsock ();
+#endif
+
listen_fd = socket (AF_INET, SOCK_STREAM, 0);
- if (listen_fd < 0)
+ if (DBUS_SOCKET_IS_INVALID (listen_fd))
{
+ DBUS_SOCKET_SET_ERRNO ();
dbus_set_error (error, _dbus_error_from_errno (errno),
"Failed to create socket \"%s:%d\": %s",
host, port, _dbus_strerror (errno));
return -1;
}
-
+#ifdef DBUS_WIN
+ if (host == NULL)
+ {
+ host = "localhost";
+ ina.s_addr = htonl (INADDR_LOOPBACK);
+ haddr = &ina;
+ }
+ else if (!host[0])
+ {
+ ina.s_addr = htonl (INADDR_ANY);
+ haddr = &ina;
+ }
+ else
+ {
+#endif
he = gethostbyname (host);
if (he == NULL)
{
+ DBUS_SOCKET_SET_ERRNO ();
dbus_set_error (error,
_dbus_error_from_errno (errno),
"Failed to lookup hostname: %s",
host);
- close (listen_fd);
+ DBUS_CLOSE_SOCKET (listen_fd);
return -1;
}
haddr = ((struct in_addr *) (he->h_addr_list)[0]);
+#ifdef DBUS_WIN
+ }
+#endif
_DBUS_ZERO (addr);
memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
@@ -750,25 +854,29 @@
if (bind (listen_fd, (struct sockaddr*) &addr, sizeof (struct sockaddr)))
{
+ DBUS_SOCKET_SET_ERRNO ();
dbus_set_error (error, _dbus_error_from_errno (errno),
"Failed to bind socket \"%s:%d\": %s",
host, port, _dbus_strerror (errno));
- close (listen_fd);
+ DBUS_CLOSE_SOCKET (listen_fd);
return -1;
}
- if (listen (listen_fd, 30 /* backlog */) < 0)
+ if (DBUS_SOCKET_API_RETURNS_ERROR (listen (listen_fd, 30 /* backlog */)))
{
+ DBUS_SOCKET_SET_ERRNO ();
dbus_set_error (error, _dbus_error_from_errno (errno),
"Failed to listen on socket \"%s:%d\": %s",
host, port, _dbus_strerror (errno));
- close (listen_fd);
+ DBUS_CLOSE_SOCKET (listen_fd);
return -1;
}
+ listen_fd = _dbus_encapsulate_socket (listen_fd);
+
if (!_dbus_set_fd_nonblocking (listen_fd, error))
{
- close (listen_fd);
+ _dbus_close (listen_fd, NULL);
return -1;
}
@@ -779,6 +887,33 @@
write_credentials_byte (int server_fd,
DBusError *error)
{
+#ifdef DBUS_WIN
+ /* FIXME: for the session bus credentials shouldn't matter (?), but
+ * for the system bus they are presumably essential. A rough outline
+ * of a way to implement the credential transfer would be this:
+ *
+ * client waits to *read* a byte.
+ *
+ * server creates a named pipe with a random name, sends a byte
+ * contining its length, and its name.
+ *
+ * client reads the name, connects to it (using Win32 API).
+ *
+ * server waits for connection to the named pipe, then calls
+ * ImpersonateNamedPipeClient(), notes its now-current credentials,
+ * calls RevertToSelf(), closes its handles to the named pipe, and
+ * is done. (Maybe there is some other way to get the SID of a named
+ * pipe client without having to use impersonation?)
+ *
+ * client closes its handles and is done.
+ *
+ */
+
+ return TRUE;
+
+#else
+
+
int bytes_written;
char buf[1] = { '\0' };
#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
@@ -838,6 +973,8 @@
_dbus_verbose ("wrote credentials byte\n");
return TRUE;
}
+
+#endif
}
/**
@@ -863,6 +1000,8 @@
DBusCredentials *credentials,
DBusError *error)
{
+#ifndef DBUS_WIN
+
struct msghdr msg;
struct iovec iov;
char buf;
@@ -1002,6 +1141,15 @@
credentials->gid);
return TRUE;
+
+#else
+
+ /* FIXME bogus testing credentials */
+ _dbus_credentials_from_current_process (credentials);
+
+ return TRUE;
+
+#endif
}
/**
@@ -1049,16 +1197,23 @@
addrlen = sizeof (addr);
+#ifndef DBUS_WIN
retry:
+#endif
client_fd = accept (listen_fd, &addr, &addrlen);
- if (client_fd < 0)
+ if (DBUS_SOCKET_IS_INVALID (client_fd))
{
+ DBUS_SOCKET_SET_ERRNO ();
+#ifndef DBUS_WIN
if (errno == EINTR)
goto retry;
+#else
+ client_fd = -1;
+#endif
}
- return client_fd;
+ return _dbus_encapsulate_socket (client_fd);
}
/** @} */
@@ -1238,6 +1393,7 @@
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
+#ifndef DBUS_WIN
directory = _dbus_string_get_const_data (dir);
if (stat (directory, &sb) < 0)
@@ -1255,7 +1411,7 @@
"%s directory is not private to the user", directory);
return FALSE;
}
-
+#endif
return TRUE;
}
@@ -1339,6 +1495,10 @@
ascii_strtod (const char *nptr,
char **endptr)
{
+ /* FIXME: The Win32 C library's strtod() doesn't handle hex.
+ * Presumably many Unixes don't either.
+ */
+
char *fail_pos;
double val;
struct lconv *locale_data;
@@ -1507,6 +1667,9 @@
* @addtogroup DBusInternalsUtils
* @{
*/
+
+#ifndef DBUS_WIN
+
static dbus_bool_t
fill_user_info_from_passwd (struct passwd *p,
DBusUserInfo *info,
@@ -1529,6 +1692,7 @@
return TRUE;
}
+#endif
static dbus_bool_t
fill_user_info (DBusUserInfo *info,
@@ -1554,6 +1718,7 @@
else
username_c = NULL;
+#ifndef DBUS_WIN
/* For now assuming that the getpwnam() and getpwuid() flavors
* are always symmetrical, if not we have to add more configure
* checks
@@ -1704,8 +1869,36 @@
failed:
_DBUS_ASSERT_ERROR_IS_SET (error);
return FALSE;
+
+#else /* DBUS_WIN */
+
+ if (uid != DBUS_UID_UNSET)
+ {
+ if (!fill_win_user_info_from_uid (uid, info, error)) {
+ _dbus_verbose("%s after fill_win_user_info_from_uid\n",__FUNCTION__);
+ return FALSE;
+ }
+ }
+ else
+ {
+ wchar_t *wname = _dbus_win_utf8_to_utf16 (username_c, error);
+
+ if (!wname)
+ return FALSE;
+
+ if (!fill_win_user_info_from_name (wname, info, error))
+ {
+ dbus_free (wname);
+ return FALSE;
+ }
+ dbus_free (wname);
+ }
+
+ return TRUE;
+#endif /* DBUS_WIN */
}
+
/**
* Gets user info for the given username.
*
@@ -1753,7 +1946,7 @@
dbus_free (info->homedir);
}
-/**
+ /**
* Frees the members of info (but not info itself).
*
* @param info the group info
@@ -1786,6 +1979,7 @@
void
_dbus_credentials_from_current_process (DBusCredentials *credentials)
{
+#ifndef DBUS_WIN
/* The POSIX spec certainly doesn't promise this, but
* we need these assertions to fail as soon as we're wrong about
* it so we can do the porting fixups
@@ -1793,10 +1987,11 @@
_dbus_assert (sizeof (pid_t) <= sizeof (credentials->pid));
_dbus_assert (sizeof (uid_t) <= sizeof (credentials->uid));
_dbus_assert (sizeof (gid_t) <= sizeof (credentials->gid));
+#endif
- credentials->pid = getpid ();
- credentials->uid = getuid ();
- credentials->gid = getgid ();
+ credentials->pid = _dbus_getpid ();
+ credentials->uid = _dbus_getuid ();
+ credentials->gid = _dbus_getgid ();
}
/**
@@ -1830,7 +2025,11 @@
unsigned long
_dbus_getpid (void)
{
+#ifndef DBUS_WIN
return getpid ();
+#else
+ return GetCurrentProcessId ();
+#endif
}
/** Gets our UID
@@ -1839,7 +2038,11 @@
dbus_uid_t
_dbus_getuid (void)
{
+#ifdef DBUS_WIN
+ return _dbus_getuid_win ();
+#else
return getuid ();
+#endif
}
#ifdef DBUS_BUILD_TESTS
@@ -1849,7 +2052,11 @@
dbus_gid_t
_dbus_getgid (void)
{
+#ifdef DBUS_WIN
+ return _dbus_getgid_win ();
+#else
return getgid ();
+#endif
}
#endif
@@ -1931,6 +2138,9 @@
int n_fds,
int timeout_milliseconds)
{
+#ifdef DBUS_WIN
+ return _dbus_poll_win (fds, n_fds, timeout_milliseconds);
+#else
#ifdef HAVE_POLL
/* This big thing is a constant expression and should get optimized
* out of existence. So it's more robust than a configure check at
@@ -2016,8 +2226,10 @@
return ready;
#endif
+#endif /* DBUS_WIN */
}
+
/** nanoseconds in a second */
#define NANOSECONDS_PER_SECOND 1000000000
/** microseconds in a second */
@@ -2036,6 +2248,7 @@
void
_dbus_sleep_milliseconds (int milliseconds)
{
+#ifndef DBUS_WIN
#ifdef HAVE_NANOSLEEP
struct timespec req;
struct timespec rem;
@@ -2052,18 +2265,22 @@
#else /* ! HAVE_USLEEP */
sleep (MAX (milliseconds / 1000, 1));
#endif
+#else /* DBUS_WIN */
+ Sleep (milliseconds);
+#endif /* !DBUS_WIN */
}
/**
* Get current time, as in gettimeofday().
*
* @param tv_sec return location for number of seconds
- * @param tv_usec return location for number of microseconds (thousandths)
+ * @param tv_usec return location for number of microseconds
*/
void
_dbus_get_current_time (long *tv_sec,
long *tv_usec)
{
+#ifndef DBUS_WIN
struct timeval t;
gettimeofday (&t, NULL);
@@ -2072,6 +2289,24 @@
*tv_sec = t.tv_sec;
if (tv_usec)
*tv_usec = t.tv_usec;
+#else
+ FILETIME ft;
+ dbus_uint64_t *time64 = (dbus_uint64_t *) &ft;
+
+ GetSystemTimeAsFileTime (&ft);
+
+ /* Convert from 100s of nanoseconds since 1601-01-01
+ * to Unix epoch. Yes, this is Y2038 unsafe.
+ */
+ *time64 -= DBUS_INT64_CONSTANT (116444736000000000);
+ *time64 /= 10;
+
+ if (tv_sec)
+ *tv_sec = *time64 / 1000000;
+
+ if (tv_usec)
+ *tv_usec = *time64 % 1000000;
+#endif
}
/**
@@ -2099,7 +2334,7 @@
filename_c = _dbus_string_get_const_data (filename);
- /* O_BINARY useful on Cygwin */
+ /* O_BINARY useful on Cygwin and Win32 */
fd = open (filename_c, O_RDONLY | O_BINARY);
if (fd < 0)
{
@@ -2139,10 +2374,11 @@
if (sb.st_size > 0 && S_ISREG (sb.st_mode))
{
int bytes_read;
+ const int encapsulated_fd = _dbus_encapsulate_fd (fd);
while (total < (int) sb.st_size)
{
- bytes_read = _dbus_read (fd, str,
+ bytes_read = _dbus_read (encapsulated_fd, str,
sb.st_size - total);
if (bytes_read <= 0)
{
@@ -2154,7 +2390,7 @@
_dbus_verbose ("read() failed: %s",
_dbus_strerror (errno));
- close (fd);
+ _dbus_close (encapsulated_fd, NULL);
_dbus_string_set_length (str, orig_len);
return FALSE;
}
@@ -2162,7 +2398,7 @@
total += bytes_read;
}
- close (fd);
+ _dbus_close (encapsulated_fd, NULL);
return TRUE;
}
else if (sb.st_size != 0)
@@ -2251,6 +2487,8 @@
goto out;
}
+ fd = _dbus_encapsulate_fd (fd);
+
need_unlink = TRUE;
total = 0;
@@ -2275,7 +2513,7 @@
total += bytes_written;
}
- if (close (fd) < 0)
+ if (_dbus_close (fd, NULL) < 0)
{
dbus_set_error (error, _dbus_error_from_errno (errno),
"Could not close file %s: %s",
@@ -2286,7 +2524,11 @@
fd = -1;
- if (rename (tmp_filename_c, filename_c) < 0)
+ if (
+#ifdef DBUS_WIN
+ (unlink (filename_c) == -1 && errno != ENOENT) ||
+#endif
+ rename (tmp_filename_c, filename_c) < 0)
{
dbus_set_error (error, _dbus_error_from_errno (errno),
"Could not rename %s to %s: %s",
@@ -2306,7 +2548,7 @@
*/
if (fd >= 0)
- close (fd);
+ _dbus_close (fd, NULL);
if (need_unlink && unlink (tmp_filename_c) < 0)
_dbus_verbose ("Failed to unlink temp file %s: %s\n",
@@ -2444,6 +2686,7 @@
_dbus_string_get_length (next_component) == 0)
return TRUE;
+#ifndef DBUS_WIN
dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
_dbus_string_get_length (dir) - 1);
@@ -2458,6 +2701,25 @@
if (!_dbus_string_append_byte (dir, '/'))
return FALSE;
}
+#else
+ dir_ends_in_slash =
+ ('/' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1) ||
+ '\\' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1));
+
+ file_starts_with_slash =
+ ('/' == _dbus_string_get_byte (next_component, 0) ||
+ '\\' == _dbus_string_get_byte (next_component, 0));
+
+ if (dir_ends_in_slash && file_starts_with_slash)
+ {
+ _dbus_string_shorten (dir, 1);
+ }
+ else if (!(dir_ends_in_slash || file_starts_with_slash))
+ {
+ if (!_dbus_string_append_byte (dir, '\\'))
+ return FALSE;
+ }
+#endif
return _dbus_string_copy (next_component, 0, dir,
_dbus_string_get_length (dir));
@@ -2565,14 +2828,18 @@
old_len = _dbus_string_get_length (str);
fd = -1;
+#ifndef DBUS_WIN
/* note, urandom on linux will fall back to pseudorandom */
fd = open ("/dev/urandom", O_RDONLY);
+#endif
+
if (fd < 0)
return pseudorandom_generate_random_bytes (str, n_bytes);
+#ifndef DBUS_WIN
if (_dbus_read (fd, str, n_bytes) != n_bytes)
{
- close (fd);
+ _dbus_close (fd, NULL);
_dbus_string_set_length (str, old_len);
return pseudorandom_generate_random_bytes (str, n_bytes);
}
@@ -2583,6 +2850,10 @@
close (fd);
return TRUE;
+#else
+ _dbus_assert_not_reached ("_dbus_generate_random_bytes fails");
+ return FALSE;
+#endif
}
/**
@@ -2632,6 +2903,7 @@
const char*
_dbus_strerror (int error_number)
{
+#ifndef DBUS_WIN
const char *msg;
msg = strerror (error_number);
@@ -2639,6 +2911,9 @@
msg = "unknown";
return msg;
+#else
+ return _dbus_strerror_win(error_number);
+#endif
}
/**
@@ -2647,7 +2922,9 @@
void
_dbus_disable_sigpipe (void)
{
+#ifndef DBUS_WIN
signal (SIGPIPE, SIG_IGN);
+#endif
}
/**
@@ -2660,6 +2937,9 @@
void
_dbus_fd_set_close_on_exec (int fd)
{
+#ifdef DBUS_WIN
+ _dbus_fd_set_close_on_exec_win(fd);
+#else
int val;
val = fcntl (fd, F_GETFD, 0);
@@ -2670,15 +2950,16 @@
val |= FD_CLOEXEC;
fcntl (fd, F_SETFD, val);
+#endif
}
/**
- * Converts a UNIX errno into a #DBusError name.
+ * Converts a UNIX errno or a Winsock error code into a #DBusError name.
*
* @todo should cover more errnos, specifically those
* from open().
*
- * @param error_number the errno.
+ * @param error_number the errno or Winsock error code.
* @returns an error name
*/
const char*
@@ -2792,6 +3073,10 @@
_dbus_close (int fd,
DBusError *error)
{
+#ifdef DBUS_WIN
+ return _dbus_close_win (fd, error);
+#else
+
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
again:
@@ -2806,6 +3091,7 @@
}
return TRUE;
+#endif
}
/**
@@ -2819,6 +3105,9 @@
_dbus_set_fd_nonblocking (int fd,
DBusError *error)
{
+#ifdef DBUS_WIN
+ return _dbus_set_fd_nonblocking_win(fd, error);
+#else
int val;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
@@ -2846,6 +3135,7 @@
}
return TRUE;
+#endif
}
#if !defined (DBUS_DISABLE_ASSERT) || defined(DBUS_BUILD_TESTS)
@@ -2893,8 +3183,8 @@
_dbus_parse_uid (const DBusString *uid_str,
dbus_uid_t *uid)
{
+ dbus_uid_t val;
int end;
- long val;
if (_dbus_string_get_length (uid_str) == 0)
{
@@ -2904,8 +3194,7 @@
val = -1;
end = 0;
- if (!_dbus_string_parse_int (uid_str, 0, &val,
- &end))
+ if (!_dbus_string_parse_int (uid_str, 0, &val, &end))
{
_dbus_verbose ("could not parse string as a UID\n");
return FALSE;
@@ -2975,6 +3264,9 @@
*fd1, *fd2);
return TRUE;
+
+#elif defined (DBUS_WIN)
+ return _dbus_full_duplex_pipe_win (fd1, fd2, blocking, error);
#else
_dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
dbus_set_error (error, DBUS_ERROR_FAILED,
Index: dbus/dbus-sysdeps.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-sysdeps.h,v
retrieving revision 1.49
diff -u -B -b -r1.49 dbus-sysdeps.h
--- dbus/dbus-sysdeps.h 8 Jul 2005 14:36:22 -0000 1.49
+++ dbus/dbus-sysdeps.h 3 Jul 2006 12:56:40 -0000
@@ -99,6 +99,22 @@
#define DBUS_UID_FORMAT "%lu"
#define DBUS_GID_FORMAT "%lu"
+#ifdef DBUS_WIN
+int _dbus_encapsulate_socket (int socket);
+int _dbus_re_encapsulate_socket (int socket);
+int _dbus_encapsulate_fd (int fd);
+int _dbus_re_encapsulate_fd (int fd);
+int _dbus_decapsulate (int fd);
+#else
+#define _dbus_encapsulate_socket(socket) (socket)
+#define _dbus_re_encapsulate_socket(socket) (socket)
+#define _dbus_encapsulate_fd(fd) (fd)
+#define _dbus_re_encapsulate_fd(fd) (fd)
+#define _dbus_decapsulate(fd) (fd)
+#endif
+
+
+
/**
* Struct representing socket credentials
*/
Index: dbus/dbus-test.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-test.c,v
retrieving revision 1.42
diff -u -B -b -r1.42 dbus-test.c
--- dbus/dbus-test.c 24 Feb 2005 16:03:56 -0000 1.42
+++ dbus/dbus-test.c 3 Jul 2006 12:56:40 -0000
@@ -154,7 +154,9 @@
run_test ("hash", specific_test, _dbus_hash_test);
+#ifndef DBUS_WIN
run_data_test ("spawn", specific_test, _dbus_spawn_test, test_data_dir);
+#endif
run_data_test ("userdb", specific_test, _dbus_userdb_test, test_data_dir);
Index: dbus/dbus-threads.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-threads.c,v
retrieving revision 1.23
diff -u -B -b -r1.23 dbus-threads.c
--- dbus/dbus-threads.c 26 Feb 2005 06:37:46 -0000 1.23
+++ dbus/dbus-threads.c 3 Jul 2006 12:56:40 -0000
@@ -222,6 +222,10 @@
DBusMutex **global_locks[] = {
#define LOCK_ADDR(name) (& _dbus_lock_##name)
+#ifdef DBUS_WIN
+ LOCK_ADDR (win32_fds),
+ LOCK_ADDR (sid_atom_cache),
+#endif
LOCK_ADDR (list),
LOCK_ADDR (connection_slots),
LOCK_ADDR (pending_call_slots),
Index: dbus/dbus-transport-unix.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-transport-unix.c,v
retrieving revision 1.49
diff -u -B -b -r1.49 dbus-transport-unix.c
--- dbus/dbus-transport-unix.c 30 May 2006 15:34:10 -0000 1.49
+++ dbus/dbus-transport-unix.c 3 Jul 2006 12:56:40 -0000
@@ -26,6 +26,9 @@
#include "dbus-transport-unix.h"
#include "dbus-transport-protected.h"
#include "dbus-watch.h"
+#ifdef DBUS_WIN
+#include "dbus-sockets-win.h"
+#endif
/**
Index: dbus/dbus-userdb.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-userdb.c,v
retrieving revision 1.19
diff -u -B -b -r1.19 dbus-userdb.c
Index: dbus/dbus-watch.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-watch.c,v
retrieving revision 1.18
diff -u -B -b -r1.18 dbus-watch.c
--- dbus/dbus-watch.c 26 Nov 2004 01:53:13 -0000 1.18
+++ dbus/dbus-watch.c 3 Jul 2006 12:56:41 -0000
@@ -486,7 +486,10 @@
int
dbus_watch_get_fd (DBusWatch *watch)
{
- return watch->fd;
+ if (watch->fd == -1)
+ return -1;
+ else
+ return _dbus_decapsulate (watch->fd);
}
/**
Index: test/spawn-test.c
===================================================================
RCS file: /cvs/dbus/dbus/test/spawn-test.c,v
retrieving revision 1.3
diff -u -B -b -r1.3 spawn-test.c
--- test/spawn-test.c 5 Apr 2003 00:37:17 -0000 1.3
+++ test/spawn-test.c 3 Jul 2006 12:57:07 -0000
@@ -31,7 +31,11 @@
argv_copy [i] = argv[i + 1];
argv_copy[argc - 1] = NULL;
+#ifdef DBUS_WIN
+ if (!_dbus_spawn_async_with_babysitter (NULL, argv_copy, setup_func, NULL, NULL, &error))
+#else
if (!_dbus_spawn_async_with_babysitter (NULL, argv_copy, setup_func, NULL, &error))
+#endif
{
fprintf (stderr, "Could not launch application: \"%s\"\n",
error.message);
Index: test/test-segfault.c
===================================================================
RCS file: /cvs/dbus/dbus/test/test-segfault.c,v
retrieving revision 1.4
diff -u -B -b -r1.4 test-segfault.c
--- test/test-segfault.c 30 Nov 2005 19:32:26 -0000 1.4
+++ test/test-segfault.c 3 Jul 2006 12:57:07 -0000
@@ -1,9 +1,26 @@
/* This is simply a process that segfaults */
+#include <config.h>
#include <stdlib.h>
#include <signal.h>
+#ifdef DBUS_WIN
+#define RLIMIT_CORE 4 /* max core file size */
+typedef unsigned long rlim_t;
+struct rlimit {
+ rlim_t rlim_cur;
+ rlim_t rlim_max;
+};
+static int getrlimit (int __resource, struct rlimit *__rlp) {
+ return -1;
+}
+static int setrlimit (int __resource, const struct rlimit *__rlp) {
+ return -1;
+}
+#else
#include <sys/time.h>
#include <sys/resource.h>
+#endif
+
int
main (int argc, char **argv)
Index: tools/dbus-monitor.c
===================================================================
RCS file: /cvs/dbus/dbus/tools/dbus-monitor.c,v
retrieving revision 1.16
diff -u -B -b -r1.16 dbus-monitor.c
--- tools/dbus-monitor.c 14 Jun 2006 14:39:51 -0000 1.16
+++ tools/dbus-monitor.c 3 Jul 2006 12:57:19 -0000
@@ -19,6 +19,7 @@
*
*/
+#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Index: tools/dbus-send.c
===================================================================
RCS file: /cvs/dbus/dbus/tools/dbus-send.c,v
retrieving revision 1.20
diff -u -B -b -r1.20 dbus-send.c
--- tools/dbus-send.c 1 Aug 2005 16:10:34 -0000 1.20
+++ tools/dbus-send.c 3 Jul 2006 12:57:19 -0000
@@ -19,6 +19,7 @@
*
*/
+#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
More information about the dbus
mailing list