Win32 Port
Ralf Habacker
ralf.habacker at freenet.de
Sat Apr 29 11:35:21 PDT 2006
Kosina, Martin schrieb:
> Ralf Habacker wrote:
>
>
>> to become a little familar with the stuff I tried to hack the sources
>>
> to
>
>> see how complicate a port would be. Tcp connections are mostly working
>>
>
>
>> and some data could already be exchanged, but test_names does not
>>
> finish
>
>> it's call. probably as Martin Kosina already stated.
>>
>
>
>> - initialisation of winsock library in dbus-sysdeps-utils-win32.c
>>
>
> I'd like to ask for suggestions on this, as well - it's a perenial
> question for ported libraries that wrap Winsock. Any natural place this
> could happen in the dbus stack? For now, I added something similar -
> _dbus_win32_init() - but is there another place we could stick it that
> would hide this [silly] step? It just needs to execute once (that could
> be handled by a static flag) before any Winsock calls are made.
>
>
I have used two places :
_dbus_connect_tcp_socket() -> used by client
_dbus_listen_tcp_socket() -> used by server
in each case before the socket() call.
The related init function looks like this
void _dbus_tcp_init()
{
static BOOL isCalled = FALSE;
WORD wVersionRequested;
WSADATA wsaData;
int err;
DBusError error;
if (isCalled)
return;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
isCalled = TRUE;
if (err)
fprintf(stderr,"socket initialisation failed with errorcode=%d",err);
else
fprintf(stderr,"Winsocket initialisation done");
//dbus_set_error (&error,"socket initialisation failed with
errorcode=%d",err);
}
>> - fixed socket/file incompatible write/read functions ->
>> dbus-sysdeps-win32.c has now a isSocket(), which are used in
>> _dbus_read/_dbus_write
>>
>
> Just curious - is your isSocket() something like _get_osfhandle()<0 ? Or
> did you find a better WinAPI that answers the handle type precisely ?
>
>
I used the return code of getsockopt(), which is zero for socket file
types and -1 for non socket type. In the second case
WSAGetLastError() returns WSAENOTSOCK
int isSocket(int fd)
{
char buf[10];
int len = 10;
int ret = getsockopt(fd,SOL_SOCKET,SO_TYPE,buf,&len) == 0 ? TRUE : FALSE;
_dbus_verbose("isSocket called for fd %d => %d
(%d)\n",fd,ret,WSAGetLastError());
return ret;
}
>> native _dbus_directory_open() , _dbus_directory_get_next_file ()
>> implementations (not tested complete)
>>
>
> Got those working, as well, the usual FindNextFile() stuff with handles,
> etc.
>
>
okay, then it is obsolate from my path. Do you have ported the
gettimeofday() function in dbus-sysdeps-unix.c:_dbus_get_current_time()
>> - Because there are several places changed and some new files are
>>
> added
>
>> i've created a tarball at
>>
> http://webdev.cegit.de/snapshots/kde-windows/dbus-win
>
> Thanks for sharing that - few other run-time things I had to add to mine
> that turned out to be crucial:
>
> - Sockets must be set non-blocking (this is pretty important or things
> won't work right):
>
> In _dbus_set_fd_nonblocking (), I used:
>
> u_long NonBlock;
> if (ioctlsocket(fd, FIONBIO, &NonBlock) == SOCKET_ERROR)
> {
> ....
> }
>
Ths may fix of one of the problems i had
> - In dbus-transport-unix():do_reading(), I had to check
> WSAGetLastError() == WSAEWOULDBLOCK (errno == EAGAIN won't give the
> right answer with Winsock). Same with writing, when the descriptor is a
> socket.
>
this could completly managed in dbus_read() and
dbus_write() function by setting errno.
> - vnsnprintf() is used to check required buffer size - the POSIX variant
> returns the number of bytes that are required, on Windows the function
> simply fails. _dbus_string_append_printf_valist() relies on the former
> behavior.
>
I had patched this too.
dbus_bool_t
_dbus_string_append_printf_valist (DBusString *str,
const char *format,
va_list args)
{
#ifdef _WIN32
/* see http://msdn2.microsoft.com/en-us/library/1kt27hek(VS.80).aspx */
char c[1024];
#else
char c;
#endif
> Looks like we had couple different philosophies - I #ifdef'ed and
> re-implemented individual calls or small blocks in the original
> dbus-sysdeps* files, ala Tor's diff. The amount of platform-specific
> linecount is ultimately pretty low, so duplicating lot of otherwise
> independent logic seemed somehow undesirable. But the dual-file approach
> has its merits, as well, so its ultimately up to the maintainers - which
> approach is preferable?
>
I have used the Qt approach (which is used also by KDE) means to have
- a public header -> for example dbus-transport.h
- optional a private headers -> I found dbus-transport_protected.h
- a platform independent base file, -> dbus-transport.c
- and platform depending files, ->
dbus-tranport-unix.c, dbus-tranport-win32.c
In the above mentioned schema according to this scheme
- unix domain sockets are platform depending and would be located in
dbus-transport-unix.c
- tcp domain sockets are platform independing which little differences,
that means mostly functions would be located in dbus-transport.c maybe
with small platform related catches, some as for example the unix
implementations of dbus_read(), dbus_write() are located in
dbus-transport-unix.c and the win32 counterparts in
dbus-transport-win32.c. In dbus-transport-win32.c named pipe support
will be also located. This would be the same for other platform related
code areas.
After relooking into the source there may be also another approach by
using to use transport related files like
dbus-transport-win32-pipe.c -> containing win32 named pipe
dbus-transport-unix-domain.c -> containing unix domain socket related code
dbus-transport-tcp.c -> containing tcp related code
to provide a function pointer table similar the following
int (*init)(..);
int (*listen)(..);
int (*connect)(..);
int (*read)(..);
int (*write)(..)
int (*close)(..)
(*read_credentials)(..)
(*write_credentials)(..)
int (*getopt)(..);
int (*setopt)(..);
either in DBusTransferVTable or DBusServerVTable depending on where it
fits better and to refactor the relating code.
In my opinion such a concept would makes sense because it will make it
very easy to add additional procotols as stated in
http://www.freedesktop.org/wiki/Software_2fDBusRemote.
Ralf
More information about the dbus
mailing list