Applied patch to make g_unlink more reliable on Win32

- Use CreateFile on Win32 to make sure g_unlink always works (GNOME BZ #674214)
- Fixed typo's in description
- Revised 0001-Don-t-start-a-DBus-server-when-built-as-static-lib.patch
This commit is contained in:
Erik van Pienbroek 2012-08-27 23:38:51 +02:00
parent d06158f473
commit d7b4489c6d
3 changed files with 364 additions and 11 deletions

View File

@ -1,6 +1,6 @@
From f40b1bdb92a2a1d77bc7b451add6a587cc270100 Mon Sep 17 00:00:00 2001
From b3ffcafba67b01f6dcecb2525dca1c51bf218efa Mon Sep 17 00:00:00 2001
From: Erik van Pienbroek <epienbro@fedoraproject.org>
Date: Sat, 5 May 2012 18:10:47 +0200
Date: Mon, 27 Aug 2012 22:57:01 +0200
Subject: [PATCH] Don't start a DBus server when built as static lib
The new Win32 DBus server code which was recently introduced works
@ -17,14 +17,22 @@ using a static compiled GLib and that a proper error message is automatically
returned to the caller. This also fixes a compilation failure which occurs
when GLib is compiled as static library
---
gio/gdbusaddress.c | 4 ++++
1 file changed, 4 insertions(+)
gio/gdbusaddress.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/gio/gdbusaddress.c b/gio/gdbusaddress.c
index 4aa13b9..5fba139 100644
index fac22b7..8f57997 100644
--- a/gio/gdbusaddress.c
+++ b/gio/gdbusaddress.c
@@ -1390,6 +1390,8 @@ get_session_address_dbus_launch (GError **error)
@@ -1354,7 +1354,6 @@ get_session_address_dbus_launch (GError **error)
{
HANDLE autolaunch_mutex, init_mutex;
char *address = NULL;
- wchar_t gio_path[MAX_PATH+1+200];
autolaunch_mutex = acquire_mutex (DBUS_AUTOLAUNCH_MUTEX);
@@ -1365,8 +1364,11 @@ get_session_address_dbus_launch (GError **error)
release_mutex (init_mutex);
@ -32,8 +40,11 @@ index 4aa13b9..5fba139 100644
+
if (address == NULL)
{
+ wchar_t gio_path[MAX_PATH+1+200];
gio_path[MAX_PATH] = 0;
@@ -1428,6 +1430,8 @@ get_session_address_dbus_launch (GError **error)
if (GetModuleFileNameW (_g_io_win32_get_module (), gio_path, MAX_PATH))
{
@@ -1403,6 +1405,8 @@ get_session_address_dbus_launch (GError **error)
}
}
@ -43,5 +54,5 @@ index 4aa13b9..5fba139 100644
if (address == NULL)
--
1.7.10.1
1.7.11.4

View File

@ -0,0 +1,334 @@
From 7f4f4354540440c0a8a37beaccbec8bc7fc15ec7 Mon Sep 17 00:00:00 2001
From: Erik van Pienbroek <epienbro@fedoraproject.org>
Date: Mon, 27 Aug 2012 23:28:54 +0200
Subject: [PATCH] Use CreateFile on Win32 to make sure g_unlink always works
The functions g_open(), g_creat() and g_fopen() defer to _wopen(),
_wcreat() and _wfopen() respectively. This is very similar to
the corresponding arrangement for Linux. However, those Windows
functions do not support renaming a file whilst it's open. As a
result, g_rename() behaves differently on the Windows platform
compared to its Linux behaviour, where files can be renamed even
while there are file handles still open. Resolved this by using
the Win32 API function CreateFile() instead of _wopen(), _wcreat()
and _wfopen()
Patch initially created by John Emmas
---
glib/gstdio.c | 259 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 233 insertions(+), 26 deletions(-)
diff --git a/glib/gstdio.c b/glib/gstdio.c
index 6d763e1..c1d072f 100644
--- a/glib/gstdio.c
+++ b/glib/gstdio.c
@@ -191,6 +191,11 @@ g_open (const gchar *filename,
int mode)
{
#ifdef G_OS_WIN32
+ HANDLE hFile;
+ DWORD dwDesiredAccess = 0;
+ DWORD dwFlagsAndAttributes = 0;
+ DWORD dwDisposition = OPEN_EXISTING;
+ DWORD dwSharedAccess = FILE_SHARE_READ | FILE_SHARE_DELETE;
wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
int retval;
int save_errno;
@@ -201,12 +206,114 @@ g_open (const gchar *filename,
return -1;
}
- retval = _wopen (wfilename, flags, mode);
- save_errno = errno;
+ /* Set up the access modes and other attributes */
+ if ((flags & _O_CREAT) && (mode & _S_IREAD))
+ {
+ if (! (mode & _S_IWRITE))
+ dwFlagsAndAttributes = FILE_ATTRIBUTE_READONLY; /* Sets file to 'read only' after the file gets closed */
+ }
+ if ( !(flags & _O_ACCMODE))
+ {
+ /* Equates to _O_RDONLY */
+ if (flags & _O_TRUNC)
+ {
+ errno = EINVAL;
+ g_free (wfilename);
+ return -1;
+ }
- g_free (wfilename);
+ dwDesiredAccess |= GENERIC_READ;
+ dwSharedAccess |= FILE_SHARE_WRITE;
+ }
+ if (flags & _O_WRONLY)
+ {
+ if (flags & _O_RDWR)
+ {
+ errno = EINVAL;
+ g_free (wfilename);
+ return -1;
+ }
+ dwDesiredAccess |= GENERIC_WRITE;
+ }
+ if (flags & _O_RDWR)
+ {
+ dwDesiredAccess |= GENERIC_READ;
+ dwDesiredAccess |= GENERIC_WRITE;
+ }
+ if (flags & _O_TRUNC)
+ {
+ if (flags & _O_CREAT)
+ dwDisposition = CREATE_ALWAYS;
+ else
+ dwDisposition = TRUNCATE_EXISTING;
+ }
+ if ((flags & _O_CREAT) && !(flags & _O_TRUNC))
+ {
+ if (flags & _O_EXCL)
+ dwDisposition = CREATE_NEW;
+ else
+ dwDisposition = OPEN_ALWAYS;
+ }
+ if (flags & _O_CREAT)
+ {
+ /* Handle the other flags that can be attached to _O_CREAT */
+ if ((flags & _O_TEMPORARY) || (flags & _O_SHORT_LIVED))
+ dwFlagsAndAttributes |= FILE_ATTRIBUTE_TEMPORARY;
+
+ if (flags & _O_TEMPORARY)
+ dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
+ }
+ if ((flags & _O_SEQUENTIAL) || (flags & _O_APPEND))
+ {
+ dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
+ }
+ else if (flags & _O_RANDOM)
+ {
+ dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
+ }
+
+ if (0 == dwFlagsAndAttributes)
+ dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
+ hFile = CreateFileW(wfilename, dwDesiredAccess, dwSharedAccess, NULL, dwDisposition, dwFlagsAndAttributes, NULL);
+
+ if (INVALID_HANDLE_VALUE == hFile)
+ {
+ retval = (-1);
+
+ switch (GetLastError ())
+ {
+#define CASE(a,b) case ERROR_##a: errno = b; break
+ CASE (FILE_NOT_FOUND, ENOENT);
+ CASE (PATH_NOT_FOUND, ENOENT);
+ CASE (ACCESS_DENIED, EACCES);
+ CASE (NOT_SAME_DEVICE, EXDEV);
+ CASE (LOCK_VIOLATION, EACCES);
+ CASE (SHARING_VIOLATION, EACCES);
+ CASE (FILE_EXISTS, EEXIST);
+ CASE (ALREADY_EXISTS, EEXIST);
+#undef CASE
+ default: errno = EIO;
+ }
+ }
+ else
+ retval = _open_osfhandle((long)hFile, flags);
+
+ if ((-1) != retval)
+ {
+ /* We have a valid file handle. Set its translation mode to text or binary, as appropriate */
+ if ((!(flags & _O_TEXT)) && (_fmode == _O_BINARY))
+ _setmode(retval, _O_BINARY);
+ else if ((flags & _O_TEXT) || (_fmode == _O_TEXT))
+ _setmode(retval, _O_TEXT);
+ else
+ _setmode(retval, _O_BINARY);
+ }
+
+ save_errno = errno;
+ g_free (wfilename);
errno = save_errno;
+
return retval;
#else
return open (filename, flags, mode);
@@ -248,6 +355,8 @@ g_creat (const gchar *filename,
int mode)
{
#ifdef G_OS_WIN32
+ HANDLE hFile;
+ DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
int retval;
int save_errno;
@@ -258,12 +367,41 @@ g_creat (const gchar *filename,
return -1;
}
- retval = _wcreat (wfilename, mode);
- save_errno = errno;
+ if (mode & _S_IREAD)
+ {
+ if (! (mode & _S_IWRITE))
+ dwFlagsAndAttributes = FILE_ATTRIBUTE_READONLY; /* Sets file to 'read only' after the file gets closed */
+ }
- g_free (wfilename);
+ hFile = CreateFileW(wfilename, (GENERIC_READ | GENERIC_WRITE), (FILE_SHARE_READ | FILE_SHARE_DELETE),
+ NULL, CREATE_ALWAYS, dwFlagsAndAttributes, NULL);
+
+ if (INVALID_HANDLE_VALUE == hFile)
+ {
+ retval = (-1);
+
+ switch (GetLastError ())
+ {
+#define CASE(a,b) case ERROR_##a: errno = b; break
+ CASE (FILE_NOT_FOUND, ENOENT);
+ CASE (PATH_NOT_FOUND, ENOENT);
+ CASE (ACCESS_DENIED, EACCES);
+ CASE (NOT_SAME_DEVICE, EXDEV);
+ CASE (LOCK_VIOLATION, EACCES);
+ CASE (SHARING_VIOLATION, EACCES);
+ CASE (FILE_EXISTS, EEXIST);
+ CASE (ALREADY_EXISTS, EEXIST);
+#undef CASE
+ default: errno = EIO;
+ }
+ }
+ else
+ retval = _open_osfhandle((long)hFile, _O_RDWR);
+ save_errno = errno;
+ g_free (wfilename);
errno = save_errno;
+
return retval;
#else
return creat (filename, mode);
@@ -699,33 +837,102 @@ g_fopen (const gchar *filename,
const gchar *mode)
{
#ifdef G_OS_WIN32
- wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
- wchar_t *wmode;
- FILE *retval;
- int save_errno;
-
- if (wfilename == NULL)
+ int hFile;
+ int flags = 0;
+ gchar priv_mode[4];
+ FILE *retval = NULL;
+
+ if ((NULL == filename) || (NULL == mode))
+ {
+ errno = EINVAL;
+ goto out;
+ }
+ if ((strlen(mode) < 1) || (strlen(mode) > 3))
+ {
+ errno - EINVAL;
+ goto out;
+ }
+
+ strncpy(priv_mode, mode, 3);
+ priv_mode[3] = '\0';
+
+ /* Set up any flags to pass to 'g_open()' */
+ if (3 == strlen(priv_mode))
+ {
+ if (('c' == priv_mode[2]) || ('n' == priv_mode[2]))
+ priv_mode[2] = '\0';
+ else
{
- errno = EINVAL;
- return NULL;
+ if (0 == strcmp(priv_mode, "a+b"))
+ flags = _O_RDWR | _O_CREAT | _O_APPEND | _O_BINARY;
+ else if (0 == strcmp(priv_mode, "a+t"))
+ flags = _O_RDWR | _O_CREAT | _O_APPEND | _O_TEXT;
+ else if (0 == strcmp(priv_mode, "r+b"))
+ flags = _O_RDWR | _O_BINARY;
+ else if (0 == strcmp(priv_mode, "r+t"))
+ flags = _O_RDWR | _O_TEXT;
+ else if (0 == strcmp(priv_mode, "w+b"))
+ flags = _O_RDWR | _O_CREAT |_O_TRUNC | _O_BINARY;
+ else if (0 == strcmp(priv_mode, "w+t"))
+ flags = _O_RDWR | _O_CREAT |_O_TRUNC | _O_TEXT;
+ else
+ {
+ errno = EINVAL;
+ goto out;
+ }
}
-
- wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL);
-
- if (wmode == NULL)
+ }
+ if (2 == strlen(priv_mode))
+ {
+ if (('c' == priv_mode[1]) || ('n' == priv_mode[1]))
+ priv_mode[1] = '\0';
+ else
{
- g_free (wfilename);
- errno = EINVAL;
- return NULL;
+ if (0 == strcmp(priv_mode, "a+"))
+ flags = _O_RDWR | _O_CREAT | _O_APPEND;
+ else if (0 == strcmp(priv_mode, "ab"))
+ flags = _O_WRONLY | _O_CREAT | _O_APPEND | _O_BINARY;
+ else if (0 == strcmp(priv_mode, "at"))
+ flags = _O_WRONLY | _O_CREAT | _O_APPEND | _O_TEXT;
+ else if (0 == strcmp(priv_mode, "rb"))
+ flags = _O_RDONLY | _O_BINARY;
+ else if (0 == strcmp(priv_mode, "rt"))
+ flags = _O_RDONLY | _O_TEXT;
+ else if (0 == strcmp(priv_mode, "wb"))
+ flags = _O_WRONLY | _O_CREAT | _O_TRUNC | _O_BINARY;
+ else if (0 == strcmp(priv_mode, "wt"))
+ flags = _O_WRONLY | _O_CREAT | _O_TRUNC | _O_TEXT;
+ else
+ {
+ errno = EINVAL;
+ goto out;
+ }
}
+ }
+ if (1 == strlen(priv_mode))
+ {
+ if (0 == strcmp(priv_mode, "a"))
+ flags = _O_WRONLY | _O_CREAT | _O_APPEND;
+ else if (0 == strcmp(priv_mode, "r"))
+ flags = _O_RDONLY;
+ else if (0 == strcmp(priv_mode, "w"))
+ flags = _O_WRONLY | _O_CREAT | _O_TRUNC;
+ else if ( !((0 == strcmp(priv_mode, "c")) || (0 == strcmp(priv_mode, "n"))))
+ {
+ errno = EINVAL;
+ goto out;
+ }
+ }
- retval = _wfopen (wfilename, wmode);
- save_errno = errno;
+ hFile = g_open (filename, flags, (_S_IREAD | _S_IWRITE));
- g_free (wfilename);
- g_free (wmode);
+ if (INVALID_HANDLE_VALUE == (HANDLE)hFile)
+ /* 'errno' will have already been set by 'g_open()' */
+ retval = NULL;
+ else
+ retval = _fdopen(hFile, mode);
- errno = save_errno;
+out:
return retval;
#else
return fopen (filename, mode);
--
1.7.11.4

View File

@ -2,7 +2,7 @@
Name: mingw-glib2
Version: 2.33.10
Release: 1%{?dist}
Release: 2%{?dist}
Summary: MinGW Windows GLib2 library
License: LGPLv2+
@ -38,13 +38,16 @@ BuildRequires: glib2-devel >= 2.31.20
# https://bugzilla.gnome.org/show_bug.cgi?id=675516
Patch0: 0001-Don-t-start-a-DBus-server-when-built-as-static-lib.patch
# https://bugzilla.gnome.org/show_bug.cgi?id=674214
Patch1: 0001-Use-CreateFile-on-Win32-to-make-sure-g_unlink-always.patch
%description
MinGW Windows Glib2 library.
# Win32
%package -n mingw32-glib2
Summary: MinGW Windows zlib compression library for the win32 target
Summary: MinGW Windows Glib2 library for the win32 target
%description -n mingw32-glib2
MinGW Windows Glib2 library.
@ -59,7 +62,7 @@ Static version of the MinGW Windows GLib2 library.
# Win64
%package -n mingw64-glib2
Summary: MinGW Windows zlib compression library for the win32 target
Summary: MinGW Windows Glib2 library for the win64 target
%description -n mingw64-glib2
MinGW Windows Glib2 library.
@ -79,6 +82,7 @@ Static version of the MinGW Windows GLib2 library.
%prep
%setup -q -n glib-%{version}
%patch0 -p1
%patch1 -p1
%build
@ -257,6 +261,10 @@ find $RPM_BUILD_ROOT -name "*.la" -delete
%changelog
* Mon Aug 27 2012 Erik van Pienbroek <epienbro@fedoraproject.org> - 2.33.10-2
- Use CreateFile on Win32 to make sure g_unlink always works (GNOME BZ #674214)
- Fixed typo's in description
* Sat Aug 25 2012 Erik van Pienbroek <epienbro@fedoraproject.org> - 2.33.10-1
- Update to 2.33.10