Re: g_stat() did not work for large file (>2B) under WIN32



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]