_wstat on Windows (actually stat stuff in general)
- From: Kean Johnston <kean johnston gmail com>
- To: "gtk-devel-list gnome org" <gtk-devel-list gnome org>
- Subject: _wstat on Windows (actually stat stuff in general)
- Date: Mon, 26 Sep 2011 08:59:29 +0200
In at least gstdio.c, possibly other places (I am still looking) there is a
lot of code to use the "wide" versions of various functions like stat,
because it is assumed that the input argument is UTF-8 and the CRT doesn't
support UTF-8 directly but rather Microsoft's own multibyte character set
stuff (MBCS). In almost all cases this is cool except for 1: stat. MSDN has
this to say about _wstat:
"_wstat does not work with Windows Vista symbolic links. In these cases,
_wstat will always report a file size of 0. _stat does work correctly with
symbolic links."
So, for stat, we have to do a double conversion: first from the input UTF-8
to UTF-16, and then from UTF-16 to MBCS so that we can call stat instead of
wstat so that users don't get any nasty surprises when using g_stat() on a
symlink in Vista. *le sigh*
There is also a broader issue with stat. The size of struct stat can vary
according to what macros are defined when you include <sys/stat.h>. If you
have _FILE_OFFSET_BITS=64 defined your size fields are 64-bit, otherwise
they *can* be 64-bit but are most often 32-bit. Thus, if glib was compiled
without _FILE_OFFSET_BITS defined, and an application uses g_stat() but
DOES have it defined, you're in for trouble (and the inverse is true - if
glib was compiled with _FILE_OFFSET_BITS=64 and the app wasn't, the same
hilarity ensues).
On almost all UNIX systems time_t is a signed 32-bit int thus capable of
representing time from the epoch through some time in 2038. Windows has
support for 64-bit time fields which is surprisingly forward thinking of them.
Since GLib is a "platform library" it would be extremely useful if
gstsdio.h defined a GLib version of the stat structures instead of just
doing "typedef struct stat GStatBuf". That structure can be consistently
defined, with sufficiently large data types that it will work on all
systems. Despire the coolness of Windows supporting time fields 64-bits
wide for the least amount of pain it would probably be best if the time
fields were left at 32-bits (although it would be really cool and forward
thinking if we used 64-bits), but to use 64-bit fields for all size fields,
and 32-bit fields for all others. That way gstdio.[ch] can be compiled in a
very specific way to get the information needed and then smush it into that
portable structure. Here's how I would define the GStatBuf data type:
typedef struct GStatBuf {
guint32 st_dev;
guint64 st_ino;
guint16 st_mode;
guint16 st_nlink;
guint32 st_uid;
guint32 st_gid;
guint32 st_rdev;
gint64 st_size;
gint32 st_atime;
gint32 st_mtime;
gint32 st_ctime;
} GStatBuf;
We would of course add defines for things like G_S_IFDIR, G_S_IFMT etc that
are also nice and portable (and the corresponding G_S_ISDIR type macros).
While in gstdio I'd also add the glaring-by-their-omission g_lseek,
g_fseek, and g_ftell all of which could take a gint32 as their argument or
return value.
A good case could be made for extending gtypes.h to include some primnitive
types such a gtime_t, goffs_t etc and use those but that's just syntactic
sugar really. Using the existing types would be just fine.
I'd really love to do this if no-one has any objections?
Kean
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]