| diff -Naur glib-2.46.0-orig/glib/gstdio.c glib-2.46.0/glib/gstdio.c |
| --- glib-2.46.0-orig/glib/gstdio.c 2015-02-26 15:57:09.000000000 +0300 |
| +++ glib-2.46.0/glib/gstdio.c 2015-09-22 09:08:58.032066100 +0300 |
| @@ -192,6 +192,11 @@ |
| 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_WRITE | FILE_SHARE_DELETE; |
| wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); |
| int retval; |
| int save_errno; |
| @@ -202,12 +207,114 @@ |
| 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 |
| int fd; |
| @@ -254,6 +361,8 @@ |
| 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; |
| @@ -264,12 +373,41 @@ |
| 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 */ |
| + } |
| + |
| + 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); |
| @@ -702,33 +840,102 @@ |
| 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) |
| - { |
| - errno = EINVAL; |
| - return NULL; |
| - } |
| - |
| - wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL); |
| - |
| - if (wmode == NULL) |
| - { |
| - g_free (wfilename); |
| - errno = EINVAL; |
| - return NULL; |
| - } |
| - |
| - retval = _wfopen (wfilename, wmode); |
| - save_errno = errno; |
| - |
| - g_free (wfilename); |
| - g_free (wmode); |
| + 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 |
| + { |
| + 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; |
| + } |
| + } |
| + } |
| + if (2 == strlen(priv_mode)) |
| + { |
| + if (('c' == priv_mode[1]) || ('n' == priv_mode[1])) |
| + priv_mode[1] = '\0'; |
| + else |
| + { |
| + 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; |
| + } |
| + } |
| + |
| + hFile = g_open (filename, flags, (_S_IREAD | _S_IWRITE)); |
| + |
| + 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); |