+2004-10-27 Matthias Clasen <mclasen@redhat.com>
+
+ Introduce the idea of a filename encoding, which is
+ *literally* the filename encoding on Unix. On windows,
+ use the Unicode name converted to UTF-8. (#156325,
+ Tor Lillqvist, Owen Taylor)
+
+ * glib/gdir.[hc]:
+ * glib/gconvert.[hc]:
+ * glib/gfileutils.[hc]:
+ * glib/gutils.[hc]:
+ * glib/giowin32.c: On Windows, keep old ABI versions
+ of GLib pathname api for DLL ABI stability. Use different
+ names for the new-style UTF-8 versions. Hide this through
+ a #define.
+
+ * glib/gstdio.[hc]: New files containing wrappers for
+ POSIX pathname api.
+
+ * glib/glib.symbols: Add new symbols.
+
+ * glib/makegalias.pl: Drop Win32 specific .def syntax,
+ include gstdio.h
+
2004-10-27 Matthias Clasen <mclasen@redhat.com>
* glib/gkeyfile.c: Fix includes. (#156500, #156499,
+2004-10-27 Matthias Clasen <mclasen@redhat.com>
+
+ Introduce the idea of a filename encoding, which is
+ *literally* the filename encoding on Unix. On windows,
+ use the Unicode name converted to UTF-8. (#156325,
+ Tor Lillqvist, Owen Taylor)
+
+ * glib/gdir.[hc]:
+ * glib/gconvert.[hc]:
+ * glib/gfileutils.[hc]:
+ * glib/gutils.[hc]:
+ * glib/giowin32.c: On Windows, keep old ABI versions
+ of GLib pathname api for DLL ABI stability. Use different
+ names for the new-style UTF-8 versions. Hide this through
+ a #define.
+
+ * glib/gstdio.[hc]: New files containing wrappers for
+ POSIX pathname api.
+
+ * glib/glib.symbols: Add new symbols.
+
+ * glib/makegalias.pl: Drop Win32 specific .def syntax,
+ include gstdio.h
+
2004-10-27 Matthias Clasen <mclasen@redhat.com>
* glib/gkeyfile.c: Fix includes. (#156500, #156499,
+2004-10-27 Matthias Clasen <mclasen@redhat.com>
+
+ Introduce the idea of a filename encoding, which is
+ *literally* the filename encoding on Unix. On windows,
+ use the Unicode name converted to UTF-8. (#156325,
+ Tor Lillqvist, Owen Taylor)
+
+ * glib/gdir.[hc]:
+ * glib/gconvert.[hc]:
+ * glib/gfileutils.[hc]:
+ * glib/gutils.[hc]:
+ * glib/giowin32.c: On Windows, keep old ABI versions
+ of GLib pathname api for DLL ABI stability. Use different
+ names for the new-style UTF-8 versions. Hide this through
+ a #define.
+
+ * glib/gstdio.[hc]: New files containing wrappers for
+ POSIX pathname api.
+
+ * glib/glib.symbols: Add new symbols.
+
+ * glib/makegalias.pl: Drop Win32 specific .def syntax,
+ include gstdio.h
+
2004-10-27 Matthias Clasen <mclasen@redhat.com>
* glib/gkeyfile.c: Fix includes. (#156500, #156499,
+2004-10-27 Matthias Clasen <mclasen@redhat.com>
+
+ Introduce the idea of a filename encoding, which is
+ *literally* the filename encoding on Unix. On windows,
+ use the Unicode name converted to UTF-8. (#156325,
+ Tor Lillqvist, Owen Taylor)
+
+ * glib/gdir.[hc]:
+ * glib/gconvert.[hc]:
+ * glib/gfileutils.[hc]:
+ * glib/gutils.[hc]:
+ * glib/giowin32.c: On Windows, keep old ABI versions
+ of GLib pathname api for DLL ABI stability. Use different
+ names for the new-style UTF-8 versions. Hide this through
+ a #define.
+
+ * glib/gstdio.[hc]: New files containing wrappers for
+ POSIX pathname api.
+
+ * glib/glib.symbols: Add new symbols.
+
+ * glib/makegalias.pl: Drop Win32 specific .def syntax,
+ include gstdio.h
+
2004-10-27 Matthias Clasen <mclasen@redhat.com>
* glib/gkeyfile.c: Fix includes. (#156500, #156499,
+2004-10-27 Matthias Clasen <mclasen@redhat.com>
+
+ Introduce the idea of a filename encoding, which is
+ *literally* the filename encoding on Unix. On windows,
+ use the Unicode name converted to UTF-8. (#156325,
+ Tor Lillqvist, Owen Taylor)
+
+ * glib/gdir.[hc]:
+ * glib/gconvert.[hc]:
+ * glib/gfileutils.[hc]:
+ * glib/gutils.[hc]:
+ * glib/giowin32.c: On Windows, keep old ABI versions
+ of GLib pathname api for DLL ABI stability. Use different
+ names for the new-style UTF-8 versions. Hide this through
+ a #define.
+
+ * glib/gstdio.[hc]: New files containing wrappers for
+ POSIX pathname api.
+
+ * glib/glib.symbols: Add new symbols.
+
+ * glib/makegalias.pl: Drop Win32 specific .def syntax,
+ include gstdio.h
+
2004-10-27 Matthias Clasen <mclasen@redhat.com>
* glib/gkeyfile.c: Fix includes. (#156500, #156499,
+2004-10-27 Matthias Clasen <mclasen@redhat.com>
+
+ * glib/tmpl/fileutils.sgml: Add some intro.
+
2004-10-26 Matthias Clasen <mclasen@redhat.com>
* gobject/gobject-docs.sgml: Add an index for 2.6 additions.
<SECTION>
<TITLE>File Utilities</TITLE>
<FILE>fileutils</FILE>
+<INCLUDE>glib.h,glib/gstdio.h</INCLUDE>
GFileError
G_FILE_ERROR
GFileTest
g_dir_rewind
g_dir_close
+<SUBSECTION>
+g_open
+g_rename
+g_mkdir
+g_stat
+g_unlink
+g_remove
+g_fopen
+g_freopen
+
<SUBSECTION Private>
g_file_error_quark
</SECTION>
<!-- ##### SECTION Long_Description ##### -->
<para>
+There is a group of functions which wrap the common POSIX functions
+dealing with filenames (g_open(), g_rename(), g_mkdir(), g_stat(),
+g_unlink(), g_remove(), g_fopen(), g_freopen()). The point of these
+wrappers is to make it possible to handle file names with any Unicode
+characters in them on Windows without having to use ifdefs and the
+wide character API in the application code.
+</para>
+<para>
+The pathname argument should be in the GLib file name encoding. On
+POSIX this is the actual on-disk encoding which might correspond to
+the locale settings of the process (or the
+<envar>G_FILENAME_ENCODING</envar> environment variable), or not.
+</para>
+<para>
+On Windows the GLib file name encoding is UTF-8. Note that the
+Microsoft C library does not use UTF-8, but has separate APIs for
+current system code page and wide characters (UTF-16). The GLib
+wrappers call the wide character API if present (on modern Windows
+systems), otherwise convert to/from the system code page.
+</para>
+<para>
+Another group of functions allows to open and read directories
+in the GLib file name encoding. These are g_dir_open(),
+g_dir_read_name(), g_dir_rewind(), g_dir_close().
</para>
<!-- ##### SECTION See_Also ##### -->
@dir:
+<!-- ##### FUNCTION g_open ##### -->
+<para>
+
+</para>
+
+@filename:
+@flags:
+@mode:
+@Returns:
+
+
+<!-- ##### FUNCTION g_rename ##### -->
+<para>
+
+</para>
+
+@oldfilename:
+@newfilename:
+@Returns:
+
+
+<!-- ##### FUNCTION g_mkdir ##### -->
+<para>
+
+</para>
+
+@filename:
+@mode:
+@Returns:
+
+
+<!-- ##### FUNCTION g_stat ##### -->
+<para>
+
+</para>
+
+@filename:
+@buf:
+@Returns:
+
+
+<!-- ##### FUNCTION g_unlink ##### -->
+<para>
+
+</para>
+
+@filename:
+@Returns:
+
+
+<!-- ##### FUNCTION g_remove ##### -->
+<para>
+
+</para>
+
+@filename:
+@Returns:
+
+
+<!-- ##### FUNCTION g_fopen ##### -->
+<para>
+
+</para>
+
+@filename:
+@mode:
+@Returns:
+
+
+<!-- ##### FUNCTION g_freopen ##### -->
+<para>
+
+</para>
+
+@filename:
+@mode:
+@stream:
+@Returns:
+
+
Since: 2.6
+
<!-- ##### MACRO G_GNUC_INTERNAL ##### -->
<para>
Expands to the GNU C <literal>visibility(hidden)</literal> attribute if the
@pid: the process id of the child process
@status: Status information about the child process,
see waitpid(2) for more information about this field
-@data: user data passed to g_child_watch_add()
+@data: user data passed to g_child_watch_add()
<!-- ##### FUNCTION g_child_watch_source_new ##### -->
gscanner.c \
gshell.c \
gslist.c \
+ gstdio.c \
gstrfuncs.c \
gstring.c \
gthread.c \
gshell.h \
gslist.h \
gspawn.h \
+ gstdio.h \
gstrfuncs.h \
gstring.h \
gthread.h \
* get_filename_charset:
* @charset: return location for the name of the filename encoding
*
- * Determines the character set used for filenames by consulting the
- * environment variables G_FILENAME_ENCODING and G_BROKEN_FILENAMES.
+ * Determines the preferred character set used for filenames by
+ * consulting the environment variables G_FILENAME_ENCODING and
+ * G_BROKEN_FILENAMES.
*
* G_FILENAME_ENCODING may be set to a comma-separated list of character
* set names. The special token "@locale" is taken to mean the character set
* character set of the current locale is taken as the filename encoding.
*
* The returned @charset belongs to GLib and must not be freed.
- *
- * Return value: %TRUE if the charset used for filename is UTF-8.
+ *
+ * Note that on Unix, regardless of the locale character set or
+ * G_FILENAME_ENCODING value, the actual file names present on a
+ * system might be in any random encoding or just gibberish.
+ *
+ * Return value: %TRUE
+ * if the charset used for filename is UTF-8.
*/
static gboolean
get_filename_charset (const gchar **filename_charset)
}
#else /* G_PLATFORM_WIN32 */
+
static gboolean
get_filename_charset (const gchar **filename_charset)
+{
+#ifdef G_OS_WIN32
+ /* On Windows GLib pretends that the filename charset is UTF-8 */
+ if (filename_charset)
+ *filename_charset = "UTF-8";
+ return TRUE;
+#else
+ /* Cygwin works like before */
+ g_get_charset (filename_charset);
+ return FALSE;
+#endif
+}
+
+#ifdef G_OS_WIN32
+
+static gboolean
+old_get_filename_charset (const gchar **filename_charset)
{
g_get_charset (filename_charset);
return FALSE;
}
+
+#endif
+
#endif /* G_PLATFORM_WIN32 */
/* This is called from g_thread_init(). It's used to
"UTF-8", charset, bytes_read, bytes_written, error);
}
+#ifdef G_OS_WIN32
+
+#undef g_filename_to_utf8
+
+/* Binary compatibility version. Not for newly compiled code. */
+
+gchar*
+g_filename_to_utf8 (const gchar *opsysstring,
+ gssize len,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error)
+{
+ const gchar *charset;
+
+ if (old_get_filename_charset (&charset))
+ return strdup_len (opsysstring, len, bytes_read, bytes_written, error);
+ else
+ return g_convert (opsysstring, len,
+ "UTF-8", charset, bytes_read, bytes_written, error);
+}
+
+#endif
+
/**
* g_filename_from_utf8:
* @utf8string: a UTF-8 encoded string.
charset, "UTF-8", bytes_read, bytes_written, error);
}
+#ifdef G_OS_WIN32
+
+#undef g_filename_from_utf8
+
+/* Binary compatibility version. Not for newly compiled code. */
+
+gchar*
+g_filename_from_utf8 (const gchar *utf8string,
+ gssize len,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error)
+{
+ const gchar *charset;
+
+ if (old_get_filename_charset (&charset))
+ return strdup_len (utf8string, len, bytes_read, bytes_written, error);
+ else
+ return g_convert (utf8string, len,
+ charset, "UTF-8", bytes_read, bytes_written, error);
+}
+
+#endif
+
/* Test of haystack has the needle prefix, comparing case
* insensitive. haystack may be UTF-8, but needle must
* contain only ascii. */
/* Convert between the operating system (or C runtime)
* representation of file names and UTF-8.
*/
+#ifdef G_OS_WIN32
+#define g_filename_to_utf8 g_filename_to_utf8_utf8
+#define g_filename_from_utf8 g_filename_from_utf8_utf8
+#endif
+
gchar* g_filename_to_utf8 (const gchar *opsysstring,
gssize len,
gsize *bytes_read,
* gdir.c: Simplified wrapper around the DIRENT functions.
*
* Copyright 2001 Hans Breuer
+ * Copyright 2004 Tor Lillqvist
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
struct _GDir
{
- DIR *dir;
+ union {
+ DIR *dirp;
+#ifdef G_OS_WIN32
+ _WDIR *wdirp;
+#endif
+ } u;
+#ifdef G_OS_WIN32
+ gchar utf8_buf[FILENAME_MAX*4];
+#endif
};
/**
* g_dir_open:
- * @path: the path to the directory you are interested in
+ * @path: the path to the directory you are interested in. On Unix
+ * in the on-disk encoding. On Windows in UTF-8
* @flags: Currently must be set to 0. Reserved for future use.
* @error: return location for a #GError, or %NULL.
* If non-%NULL, an error will be set if and only if
* g_dir_open_fails.
*
- * Opens a directory for reading. The names of the files
- * in the directory can then be retrieved using
- * g_dir_read_name().
+ * Opens a directory for reading. The names of the files in the
+ * directory can then be retrieved using g_dir_read_name().
*
* Return value: a newly allocated #GDir on success, %NULL on failure.
* If non-%NULL, you must free the result with g_dir_close()
GError **error)
{
GDir *dir;
+#ifndef G_OS_WIN32
gchar *utf8_path;
+#endif
g_return_val_if_fail (path != NULL, NULL);
+#ifdef G_OS_WIN32
+ if (G_WIN32_HAVE_WIDECHAR_API ())
+ {
+ wchar_t *wpath = g_utf8_to_utf16 (path, -1, NULL, NULL, error);
+
+ if (wpath == NULL)
+ return NULL;
+
+ dir = g_new (GDir, 1);
+
+ dir->u.wdirp = _wopendir (wpath);
+ g_free (wpath);
+
+ if (dir->u.wdirp)
+ return dir;
+ }
+ else
+ {
+ gchar *cp_path = g_locale_from_utf8 (path, -1, NULL, NULL, error);
+
+ if (cp_path == NULL)
+ return NULL;
+
+ dir = g_new (GDir, 1);
+
+ dir->u.dirp = opendir (cp_path);
+
+ g_free (cp_path);
+
+ if (dir->u.dirp)
+ return dir;
+ }
+
+ /* error case */
+
+ g_set_error (error,
+ G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ _("Error opening directory '%s': %s"),
+ path, g_strerror (errno));
+
+ g_free (dir);
+
+ return NULL;
+#else
dir = g_new (GDir, 1);
- dir->dir = opendir (path);
+ dir->u.dirp = opendir (path);
- if (dir->dir)
+ if (dir->u.dirp)
return dir;
/* error case */
g_free (dir);
return NULL;
+#endif
}
+#ifdef G_OS_WIN32
+
+/* The above function actually is called g_dir_open_utf8, and it's
+ * that what applications compiled with this GLib version will
+ * use.
+ */
+
+#undef g_dir_open
+
+/* Binary compatibility version. Not for newly compiled code. */
+
+GDir *
+g_dir_open (const gchar *path,
+ guint flags,
+ GError **error)
+{
+ gchar *utf8_path = g_locale_to_utf8 (path, -1, NULL, NULL, error);
+ GDir *retval;
+
+ if (utf8_path == NULL)
+ return NULL;
+
+ retval = g_dir_open_utf8 (utf8_path, flags, error);
+
+ g_free (utf8_path);
+
+ return retval;
+}
+#endif
+
/**
* g_dir_read_name:
* @dir: a #GDir* created by g_dir_open()
*
- * Retrieves the name of the next entry in the directory.
- * The '.' and '..' entries are omitted. The returned name is in
- * the encoding used for filenames. Use g_filename_to_utf8() to
- * convert it to UTF-8.
+ * Retrieves the name of the next entry in the directory. The '.' and
+ * '..' entries are omitted. On Windows, the returned name is in
+ * UTF-8. On Unix, it is in the on-disk encoding.
*
- * Return value: The entries name or %NULL if there are no
+ * Return value: The entry's name or %NULL if there are no
* more entries. The return value is owned by GLib and
* must not be modified or freed.
**/
g_return_val_if_fail (dir != NULL, NULL);
- entry = readdir (dir->dir);
+#ifdef G_OS_WIN32
+ if (G_WIN32_HAVE_WIDECHAR_API ())
+ {
+ gchar *utf8_name;
+ struct _wdirent *wentry;
+
+ while (1)
+ {
+ wentry = _wreaddir (dir->u.wdirp);
+ while (wentry
+ && (0 == wcscmp (wentry->d_name, L".") ||
+ 0 == wcscmp (wentry->d_name, L"..")))
+ wentry = _wreaddir (dir->u.wdirp);
+
+ if (wentry == NULL)
+ return NULL;
+
+ utf8_name = g_utf16_to_utf8 (wentry->d_name, -1, NULL, NULL, NULL);
+
+ if (utf8_name == NULL)
+ continue; /* Huh, impossible? Skip it anyway */
+
+ strcpy (dir->utf8_buf, utf8_name);
+ g_free (utf8_name);
+
+ return dir->utf8_buf;
+ }
+ }
+ else
+ {
+ while (1)
+ {
+ gchar *utf8_name;
+
+ entry = readdir (dir->u.dirp);
+ while (entry
+ && (0 == strcmp (entry->d_name, ".") ||
+ 0 == strcmp (entry->d_name, "..")))
+ entry = readdir (dir->u.dirp);
+
+ if (entry == NULL)
+ return NULL;
+
+ utf8_name = g_locale_to_utf8 (entry->d_name, -1, NULL, NULL, NULL);
+
+ if (utf8_name != NULL)
+ {
+ strcpy (dir->utf8_buf, utf8_name);
+ g_free (utf8_name);
+
+ return dir->utf8_buf;
+ }
+ }
+ }
+#else
+ entry = readdir (dir->u.dirp);
while (entry
&& (0 == strcmp (entry->d_name, ".") ||
0 == strcmp (entry->d_name, "..")))
- entry = readdir (dir->dir);
+ entry = readdir (dir->u.dirp);
if (entry)
return entry->d_name;
else
return NULL;
+#endif
+}
+
+#ifdef G_OS_WIN32
+
+/* Ditto for g_dir_read_name */
+
+#undef g_dir_read_name
+
+/* Binary compatibility version. Not for newly compiled code. */
+
+G_CONST_RETURN gchar*
+g_dir_read_name (GDir *dir)
+{
+ while (1)
+ {
+ const gchar *utf8_name = g_dir_read_name_utf8 (dir);
+ gchar *retval;
+
+ if (utf8_name == NULL)
+ return NULL;
+
+ retval = g_locale_from_utf8 (utf8_name, -1, NULL, NULL, NULL);
+
+ if (retval != NULL)
+ {
+ strcpy (dir->utf8_buf, retval);
+ g_free (retval);
+
+ return dir->utf8_buf;
+ }
+ }
}
+#endif
+
/**
* g_dir_rewind:
* @dir: a #GDir* created by g_dir_open()
{
g_return_if_fail (dir != NULL);
- rewinddir (dir->dir);
+#ifdef G_OS_WIN32
+ if (G_WIN32_HAVE_WIDECHAR_API ())
+ {
+ _wrewinddir (dir->u.wdirp);
+ return;
+ }
+#endif
+
+ rewinddir (dir->u.dirp);
}
/**
{
g_return_if_fail (dir != NULL);
- closedir (dir->dir);
+#ifdef G_OS_WIN32
+ if (G_WIN32_HAVE_WIDECHAR_API ())
+ {
+ _wclosedir (dir->u.wdirp);
+ g_free (dir);
+ return;
+ }
+#endif
+
+ closedir (dir->u.dirp);
g_free (dir);
}
typedef struct _GDir GDir;
-GDir * g_dir_open (const gchar *path,
- guint flags,
- GError **error);
-G_CONST_RETURN gchar *g_dir_read_name (GDir *dir);
-void g_dir_rewind (GDir *dir);
-void g_dir_close (GDir *dir);
+#ifdef G_OS_WIN32
+/* For DLL ABI stability, keep old names for old (non-UTF-8) functionality. */
+#define g_dir_open g_dir_open_utf8
+#define g_dir_read_name g_dir_read_name_utf8
+#endif
+
+GDir * g_dir_open (const gchar *path,
+ guint flags,
+ GError **error);
+G_CONST_RETURN gchar *g_dir_read_name (GDir *dir);
+void g_dir_rewind (GDir *dir);
+void g_dir_close (GDir *dir);
G_END_DECLS
#define O_BINARY 0
#endif
+#include "gstdio.h"
#include "glibintl.h"
/**
* <informalexample><programlisting>
* /* DON'T DO THIS */
* if (!g_file_test (filename, G_FILE_TEST_IS_SYMLINK)) {
- * fd = open (filename, O_WRONLY);
+ * fd = g_open (filename, O_WRONLY);
* /* write to fd */
* }
* </programlisting></informalexample>
g_file_test (const gchar *filename,
GFileTest test)
{
+#ifdef G_OS_WIN32
+ if (G_WIN32_HAVE_WIDECHAR_API ())
+ {
+ wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+
+ if (wfilename == NULL)
+ return FALSE;
+
+ if ((test & G_FILE_TEST_EXISTS) && (_waccess (wfilename, F_OK) == 0))
+ {
+ g_free (wfilename);
+ return TRUE;
+ }
+
+ if (test & (G_FILE_TEST_IS_REGULAR |
+ G_FILE_TEST_IS_DIR |
+ G_FILE_TEST_IS_EXECUTABLE))
+ {
+ struct _stat s;
+
+ if (_wstat (wfilename, &s) == 0)
+ {
+ if ((test & G_FILE_TEST_IS_REGULAR) && S_ISREG (s.st_mode))
+ {
+ g_free (wfilename);
+ return TRUE;
+ }
+
+ if ((test & G_FILE_TEST_IS_DIR) && S_ISDIR (s.st_mode))
+ {
+ g_free (wfilename);
+ return TRUE;
+ }
+
+ if ((test & G_FILE_TEST_IS_EXECUTABLE) &&
+ (s.st_mode & _S_IEXEC))
+ {
+ g_free (wfilename);
+ return TRUE;
+ }
+ }
+ }
+
+ g_free (wfilename);
+
+ return FALSE;
+ }
+ else
+ {
+ gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
+
+ if (cp_filename == NULL)
+ return FALSE;
+
+ if ((test & G_FILE_TEST_EXISTS) && (access (cp_filename, F_OK) == 0))
+ {
+ g_free (cp_filename);
+ return TRUE;
+ }
+
+ if (test & (G_FILE_TEST_IS_REGULAR |
+ G_FILE_TEST_IS_DIR |
+ G_FILE_TEST_IS_EXECUTABLE))
+ {
+ struct stat s;
+
+ if (stat (cp_filename, &s) == 0)
+ {
+ if ((test & G_FILE_TEST_IS_REGULAR) && S_ISREG (s.st_mode))
+ {
+ g_free (cp_filename);
+ return TRUE;
+ }
+
+ if ((test & G_FILE_TEST_IS_DIR) && S_ISDIR (s.st_mode))
+ {
+ g_free (cp_filename);
+ return TRUE;
+ }
+
+ if ((test & G_FILE_TEST_IS_EXECUTABLE) &&
+ (s.st_mode & _S_IEXEC))
+ {
+ g_free (cp_filename);
+ return TRUE;
+ }
+ }
+ }
+
+ g_free (cp_filename);
+
+ return FALSE;
+ }
+#else
if ((test & G_FILE_TEST_EXISTS) && (access (filename, F_OK) == 0))
return TRUE;
-#ifndef G_OS_WIN32
if ((test & G_FILE_TEST_IS_EXECUTABLE) && (access (filename, X_OK) == 0))
{
if (getuid () != 0)
}
else
test &= ~G_FILE_TEST_IS_EXECUTABLE;
-#endif
if (test & G_FILE_TEST_IS_SYMLINK)
{
-#ifdef G_OS_WIN32
- /* no sym links on win32, no lstat in msvcrt */
-#else
struct stat s;
if ((lstat (filename, &s) == 0) && S_ISLNK (s.st_mode))
return TRUE;
-#endif
}
if (test & (G_FILE_TEST_IS_REGULAR |
if ((test & G_FILE_TEST_IS_DIR) && S_ISDIR (s.st_mode))
return TRUE;
-#ifndef G_OS_WIN32
/* The extra test for root when access (file, X_OK) succeeds.
- * Probably only makes sense on Unix.
*/
if ((test & G_FILE_TEST_IS_EXECUTABLE) &&
((s.st_mode & S_IXOTH) ||
(s.st_mode & S_IXUSR) ||
(s.st_mode & S_IXGRP)))
return TRUE;
-#else
- if ((test & G_FILE_TEST_IS_EXECUTABLE) &&
- (s.st_mode & _S_IEXEC))
- return TRUE;
-#endif
}
}
return FALSE;
+#endif
+}
+
+#ifdef G_OS_WIN32
+
+#undef g_file_test
+
+/* Binary compatibility version. Not for newly compiled code. */
+
+gboolean
+g_file_test (const gchar *filename,
+ GFileTest test)
+{
+ gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, NULL);
+ gboolean retval;
+
+ if (utf8_filename == NULL)
+ return FALSE;
+
+ retval = g_file_test_utf8 (utf8_filename, test);
+
+ g_free (utf8_filename);
+
+ return retval;
}
+#endif
+
GQuark
g_file_error_quark (void)
{
}
static gboolean
-get_contents_stdio (const gchar *filename,
+get_contents_stdio (const gchar *utf8_filename,
FILE *f,
gchar **contents,
gsize *length,
if (str == NULL)
{
- gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
- NULL, NULL, NULL);
g_set_error (error,
G_FILE_ERROR,
G_FILE_ERROR_NOMEM,
_("Could not allocate %lu bytes to read file \"%s\""),
(gulong) total_allocated,
utf8_filename ? utf8_filename : "???");
- g_free (utf8_filename);
goto error;
}
if (ferror (f))
{
- gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
- NULL, NULL, NULL);
g_set_error (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
_("Error reading file '%s': %s"),
utf8_filename ? utf8_filename : "???",
g_strerror (errno));
- g_free (utf8_filename);
goto error;
}
#ifndef G_OS_WIN32
static gboolean
-get_contents_regfile (const gchar *filename,
+get_contents_regfile (const gchar *utf8_filename,
struct stat *stat_buf,
gint fd,
gchar **contents,
if (buf == NULL)
{
- gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
- NULL, NULL, NULL);
g_set_error (error,
G_FILE_ERROR,
G_FILE_ERROR_NOMEM,
_("Could not allocate %lu bytes to read file \"%s\""),
(gulong) alloc_size,
utf8_filename ? utf8_filename : "???");
- g_free (utf8_filename);
goto error;
}
{
if (errno != EINTR)
{
- gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
- NULL, NULL, NULL);
g_free (buf);
g_set_error (error,
G_FILE_ERROR,
_("Failed to read from file '%s': %s"),
utf8_filename ? utf8_filename : "???",
g_strerror (errno));
- g_free (utf8_filename);
goto error;
}
{
struct stat stat_buf;
gint fd;
-
+ gchar *utf8_filename = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
+
/* O_BINARY useful on Cygwin */
fd = open (filename, O_RDONLY|O_BINARY);
if (fd < 0)
{
- gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
- NULL, NULL, NULL);
g_set_error (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
/* I don't think this will ever fail, aside from ENOMEM, but. */
if (fstat (fd, &stat_buf) < 0)
{
- gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
- NULL, NULL, NULL);
close (fd);
g_set_error (error,
G_FILE_ERROR,
if (stat_buf.st_size > 0 && S_ISREG (stat_buf.st_mode))
{
- return get_contents_regfile (filename,
- &stat_buf,
- fd,
- contents,
- length,
- error);
+ gboolean retval = get_contents_regfile (utf8_filename,
+ &stat_buf,
+ fd,
+ contents,
+ length,
+ error);
+ g_free (utf8_filename);
+
+ return retval;
}
else
{
FILE *f;
+ gboolean retval;
f = fdopen (fd, "r");
if (f == NULL)
{
- gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
- NULL, NULL, NULL);
-
g_set_error (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
return FALSE;
}
- return get_contents_stdio (filename, f, contents, length, error);
+ retval = get_contents_stdio (utf8_filename, f, contents, length, error);
+ g_free (utf8_filename);
+
+ return retval;
}
}
static gboolean
get_contents_win32 (const gchar *filename,
- gchar **contents,
- gsize *length,
- GError **error)
+ gchar **contents,
+ gsize *length,
+ GError **error)
{
FILE *f;
-
- /* I guess you want binary mode; maybe you want text sometimes? */
- f = fopen (filename, "rb");
+ gboolean retval;
+ wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+
+ f = _wfopen (wfilename, L"rb");
+ g_free (wfilename);
if (f == NULL)
{
return FALSE;
}
- return get_contents_stdio (filename, f, contents, length, error);
+ retval = get_contents_stdio (filename, f, contents, length, error);
+
+ return retval;
}
#endif
/**
* g_file_get_contents:
- * @filename: a file to read contents from
+ * @filename: name of a file to read contents from, in the encoding used for filenames
* @contents: location to store an allocated string
* @length: location to store length in bytes of the contents
* @error: return location for a #GError
#endif
}
+#ifdef G_OS_WIN32
+
+#undef g_file_get_contents
+
+/* Binary compatibility version. Not for newly compiled code. */
+
+gboolean
+g_file_get_contents (const gchar *filename,
+ gchar **contents,
+ gsize *length,
+ GError **error)
+{
+ gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error);
+ gboolean retval;
+
+ if (utf8_filename == NULL)
+ return FALSE;
+
+ retval = g_file_get_contents (utf8_filename, contents, length, error);
+
+ g_free (utf8_filename);
+
+ return retval;
+}
+
+#endif
+
/*
* mkstemp() implementation is from the GNU C library.
* Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
v /= NLETTERS;
XXXXXX[5] = letters[v % NLETTERS];
- fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
+ /* tmpl is in UTF-8 on Windows, thus use g_open() */
+ fd = g_open (tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
if (fd >= 0)
return fd;
#endif
}
+#ifdef G_OS_WIN32
+
+#undef g_mkstemp
+
+/* Binary compatibility version. Not for newly compiled code. */
+
+gint
+g_mkstemp (gchar *tmpl)
+{
+ int len;
+ char *XXXXXX;
+ int count, fd;
+ static const char letters[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ static const int NLETTERS = sizeof (letters) - 1;
+ glong value;
+ GTimeVal tv;
+ static int counter = 0;
+
+ len = strlen (tmpl);
+ if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
+ return -1;
+
+ /* This is where the Xs start. */
+ XXXXXX = &tmpl[len - 6];
+
+ /* Get some more or less random data. */
+ g_get_current_time (&tv);
+ value = (tv.tv_usec ^ tv.tv_sec) + counter++;
+
+ for (count = 0; count < 100; value += 7777, ++count)
+ {
+ glong v = value;
+
+ /* Fill in the random bits. */
+ XXXXXX[0] = letters[v % NLETTERS];
+ v /= NLETTERS;
+ XXXXXX[1] = letters[v % NLETTERS];
+ v /= NLETTERS;
+ XXXXXX[2] = letters[v % NLETTERS];
+ v /= NLETTERS;
+ XXXXXX[3] = letters[v % NLETTERS];
+ v /= NLETTERS;
+ XXXXXX[4] = letters[v % NLETTERS];
+ v /= NLETTERS;
+ XXXXXX[5] = letters[v % NLETTERS];
+
+ /* This is the backward compatibility system codepage version,
+ * thus use normal open().
+ */
+ fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
+
+ if (fd >= 0)
+ return fd;
+ else if (errno != EEXIST)
+ /* Any other error will apply also to other names we might
+ * try, and there are 2^32 or so of them, so give up now.
+ */
+ return -1;
+ }
+
+ /* We got out of the loop because we ran out of combinations to try. */
+ return -1;
+}
+
+#endif
+
/**
* g_file_open_tmp:
* @tmpl: Template for file name, as in g_mkstemp(), basename only
return retval;
}
+#ifdef G_OS_WIN32
+
+#undef g_file_open_tmp
+
+/* Binary compatibility version. Not for newly compiled code. */
+
+gint
+g_file_open_tmp (const gchar *tmpl,
+ gchar **name_used,
+ GError **error)
+{
+ gchar *utf8_tmpl = g_locale_to_utf8 (tmpl, -1, NULL, NULL, error);
+ gchar *utf8_name_used;
+ gint retval;
+
+ if (utf8_tmpl == NULL)
+ return -1;
+
+ retval = g_file_open_tmp_utf8 (utf8_tmpl, &utf8_name_used, error);
+
+ if (retval == -1)
+ return -1;
+
+ if (name_used)
+ *name_used = g_locale_from_utf8 (utf8_name_used, -1, NULL, NULL, NULL);
+
+ g_free (utf8_name_used);
+
+ return retval;
+}
+
+#endif
+
static gchar *
g_build_pathv (const gchar *separator,
const gchar *first_element,
/* So other code can generate a GFileError */
GFileError g_file_error_from_errno (gint err_no);
+#ifdef G_OS_WIN32
+#define g_file_test g_file_test_utf8
+#define g_file_get_contents g_file_get_contents_utf8
+#define g_mkstemp g_mkstemp_utf8
+#define g_file_open_tmp g_file_open_tmp_utf8
+#endif
+
gboolean g_file_test (const gchar *filename,
GFileTest test);
gboolean g_file_get_contents (const gchar *filename,
G_END_DECLS
#endif /* __G_FILEUTILS_H__ */
-
-
#include <errno.h>
#include <sys/stat.h>
+#include "gstdio.h"
#include "glibintl.h"
typedef struct _GIOWin32Channel GIOWin32Channel;
}
/* always open 'untranslated' */
- fid = open (filename, flags | _O_BINARY, pmode);
+ fid = g_open (filename, flags | _O_BINARY, pmode);
if (g_io_win32_get_debug_flag ())
{
return channel;
}
+#ifdef G_OS_WIN32
+
+#undef g_io_channel_new_file
+
+/* Binary compatibility version. Not for newly compiled code. */
+
+GIOChannel *
+g_io_channel_new_file (const gchar *filename,
+ const gchar *mode,
+ GError **error)
+{
+ gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error);
+ GIOChannel *retval;
+
+ if (utf8_filename == NULL)
+ return NULL;
+
+ retval = g_io_channel_new_file_utf8 (utf8_filename, mode, error);
+
+ g_free (utf8_filename);
+
+ return retval;
+}
+
+#endif
+
static GIOStatus
g_io_win32_set_flags (GIOChannel *channel,
GIOFlags flags,
g_dir_close
g_direct_equal
g_direct_hash
-g_dir_open
-g_dir_read_name
+g_dir_open PRIVATE
+#ifdef G_OS_WIN32
+g_dir_open_utf8
+#endif
+g_dir_read_name PRIVATE
+#ifdef G_OS_WIN32
+g_dir_read_name_utf8
+#endif
g_dir_rewind
g_error_copy
g_error_free
g_error_new_literal
g_file_error_from_errno
g_file_error_quark
-g_file_get_contents
+g_file_get_contents PRIVATE
+#ifdef G_OS_WIN32
+g_file_get_contents_utf8
+#endif
g_filename_from_uri
-g_filename_from_utf8
+g_filename_from_utf8 PRIVATE
+#ifdef G_OS_WIN32
+g_filename_from_utf8_utf8
+#endif
g_filename_to_uri
-g_filename_to_utf8
-g_file_open_tmp
+g_filename_to_utf8 PRIVATE
+#ifdef G_OS_WIN32
+g_filename_to_utf8_utf8
+#endif
+g_file_open_tmp PRIVATE
+#ifdef G_OS_WIN32
+g_file_open_tmp_utf8
+#endif
g_file_read_link
-g_file_test
+g_file_test PRIVATE
+#ifdef G_OS_WIN32
+g_file_test_utf8
+#endif
g_find_program_in_path
+g_fopen
g_fprintf
g_free
+g_freopen
g_get_application_name
g_get_charset
-g_get_current_dir
+g_get_current_dir PRIVATE
+#ifdef G_OS_WIN32
+g_get_current_dir_utf8
+#endif
g_get_current_time
g_getenv
-g_get_home_dir
+g_get_home_dir PRIVATE
+#ifdef G_OS_WIN32
+g_get_home_dir_utf8
+#endif
g_get_language_names
g_get_prgname
g_get_real_name
g_get_system_config_dirs
g_get_system_data_dirs
-g_get_tmp_dir
+g_get_tmp_dir PRIVATE
+#ifdef G_OS_WIN32
+g_get_tmp_dir_utf8
+#endif
g_get_user_cache_dir
g_get_user_config_dir
g_get_user_data_dir
g_io_channel_get_flags
g_io_channel_get_line_term
g_io_channel_init
-g_io_channel_new_file
+g_io_channel_new_file PRIVATE
+#ifdef G_OS_WIN32
+g_io_channel_new_file_utf8
+#endif
g_io_channel_read
g_io_channel_read_chars
g_io_channel_read_line
g_mem_is_system_malloc
g_mem_profile
g_mem_set_vtable
-g_mkstemp
+g_mkdir
+g_mkstemp PRIVATE
+#ifdef G_OS_WIN32
+g_mkstemp_utf8
+#endif
g_node_child_index
g_node_child_position
g_node_children_foreach
g_once_impl
g_on_error_query
g_on_error_stack_trace
+g_open
g_option_context_add_group
g_option_context_add_main_entries
g_option_error_quark
g_relation_new
g_relation_print
g_relation_select
+g_remove
+g_rename
g_return_if_fail_warning
g_scanner_cur_line
g_scanner_cur_position
g_spawn_error_quark
g_spawn_sync
g_sprintf
+g_stat
g_static_mutex_free
g_static_mutex_get_mutex_impl
g_static_mutex_init
g_unichar_xdigit_value
g_unicode_canonical_decomposition
g_unicode_canonical_ordering
+g_unlink
g_unsetenv
g_uri_list_extract_uris
g_usleep
--- /dev/null
+/* gstdio.c - wrappers for C library functions
+ *
+ * Copyright 2004 Tor Lillqvist
+ *
+ * GLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GLib; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef G_OS_WIN32
+#include <wchar.h>
+#include <io.h>
+#endif
+
+#include "galias.h"
+#include "glib.h"
+#include "gstdio.h"
+
+#if !defined (G_OS_UNIX) && !defined (G_OS_WIN32)
+#error Please port this to your operating system
+#endif
+
+
+/**
+ * g_open:
+ * @filename: a pathname in the GLib file name encoding
+ * @flags: as in open()
+ * @mode: as in open()
+ *
+ * A wrapper for the POSIX open() function. The open() function is used
+ * to convert a pathname into a file descriptor.
+ *
+ * See the C library manual for more details about open().
+ *
+ * The point of these wrappers is to make it possible to handle file
+ * names with any Unicode characters in them on Windows without having
+ * to use ifdefs and the wide character API in the application code.
+ *
+ * The pathname argument should be in the GLib file name encoding. On
+ * POSIX this is the actual on-disk encoding which might correspond to
+ * the locale settings of the process (or the
+ * <envar>G_FILENAME_ENCODING</envar> environment variable), or not.
+ *
+ * On Windows the GLib file name encoding is UTF-8. Note that the
+ * Microsoft C library does not use UTF-8, but has separate APIs for
+ * current system code page and wide characters (UTF-16). The GLib
+ * wrappers call the wide character API if present (on modern Windows
+ * systems), otherwise convert to/from the system code page.
+ *
+ * Returns: a new file descriptor, or -1 if an error occurred
+ *
+ * Since: 2.6
+ */
+int
+g_open (const gchar *filename,
+ int flags,
+ int mode)
+{
+#ifdef G_OS_WIN32
+ if (G_WIN32_HAVE_WIDECHAR_API ())
+ {
+ wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+ int retval = _wopen (wfilename, flags, mode);
+ int save_errno = errno;
+
+ g_free (wfilename);
+
+ errno = save_errno;
+ return retval;
+ }
+ else
+ {
+ gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
+ int retval = open (cp_filename, flags, mode);
+ int save_errno = errno;
+
+ g_free (cp_filename);
+
+ errno = save_errno;
+ return retval;
+ }
+#else
+ return open (filename, flags, mode);
+#endif
+}
+
+/**
+ * g_rename:
+ * @oldfilename: a pathname in the GLib file name encoding
+ * @newfilename: a pathname in the GLib file name encoding
+ *
+ * A wrapper for the POSIX rename() function. The rename() function
+ * renames a file, moving it between directories if required.
+ *
+ * See the C library manual for more details about rename().
+ *
+ * Returns: 0 if the renaming succeeded, -1 if an error occurred
+ *
+ * Since: 2.6
+ */
+int
+g_rename (const gchar *oldfilename,
+ const gchar *newfilename)
+{
+#ifdef G_OS_WIN32
+ if (G_WIN32_HAVE_WIDECHAR_API ())
+ {
+ wchar_t *woldfilename = g_utf8_to_utf16 (oldfilename, -1, NULL, NULL, NULL);
+ wchar_t *wnewfilename = g_utf8_to_utf16 (newfilename, -1, NULL, NULL, NULL);
+ int retval = _wrename (woldfilename, wnewfilename);
+ int save_errno = errno;
+
+ g_free (woldfilename);
+ g_free (wnewfilename);
+
+ errno = save_errno;
+ return retval;
+ }
+ else
+ {
+ gchar *cp_oldfilename = g_locale_from_utf8 (oldfilename, -1, NULL, NULL, NULL);
+ gchar *cp_newfilename = g_locale_from_utf8 (newfilename, -1, NULL, NULL, NULL);
+ int retval = rename (cp_oldfilename, cp_newfilename);
+ int save_errno = errno;
+
+ g_free (cp_oldfilename);
+ g_free (cp_newfilename);
+
+ errno = save_errno;
+ return retval;
+ }
+#else
+ return rename (oldfilename, newfilename);
+#endif
+}
+
+/**
+ * g_mkdir:
+ * @filename: a pathname in the GLib file name encoding
+ * @mode: permissions to use for the newly created directory
+ *
+ * A wrapper for the POSIX mkdir() function. The mkdir() function
+ * attempts to create a directory with the given name and permissions.
+ *
+ * See the C library manual for more details about mkdir().
+ *
+ * Returns: 0 if the directory was successfully created, -1 if an error
+ * occurred
+ *
+ * Since: 2.6
+ */
+int
+g_mkdir (const gchar *filename,
+ int mode)
+{
+#ifdef G_OS_WIN32
+ if (G_WIN32_HAVE_WIDECHAR_API ())
+ {
+ wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+ int retval = _wmkdir (wfilename);
+ int save_errno = errno;
+
+ g_free (wfilename);
+
+ errno = save_errno;
+ return retval;
+ }
+ else
+ {
+ gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
+ int retval = mkdir (cp_filename);
+ int save_errno = errno;
+
+ g_free (cp_filename);
+
+ errno = save_errno;
+ return retval;
+ }
+#else
+ return mkdir (filename, mode);
+#endif
+}
+
+/**
+ * g_stat:
+ * @filename: a pathname in the GLib file name encoding
+ * @buf: a pointer to a <structname>stat</structname> struct, which
+ * will be filled with the file information
+ *
+ * A wrapper for the POSIX stat() function. The stat() function
+ * returns information about a file.
+ *
+ * See the C library manual for more details about stat().
+ *
+ * Returns: 0 if the directory was successfully created, -1 if an error
+ * occurred
+ *
+ * Since: 2.6
+ */
+int
+g_stat (const gchar *filename,
+ struct stat *buf)
+{
+#ifdef G_OS_WIN32
+ if (G_WIN32_HAVE_WIDECHAR_API ())
+ {
+ wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+ int retval = _wstat (wfilename, (struct _stat *) buf);
+ int save_errno = errno;
+
+ g_free (wfilename);
+
+ errno = save_errno;
+ return retval;
+ }
+ else
+ {
+ gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
+ int retval = stat (cp_filename, buf);
+ int save_errno = errno;
+
+ g_free (cp_filename);
+
+ errno = save_errno;
+ return retval;
+ }
+#else
+ return stat (filename, buf);
+#endif
+}
+
+/**
+ * g_unlink:
+ * @filename: a pathname in the GLib file name encoding
+ *
+ * A wrapper for the POSIX unlink() function. The unlink() function
+ * deletes a name from the filesystem. If this was the last link to the
+ * file and no processes have it opened, the diskspace occupied by the
+ * file is freed.
+ *
+ * See the C library manual for more details about unlink().
+ *
+ * Returns: 0 if the directory was successfully created, -1 if an error
+ * occurred
+ *
+ * Since: 2.6
+ */
+int
+g_unlink (const gchar *filename)
+{
+#ifdef G_OS_WIN32
+ if (G_WIN32_HAVE_WIDECHAR_API ())
+ {
+ wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+ int retval = _wunlink (wfilename);
+ int save_errno = errno;
+
+ g_free (wfilename);
+
+ errno = save_errno;
+ return retval;
+ }
+ else
+ {
+ gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
+ int retval = unlink (cp_filename);
+ int save_errno = errno;
+
+ g_free (cp_filename);
+
+ errno = save_errno;
+ return retval;
+ }
+#else
+ return unlink (filename);
+#endif
+}
+
+/**
+ * g_remove:
+ * @filename: a pathname in the GLib file name encoding
+ *
+ * A wrapper for the POSIX remove() function. The remove() function
+ * deletes a name from the filesystem. It calls unlink() for files
+ * and rmdir() for directories.
+ *
+ * See the C library manual for more details about remove().
+ *
+ * Returns: 0 if the directory was successfully created, -1 if an error
+ * occurred
+ *
+ * Since: 2.6
+ */
+int
+g_remove (const gchar *filename)
+{
+#ifdef G_OS_WIN32
+ if (G_WIN32_HAVE_WIDECHAR_API ())
+ {
+ wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+ int retval = _wremove (wfilename);
+ int save_errno = errno;
+
+ g_free (wfilename);
+
+ errno = save_errno;
+ return retval;
+ }
+ else
+ {
+ gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
+ int retval = remove (cp_filename);
+ int save_errno = errno;
+
+ g_free (cp_filename);
+
+ errno = save_errno;
+ return retval;
+ }
+#else
+ return remove (filename);
+#endif
+}
+
+/**
+ * g_fopen:
+ * @filename: a pathname in the GLib file name encoding
+ * @mode: a string describing the mode in which the file should be
+ * opened
+ *
+ * A wrapper for the POSIX fopen() function. The fopen() function opens
+ * a file and associates a new stream with it.
+ *
+ * See the C library manual for more details about fopen().
+ *
+ * Returns: A <typename>FILE</typename> pointer if the file was successfully
+ * opened, or %NULL if an error occurred
+ *
+ * Since: 2.6
+ */
+FILE *
+g_fopen (const gchar *filename,
+ const gchar *mode)
+{
+#ifdef G_OS_WIN32
+ if (G_WIN32_HAVE_WIDECHAR_API ())
+ {
+ wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+ wchar_t *wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL);
+ FILE *retval = _wfopen (wfilename, wmode);
+ int save_errno = errno;
+
+ g_free (wfilename);
+ g_free (wmode);
+
+ errno = save_errno;
+ return retval;
+ }
+ else
+ {
+ gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
+ FILE *retval = fopen (cp_filename, mode);
+ int save_errno = errno;
+
+ g_free (cp_filename);
+
+ errno = save_errno;
+ return retval;
+ }
+#else
+ return fopen (filename, mode);
+#endif
+}
+
+/**
+ * g_freopen:
+ * @filename: a pathname in the GLib file name encoding
+ * @mode: a string describing the mode in which the file should be
+ * opened
+ * @stream: an existing stream which will be reused, or %NULL
+ *
+ * A wrapper for the POSIX freopen() function. The freopen() function
+ * opens a file and associates it with an existing stream.
+ *
+ * See the C library manual for more details about freopen().
+ *
+ * Returns: A <typename>FILE</typename> pointer if the file was successfully
+ * opened, or %NULL if an error occurred.
+ *
+ * Since: 2.6
+ */
+FILE *
+g_freopen (const gchar *filename,
+ const gchar *mode,
+ FILE *stream)
+{
+#ifdef G_OS_WIN32
+ if (G_WIN32_HAVE_WIDECHAR_API ())
+ {
+ wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+ wchar_t *wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL);
+ FILE *retval = _wfreopen (wfilename, wmode, stream);
+ int save_errno = errno;
+
+ g_free (wfilename);
+ g_free (wmode);
+
+ errno = save_errno;
+ return retval;
+ }
+ else
+ {
+ gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
+ FILE *retval = freopen (cp_filename, mode, stream);
+ int save_errno = errno;
+
+ g_free (cp_filename);
+
+ errno = save_errno;
+ return retval;
+ }
+#else
+ return freopen (filename, mode, stream);
+#endif
+}
--- /dev/null
+/* gstdio.h - GFilename wrappers for C library functions
+ *
+ * Copyright 2004 Tor Lillqvist
+ *
+ * GLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GLib; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __G_STDIO_H__
+#define __G_STDIO_H__
+
+#include <glib/gprintf.h>
+
+#include <sys/stat.h>
+
+/* Wrappers for C library functions that take pathname arguments. On
+ * Unix, the pathname is a file name as it literally is in the file
+ * system. On well-maintained systems with consistent users who know
+ * what they are doing and no exchange of files with others this would
+ * be a well-defined encoding, preferrably UTF-8. On Windows, the
+ * pathname is always in UTF-8, even if that is not the on-disk
+ * encoding or the encoding used by the Win32 API.
+ */
+
+int g_open (const gchar *filename,
+ int flags,
+ int mode);
+
+int g_rename (const gchar *oldfilename,
+ const gchar *newfilename);
+
+int g_mkdir (const gchar *filename,
+ int mode);
+
+int g_stat (const gchar *filename,
+ struct stat *buf);
+
+int g_unlink (const gchar *filename);
+
+int g_remove (const gchar *filename);
+
+FILE *g_fopen (const gchar *filename,
+ const gchar *mode);
+
+FILE *g_freopen (const gchar *filename,
+ const gchar *mode,
+ FILE *stream);
+
+#endif /* __G_STDIO_H__ */
buffer[1] = 0;
}
+#ifdef G_OS_WIN32
+ dir = g_locale_to_utf8 (buffer, -1, NULL, NULL, NULL);
+#else
dir = g_strdup (buffer);
+#endif
g_free (buffer);
return dir;
}
+#ifdef G_OS_WIN32
+
+#undef g_get_current_dir
+
+/* Binary compatibility version. Not for newly compiled code. */
+
+gchar*
+g_get_current_dir (void)
+{
+ gchar *utf8_dir = g_get_current_dir_utf8 ();
+ gchar *dir = g_locale_from_utf8 (utf8_dir, -1, NULL, NULL, NULL);
+ g_free (utf8_dir);
+ return dir;
+}
+
+#endif
+
/**
* g_getenv:
* @variable: the environment variable to get.
return g_home_dir;
}
+#ifdef G_OS_WIN32
+
+#undef g_get_home_dir
+
+G_CONST_RETURN gchar*
+g_get_home_dir (void)
+{
+ static gchar *home_dir = NULL;
+
+ G_LOCK (g_utils_global);
+ if (!g_tmp_dir)
+ g_get_any_init ();
+ if (!home_dir && g_home_dir)
+ home_dir = g_locale_from_utf8 (g_home_dir, -1, NULL, NULL, NULL);
+ G_UNLOCK (g_utils_global);
+
+ return home_dir;
+}
+
+#endif
+
/* Return a directory to be used to store temporary files. This is the
* value of the TMPDIR, TMP or TEMP environment variables (they are
* checked in that order). If none of those exist, use P_tmpdir from
return g_tmp_dir;
}
+#ifdef G_OS_WIN32
+
+#undef g_get_tmp_dir
+
+G_CONST_RETURN gchar*
+g_get_tmp_dir (void)
+{
+ static gchar *tmp_dir = NULL;
+
+ G_LOCK (g_utils_global);
+ if (!g_tmp_dir)
+ g_get_any_init ();
+ if (!tmp_dir)
+ tmp_dir = g_locale_from_utf8 (g_tmp_dir, -1, NULL, NULL, NULL);
+
+ if (tmp_dir == NULL)
+ tmp_dir = "C:\\";
+ G_UNLOCK (g_utils_global);
+
+ return tmp_dir;
+}
+
+#endif
+
G_LOCK_DEFINE_STATIC (g_prgname);
static gchar *g_prgname = NULL;
/* Retrive static string info
*/
+#ifdef G_OS_WIN32
+#define g_get_home_dir g_get_home_dir_utf8
+#define g_get_tmp_dir g_get_tmp_dir_utf8
+#endif
G_CONST_RETURN gchar* g_get_user_name (void);
G_CONST_RETURN gchar* g_get_real_name (void);
G_CONST_RETURN gchar* g_get_home_dir (void);
#endif /* G_DISABLE_DEPRECATED */
+#ifdef G_OS_WIN32
+#define g_get_current_dir g_get_current_dir_utf8
+#endif
+
/* The returned strings are newly allocated with g_malloc() */
gchar* g_get_current_dir (void);
gchar* g_path_get_basename (const gchar *file_name);
#include "glib.h"
-#include "gprintf.h"
+#include "gstdio.h"
#ifdef G_OS_WIN32
#include "gwin32.h"
#endif
next;
}
-
my $str = $_;
+ # Drop any Win32 specific .def file syntax
+ $str = (split (/ /, $str))[0];
chomp($str);
my $alias = "IA__".$str;