Ardour  8.7-15-gadf511264b
gstdio_compat.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015-2017 Robin Gareus <robin@gareus.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 /* glib mingw64/win32 compatibility
20  *
21  * see http://pidgin.im/pipermail/devel/2014-April/023475.html
22  * and https://pidgin.im/pipermail/commits/2014-April/025031.html
23  * https://tracker.ardour.org/view.php?id=6575
24  */
25 
26 #ifndef __pbd_gstdio_compat_h__
27 #define __pbd_gstdio_compat_h__
28 
29 #include <glib/gstdio.h>
30 
31 /* glib's definition of g_stat+GStatBuf is broken for mingw64-w32
32  * (and possibly other 32-bit windows)
33  */
34 #if defined(_WIN32) && !defined(_MSC_VER) && !defined(_WIN64)
35 typedef struct _stat GStatBufW32;
36 static inline int
37 pbd_g_stat(const gchar *filename, GStatBufW32 *buf)
38 {
39  return g_stat(filename, (GStatBuf*)buf);
40 }
41 # define GStatBuf GStatBufW32
42 # define g_stat pbd_g_stat
43 # define g_lstat pbd_g_stat
44 #endif
45 
46 /* 64bit mingw -- use _mingw_stat64.h
47  *
48  * glib-2.42.0 wrongly uses _wstat() with 'struct stat' (only MSVC is special cased),
49  * while the windows API is
50  * int _wstat(const wchar_t*, struct _stat*)
51  * note that struct _stat != struct stat;
52  *
53  * This has been fixed with sometime between 2.42.0 and 2.64.1
54  */
55 #if defined(_WIN32) && !defined(_MSC_VER) && defined(_WIN64) && !GLIB_CHECK_VERSION (2,64,1)
56 #include <windows.h>
57 #include <errno.h>
58 #include <wchar.h>
59 
60 typedef struct _stat GStatBufW64;
61 static inline int
62 pbd_g_stat(const gchar* filename, GStatBufW64* buf)
63 {
64  gunichar2* wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
65  if (wfilename == NULL) {
66  errno = EINVAL;
67  return -1;
68  }
69 
70  int len = wcslen ((wchar_t*)wfilename);
71  while (len > 0 && G_IS_DIR_SEPARATOR (wfilename[len-1])) {
72  --len;
73  }
74  if (len > 0 && (!g_path_is_absolute (filename) || len > g_path_skip_root (filename) - filename)) {
75  wfilename[len] = '\0';
76  }
77 
78  int retval = _wstat ((wchar_t*)wfilename, buf);
79  int save_errno = errno;
80  g_free (wfilename);
81  errno = save_errno;
82  return retval;
83 }
84 # define GStatBuf GStatBufW64
85 # define g_stat pbd_g_stat
86 # define g_lstat pbd_g_stat
87 #endif
88 
89 #endif /* __pbd_gstdio_compat_h__ */