Re: g_stat() did not work for large file (>2B) under WIN32
- From: Kuang-Chun Cheng <kccheng LinuxDAQ-Labs com>
- To: Tor Lillqvist <tml iki fi>
- Cc: gtk-devel-list <gtk-devel-list gnome org>
- Subject: Re: g_stat() did not work for large file (>2B) under WIN32
- Date: Thu, 30 Jul 2009 15:38:39 +0800
On Thu, Jul 30, 2009 at 3:16 PM, Tor Lillqvist<tml iki fi> wrote:
>> But I still think it's not a bad idea to make g_stat() to have the same behavior
>> as stat() on Linux.
>
> But it *has* the same behaviour, more or less, to the extent possible.
> What makes you think using -D_LARGEFILE64_SOURCE
> -D_FILE_OFFSET_BITS=64 is the "standard" thing to do on Linux? If it
> was "the standard" thing one always must do, why is it then needed at
> all, shouldn't it be the *non-standard* case that requires extra
> compiler options? (Yeah, I am mostly just playing devil's advocate
> here.)
>
> It is not really possible to change this now. Remember that g_stat()
> takes a struct stat, and we can't change what struct stat is in the
> Microsoft C library. Also, I honestly don't think the Linux way to
> handle this is ideal either. It is, in my eyes, a bit ugly that
> compiler options affect the sizes of fields in a "standard" structure
> like struct stat. If some library out of your control has struct stat
> as part of its API, how can you know if that library has been compiled
> with -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 or not?
>
> Was it really that hard to predict that in the future file sizes can
> be over 2 GB back when the Linux struct stat was defined? Why didn't
> they make it use 64-bit size from the beginning? For something like
> Windows, or SunOS/Solaris, with much longer history, one can
> understand it better.
>
> You should know that the g_stat(), g_fopen() etc so-called gstdio
> wrappers were introduced for one single reason: to make it easy to
> handle arbitrary file names on Windows by offering an API that uses
> UTF-8. Around that time it was becoming more and more clear that all
> of GTK+ will be very UTF-8 -oriented, so it fit in nicely to use UTF-8
> also for file names (and other strings passed to/from the OS) on
> Windows.
>
> In retrospect, it might have been a good idea back then to make
> g_stat() take not a struct stat, but some new struct GStat type, which
> then on Linux would have been identical to struct stat as it is when
> -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 are used (regardless if
> these macro definitions would be present when GStat-using code is
> compiled or not), and on Windows would have been identical to struct
> _stati64.
>
> But that can't be changed now because it would of course break stuff
> horribly. And anyway, GIO is the "modern" API in GLib to get file
> attributes, and it obviously uses a 64-bit size.
agree
>
> Maybe we could introduce a *new* function, though, g_gstat(), which
> would take a GStat, defined as described above?
>
In fact, this is my current solution as below:
(it may not complete, but at least, solve my problem)
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE 1 /* for stat() large file */
#endif
#ifndef _FILE_OFFSET_BITS
#define _FILE_OFFSET_BITS 64 /* for fopen() large file */
#endif
#include <sys/stat.h>
#ifdef G_OS_WIN32
#if __MSVCRT_VERSION__ >= 0x0601
typedef struct __stat64 ovi_stat_t;
#define _DEBUG_REAL_STAT "struct __stat64"
#else
typedef struct _stati64 ovi_stat_t;
#define _DEBUG_REAL_STAT "struct _stati64"
#endif
#else
typedef struct stat ovi_stat_t;
#define _DEBUG_REAL_STAT "struct stat"
#endif
int ovi_stat (const gchar *filename, ovi_stat_t *buf);
int ovi_stat (const gchar *filename, ovi_stat_t *buf)
{
#ifdef G_OS_WIN32
wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
int retval;
int save_errno;
int len;
if (wfilename == NULL)
{
errno = EINVAL;
return -1;
}
len = wcslen (wfilename);
while (len > 0 && G_IS_DIR_SEPARATOR (wfilename[len-1]))
len--;
if (len > 0 &&
(!g_path_is_absolute (filename) || len > g_path_skip_root
(filename) - filename))
wfilename[len] = '\0';
#ifdef _LARGEFILE64_SOURCE
#if __MSVCRT_VERSION__ >= 0x0601
retval = _wstat64 (wfilename, (struct __stat64 *) buf);
#else
retval = _wstati64 (wfilename, (struct _stati64 *) buf);
#endif
#else
retval = _wstat (wfilename, (struct _stat *) buf);
#endif
save_errno = errno;
g_free (wfilename);
errno = save_errno;
return retval;
#else
return stat (filename, buf);
#endif
}
Regards
KC
> --tml
> _______________________________________________
> gtk-devel-list mailing list
> gtk-devel-list gnome org
> http://mail.gnome.org/mailman/listinfo/gtk-devel-list
>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]