Commit 6e214b5b authored by Marcus Brinkmann's avatar Marcus Brinkmann Committed by Ralf Habacker

Prepare for WinCE port: Convert windows code to native API, avoid errno.

parent 4708efee
......@@ -29,12 +29,72 @@
#include "dbus-sysdeps-win.h"
#include "dbus-pipe.h"
#include <errno.h>
#include <fcntl.h>
#include <io.h>
#include <sys/stat.h>
#include <windows.h>
/**
* Thin wrapper around the read() system call that appends
* the data it reads to the DBusString buffer. It appends
* up to the given count.
*
* @param hnd the HANDLE to read from
* @param buffer the buffer to append data to
* @param count the amount of data to read
* @param error place to set an error
* @returns the number of bytes read or -1
*/
static int
_dbus_file_read (HANDLE hnd,
DBusString *buffer,
int count,
DBusError *error)
{
BOOL result;
DWORD bytes_read;
int start;
char *data;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
_dbus_assert (count >= 0);
start = _dbus_string_get_length (buffer);
if (!_dbus_string_lengthen (buffer, count))
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
return -1;
}
data = _dbus_string_get_data_len (buffer, start, count);
again:
result = ReadFile (hnd, data, count, &bytes_read, NULL);
if (result == 0)
{
char *emsg = _dbus_win_error_string (GetLastError ());
dbus_set_error (error, _dbus_win_error_from_last_error (),
"Failed to read from 0x%x: %s", hnd, emsg);
_dbus_win_free_error_string (emsg);
return -1;
}
if (bytes_read)
{
/* put length back (doesn't actually realloc) */
_dbus_string_set_length (buffer, start + bytes_read);
#if 0
if (bytes_read > 0)
_dbus_verbose_bytes_of_string (buffer, start, bytes_read);
#endif
}
return bytes_read;
}
/**
* Appends the contents of the given file to the string,
* returning error code. At the moment, won't open a file
......@@ -50,8 +110,9 @@ _dbus_file_get_contents (DBusString *str,
const DBusString *filename,
DBusError *error)
{
int fd;
struct _stati64 sb;
HANDLE hnd;
DWORD fsize;
DWORD fsize_hi;
int orig_len;
int total;
const char *filename_c;
......@@ -60,62 +121,67 @@ _dbus_file_get_contents (DBusString *str,
filename_c = _dbus_string_get_const_data (filename);
fd = _open (filename_c, O_RDONLY | O_BINARY);
if (fd < 0)
hnd = CreateFileA (filename_c, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hnd == INVALID_HANDLE_VALUE)
{
dbus_set_error (error, _dbus_error_from_errno (errno),
"Failed to open \"%s\": %s",
filename_c,
strerror (errno));
char *emsg = _dbus_win_error_string (GetLastError ());
dbus_set_error (error, _dbus_win_error_from_last_error (),
"Failed to open \"%s\": %s", filename_c, emsg);
_dbus_win_free_error_string (emsg);
return FALSE;
}
_dbus_verbose ("file %s fd %d opened\n", filename_c, fd);
if (_fstati64 (fd, &sb) < 0)
{
dbus_set_error (error, _dbus_error_from_errno (errno),
"Failed to stat \"%s\": %s",
filename_c,
strerror (errno));
_dbus_verbose ("file %s fd 0x%x opened\n", filename_c, hnd);
fsize = GetFileSize (hnd, &fsize_hi);
if (fsize == 0xFFFFFFFF && GetLastError() != NO_ERROR)
{
char *emsg = _dbus_win_error_string (GetLastError ());
dbus_set_error (error, _dbus_win_error_from_last_error (),
"Failed to get file size for \"%s\": %s",
filename_c, emsg);
_dbus_win_free_error_string (emsg);
_dbus_verbose ("fstat() failed: %s",
strerror (errno));
_dbus_verbose ("GetFileSize() failed: %s", emsg);
_close (fd);
CloseHandle (hnd);
return FALSE;
}
if (sb.st_size > _DBUS_ONE_MEGABYTE)
if (fsize_hi != 0 || fsize > _DBUS_ONE_MEGABYTE)
{
dbus_set_error (error, DBUS_ERROR_FAILED,
"File size %lu of \"%s\" is too large.",
(unsigned long) sb.st_size, filename_c);
_close (fd);
"File size %lu/%lu of \"%s\" is too large.",
(unsigned long) fsize_hi,
(unsigned long) fsize, filename_c);
CloseHandle (hnd);
return FALSE;
}
total = 0;
orig_len = _dbus_string_get_length (str);
if (sb.st_size > 0 && S_ISREG (sb.st_mode))
if (fsize > 0)
{
int bytes_read;
while (total < (int) sb.st_size)
while (total < fsize)
{
bytes_read = _dbus_file_read (fd, str, sb.st_size - total);
bytes_read = _dbus_file_read (hnd, str, fsize - total, error);
if (bytes_read <= 0)
{
dbus_set_error (error, _dbus_error_from_errno (errno),
"Error reading \"%s\": %s",
filename_c,
strerror (errno));
_dbus_verbose ("read() failed: %s",
strerror (errno));
_close (fd);
if (bytes_read == 0)
{
dbus_set_error (error, DBUS_ERROR_FAILED,
"Premature EOF reading \"%s\"",
filename_c);
}
else
_DBUS_ASSERT_ERROR_IS_SET (error);
CloseHandle (hnd);
_dbus_string_set_length (str, orig_len);
return FALSE;
}
......@@ -123,25 +189,17 @@ _dbus_file_get_contents (DBusString *str,
total += bytes_read;
}
_close (fd);
CloseHandle (hnd);
return TRUE;
}
else if (sb.st_size != 0)
{
_dbus_verbose ("Can only open regular files at the moment.\n");
dbus_set_error (error, DBUS_ERROR_FAILED,
"\"%s\" is not a regular file",
filename_c);
_close (fd);
return FALSE;
}
else
{
_close (fd);
CloseHandle (hnd);
return TRUE;
}
}
/**
* Writes a string out to a file. If the file exists,
* it will be atomically overwritten by the new data.
......@@ -156,7 +214,7 @@ _dbus_string_save_to_file (const DBusString *str,
const DBusString *filename,
DBusError *error)
{
int fd;
HANDLE hnd;
int bytes_to_write;
const char *filename_c;
DBusString tmp_filename;
......@@ -168,7 +226,7 @@ _dbus_string_save_to_file (const DBusString *str,
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
fd = -1;
hnd = INVALID_HANDLE_VALUE;
retval = FALSE;
need_unlink = FALSE;
......@@ -203,17 +261,20 @@ _dbus_string_save_to_file (const DBusString *str,
filename_c = _dbus_string_get_const_data (filename);
tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
fd = _open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
0600);
if (fd < 0)
hnd = CreateFileA (tmp_filename_c, GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL,
INVALID_HANDLE_VALUE);
if (hnd == INVALID_HANDLE_VALUE)
{
dbus_set_error (error, _dbus_error_from_errno (errno),
"Could not create %s: %s", tmp_filename_c,
strerror (errno));
char *emsg = _dbus_win_error_string (GetLastError ());
dbus_set_error (error, _dbus_win_error_from_last_error (),
"Could not create \"%s\": %s", filename_c, emsg);
_dbus_win_free_error_string (emsg);
goto out;
}
_dbus_verbose ("tmp file %s fd %d opened\n", tmp_filename_c, fd);
_dbus_verbose ("tmp file %s fd 0x%x opened\n", tmp_filename_c, hnd);
need_unlink = TRUE;
......@@ -223,40 +284,42 @@ _dbus_string_save_to_file (const DBusString *str,
while (total < bytes_to_write)
{
int bytes_written;
DWORD bytes_written;
BOOL res;
bytes_written = _write (fd, str_c + total, bytes_to_write - total);
res = WriteFile (hnd, str_c + total, bytes_to_write - total,
&bytes_written, NULL);
if (bytes_written <= 0)
if (res == 0 || bytes_written <= 0)
{
dbus_set_error (error, _dbus_error_from_errno (errno),
"Could not write to %s: %s", tmp_filename_c,
strerror (errno));
char *emsg = _dbus_win_error_string (GetLastError ());
dbus_set_error (error, _dbus_win_error_from_last_error (),
"Could not write to %s: %s", tmp_filename_c, emsg);
_dbus_win_free_error_string (emsg);
goto out;
}
total += bytes_written;
}
if (_close (fd) < 0)
if (CloseHandle (hnd) == 0)
{
dbus_set_error (error, _dbus_error_from_errno (errno),
"Could not close file %s: %s",
tmp_filename_c, strerror (errno));
char *emsg = _dbus_win_error_string (GetLastError ());
dbus_set_error (error, _dbus_win_error_from_last_error (),
"Could not close file %s: %s", tmp_filename_c, emsg);
_dbus_win_free_error_string (emsg);
goto out;
}
fd = -1;
hnd = INVALID_HANDLE_VALUE;
/* Unlike rename(), MoveFileEx() can replace existing files */
if (!MoveFileExA (tmp_filename_c, filename_c, MOVEFILE_REPLACE_EXISTING))
{
char *emsg = _dbus_win_error_string (GetLastError ());
dbus_set_error (error, DBUS_ERROR_FAILED,
"Could not rename %s to %s: %s",
tmp_filename_c, filename_c,
emsg);
dbus_set_error (error, _dbus_win_error_from_last_error (),
"Could not rename %s to %s: %s",
tmp_filename_c, filename_c, emsg);
_dbus_win_free_error_string (emsg);
goto out;
......@@ -269,12 +332,16 @@ _dbus_string_save_to_file (const DBusString *str,
out:
/* close first, then unlink */
if (fd >= 0)
_close (fd);
if (hnd != INVALID_HANDLE_VALUE)
CloseHandle (hnd);
if (need_unlink && _unlink (tmp_filename_c) < 0)
_dbus_verbose ("failed to unlink temp file %s: %s\n",
tmp_filename_c, strerror (errno));
if (need_unlink && DeleteFileA (tmp_filename_c) == 0)
{
char *emsg = _dbus_win_error_string (GetLastError ());
_dbus_verbose ("Failed to unlink temp file %s: %s", tmp_filename_c,
emsg);
_dbus_win_free_error_string (emsg);
}
_dbus_string_free (&tmp_filename);
......@@ -295,99 +362,40 @@ dbus_bool_t
_dbus_create_file_exclusively (const DBusString *filename,
DBusError *error)
{
int fd;
HANDLE hnd;
const char *filename_c;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
filename_c = _dbus_string_get_const_data (filename);
fd = _open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
0600);
if (fd < 0)
hnd = CreateFileA (filename_c, GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL,
INVALID_HANDLE_VALUE);
if (hnd == INVALID_HANDLE_VALUE)
{
dbus_set_error (error,
DBUS_ERROR_FAILED,
"Could not create file %s: %s\n",
filename_c,
strerror (errno));
char *emsg = _dbus_win_error_string (GetLastError ());
dbus_set_error (error, _dbus_win_error_from_last_error (),
"Could not create file %s: %s",
filename_c, emsg);
_dbus_win_free_error_string (emsg);
return FALSE;
}
_dbus_verbose ("exclusive file %s fd %d opened\n", filename_c, fd);
_dbus_verbose ("exclusive file %s fd 0x%x opened\n", filename_c, hnd);
if (_close (fd) < 0)
if (CloseHandle (hnd) == 0)
{
dbus_set_error (error,
DBUS_ERROR_FAILED,
"Could not close file %s: %s\n",
filename_c,
strerror (errno));
char *emsg = _dbus_win_error_string (GetLastError ());
dbus_set_error (error, _dbus_win_error_from_last_error (),
"Could not close file %s: %s",
filename_c, emsg);
_dbus_win_free_error_string (emsg);
return FALSE;
}
return TRUE;
}
/**
* Thin wrapper around the read() system call that appends
* the data it reads to the DBusString buffer. It appends
* up to the given count, and returns the same value
* and same errno as read(). The only exception is that
* _dbus_file_read() handles EINTR for you. Also,
* _dbus_file_read() can return ENOMEM.
*
* @param fd the file descriptor to read from
* @param buffer the buffer to append data to
* @param count the amount of data to read
* @returns the number of bytes read or -1
*/
int
_dbus_file_read (int fd,
DBusString *buffer,
int count)
{
int bytes_read;
int start;
char *data;
_dbus_assert (count >= 0);
start = _dbus_string_get_length (buffer);
if (!_dbus_string_lengthen (buffer, count))
{
errno = ENOMEM;
return -1;
}
data = _dbus_string_get_data_len (buffer, start, count);
again:
bytes_read = _read (fd, data, count);
if (bytes_read < 0)
{
if (errno == EINTR)
goto again;
else
{
/* put length back (note that this doesn't actually realloc anything) */
_dbus_string_set_length (buffer, start);
return -1;
}
}
else
{
/* put length back (doesn't actually realloc) */
_dbus_string_set_length (buffer, start + bytes_read);
#if 0
if (bytes_read > 0)
_dbus_verbose_bytes_of_string (buffer, start, bytes_read);
#endif
return bytes_read;
}
}
......@@ -54,9 +54,6 @@ dbus_bool_t _dbus_create_file_exclusively (const DBusString *filename,
DBusError *error);
dbus_bool_t _dbus_delete_file (const DBusString *filename,
DBusError *error);
int _dbus_file_read (int fd,
DBusString *buffer,
int count);
/** @} */
......
......@@ -30,10 +30,6 @@
#include <stdio.h>
#ifdef HAVE_ERRNO_H
# include <errno.h>
#endif
static dbus_bool_t
do_check_nonce (int fd, const DBusString *nonce, DBusError *error)
{
......@@ -191,7 +187,7 @@ generate_and_write_nonce (const DBusString *filename, DBusError *error)
* indicate whether the server accepted the nonce.
*/
dbus_bool_t
_dbus_send_nonce(int fd, const DBusString *noncefile, DBusError *error)
_dbus_send_nonce (int fd, const DBusString *noncefile, DBusError *error)
{
dbus_bool_t read_result;
int send_result;
......@@ -203,36 +199,33 @@ _dbus_send_nonce(int fd, const DBusString *noncefile, DBusError *error)
if (_dbus_string_get_length (noncefile) == 0)
return FALSE;
if ( !_dbus_string_init (&nonce) )
if (!_dbus_string_init (&nonce))
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
return FALSE;
}
read_result = _dbus_read_nonce (noncefile, &nonce, NULL);
}
read_result = _dbus_read_nonce (noncefile, &nonce, error);
if (!read_result)
{
dbus_set_error (error,
_dbus_error_from_errno (errno),
"Could not read nonce from file %s (%s)",
_dbus_string_get_const_data (noncefile), _dbus_strerror(errno));
_DBUS_ASSERT_ERROR_IS_SET (error);
_dbus_string_free (&nonce);
return FALSE;
}
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
send_result = _dbus_write_socket (fd, &nonce, 0, _dbus_string_get_length (&nonce));
_dbus_string_free (&nonce);
if (send_result == -1)
{
dbus_set_error (error,
_dbus_error_from_errno (errno),
"Failed to send nonce (fd=%d): %s",
fd, _dbus_strerror(errno));
return FALSE;
}
{
dbus_set_error (error,
_dbus_error_from_system_errno (),
"Failed to send nonce (fd=%d): %s",
fd, _dbus_strerror_from_errno ());
return FALSE;
}
return TRUE;
}
......@@ -284,8 +277,10 @@ do_noncefile_create (DBusNonceFile *noncefile,
}
if (!_dbus_create_directory (&noncefile->dir, error))
{
_DBUS_ASSERT_ERROR_IS_SET (error);
goto on_error;
}
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
}
else
......@@ -303,10 +298,12 @@ do_noncefile_create (DBusNonceFile *noncefile,
if (!generate_and_write_nonce (&noncefile->path, error))
{
_DBUS_ASSERT_ERROR_IS_SET (error);
if (use_subdir)
_dbus_delete_directory (&noncefile->dir, NULL); //we ignore possible errors deleting the dir and return the write error instead
goto on_error;
}
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
_dbus_string_free (&randomStr);
......
......@@ -28,8 +28,7 @@
#include "dbus-internals.h"
#include "dbus-pipe.h"
#include <io.h>
#include <errno.h>
#include <windows.h>
/**
* write data to a pipe.
......@@ -48,15 +47,17 @@ _dbus_pipe_write (DBusPipe *pipe,
int len,
DBusError *error)
{
int written;
DWORD written;
BOOL res;
const char *buffer_c = _dbus_string_get_const_data (buffer);
written = _write (pipe->fd_or_handle, buffer_c + start, len);
if (written < 0)
res = WriteFile ((HANDLE) pipe->fd_or_handle, buffer_c + start, len, &written, NULL);
if (res == 0 || written < 0)
{
dbus_set_error (error, DBUS_ERROR_FAILED,
"Writing to pipe: %s\n",
strerror (errno));
_dbus_strerror_from_errno ());
}
return written;
}
......@@ -74,10 +75,11 @@ _dbus_pipe_close (DBusPipe *pipe,
{
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
if (_close (pipe->fd_or_handle) < 0)
if (CloseHandle ((HANDLE) pipe->fd_or_handle) == 0)
{
dbus_set_error (error, _dbus_error_from_errno (errno),
"Could not close pipe %d: %s", pipe->fd_or_handle, strerror (errno));
dbus_set_error (error, _dbus_error_from_system_errno (),
"Could not close pipe %d: %s", pipe->fd_or_handle,
_dbus_strerror_from_errno ());
return -1;
}
else
......
......@@ -37,7 +37,9 @@
#undef interface
#if HAVE_ERRNO_H
#include <errno.h>
#endif
/* Make use of the fact that the WSAE* error codes don't
* overlap with errno E* codes. Wrapper functions store
......@@ -51,7 +53,7 @@
#define DBUS_SOCKET_IS_INVALID(s) ((SOCKET)(s) == INVALID_SOCKET)
#define DBUS_SOCKET_API_RETURNS_ERROR(n) ((n) == SOCKET_ERROR)
#define DBUS_SOCKET_SET_ERRNO() errno = WSAGetLastError()
#define DBUS_SOCKET_SET_ERRNO() (_dbus_win_set_errno (WSAGetLastError()))
#define DBUS_CLOSE_SOCKET(s) closesocket(s)