X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbus%2Fdbus-file-win.c;h=06a8ea1ced4a74d103d495c3679a2b46968442d4;hb=67f9cca382df0d03adfe6b619aa613d103fa77f6;hp=ca346e3fb331c28e7dd7e28a6a46e240cfb26ccc;hpb=31d9f4d655416caf499cdab4019a453650fb2d72;p=platform%2Fupstream%2Fdbus.git diff --git a/dbus/dbus-file-win.c b/dbus/dbus-file-win.c index ca346e3..06a8ea1 100644 --- a/dbus/dbus-file-win.c +++ b/dbus/dbus-file-win.c @@ -22,18 +22,77 @@ * */ +#include #include "dbus-protocol.h" #include "dbus-string.h" #include "dbus-internals.h" #include "dbus-sysdeps-win.h" #include "dbus-pipe.h" -#include -#include -#include -#include - #include + + +/** + * 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); + + 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 @@ -49,72 +108,78 @@ _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; + unsigned int total; const char *filename_c; _DBUS_ASSERT_ERROR_IS_CLEAR (error); 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 hnd %p 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; } @@ -122,40 +187,34 @@ _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. * * @param str the string to write out * @param filename the file to save string to + * @param world_readable if true, ensure file is world readable * @param error error to be filled in on failure * @returns #FALSE on failure */ dbus_bool_t _dbus_string_save_to_file (const DBusString *str, const DBusString *filename, + dbus_bool_t world_readable, DBusError *error) { - int fd; + HANDLE hnd; int bytes_to_write; const char *filename_c; DBusString tmp_filename; @@ -167,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; @@ -202,17 +261,26 @@ _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) + /* TODO - support world-readable in an atomic fashion */ + 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; } + if (world_readable) + { + if (! _dbus_make_file_world_readable (&tmp_filename, error)) + goto out; + } - _dbus_verbose ("tmp file %s fd %d opened\n", tmp_filename_c, fd); + _dbus_verbose ("tmp file %s hnd %p opened\n", tmp_filename_c, hnd); need_unlink = TRUE; @@ -222,40 +290,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) < 0) + 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; @@ -268,12 +338,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); @@ -294,99 +368,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 hnd %p 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; - } -}