mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Add a few functions from GLib 2.8 in lib/glib28.
Remove empty directory lib/glib26. Add lib/glib28 instead with the necessary sources and headers to have the following functions even on a GLib 2.6 system (!defined(HAVE_GLIB_2_8)) - g_access, g_chmod, - g_file_set_contents, - g_win32_locale_filename_from_utf8. Make use of them, improving r15429 and r15430. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@15445 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
20
configure.in
20
configure.in
@@ -193,6 +193,25 @@ then
|
||||
AC_MSG_ERROR([Cannot find glib. Check config.log])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(for GLIB - version >= 2.8.0)
|
||||
if $PKG_CONFIG 'glib-2.0 >= 2.8.0'
|
||||
then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_GLIB_2_8,1,[System has glib 2.8.0 or better])
|
||||
HAVE_GLIB_2_8=yes
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test "x${native_win32}" = "xyes"; then
|
||||
AC_MSG_ERROR([*** GLIB >= 2.8 is required to build Gnucash on Windows.])
|
||||
else
|
||||
GLIB26_LIBS="$GLIB_LIBS"
|
||||
GLIB_LIBS="\${top_builddir}/lib/glib28/libgnc-glib.la $GLIB_LIBS"
|
||||
GLIB_CFLAGS="-I\${top_srcdir}/lib/glib28 $GLIB_CFLAGS"
|
||||
AC_SUBST(GLIB26_LIBS)
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_GLIB_2_8, test "x$HAVE_GLIB_2_8" = "xyes")
|
||||
|
||||
AC_MSG_CHECKING(for GLIB - version >= 2.9.0)
|
||||
if $PKG_CONFIG 'glib-2.0 >= 2.9.0'
|
||||
then
|
||||
@@ -2050,6 +2069,7 @@ AC_CONFIG_FILES(po/Makefile.in
|
||||
doc/examples/Makefile
|
||||
intl-scm/Makefile
|
||||
lib/Makefile
|
||||
lib/glib28/Makefile
|
||||
lib/guile-www/Makefile
|
||||
lib/srfi/Makefile
|
||||
lib/libc/Makefile
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
SUBDIRS = libc guile-www srfi
|
||||
DIST_SUBDIRS = libc guile-www srfi libgsf-1.12.3 goffice-0.0.4 libqof
|
||||
SUBDIRS = libc glib28 guile-www srfi
|
||||
DIST_SUBDIRS = libc glib28 guile-www srfi libgsf-1.12.3 goffice-0.0.4 libqof
|
||||
|
||||
if !HAVE_GOFFICE
|
||||
if !HAVE_LIBGSF
|
||||
|
||||
18
lib/glib28/Makefile.am
Normal file
18
lib/glib28/Makefile.am
Normal file
@@ -0,0 +1,18 @@
|
||||
noinst_LTLIBRARIES = libgnc-glib.la
|
||||
|
||||
DUMMYSRCS = dummy.c
|
||||
REALSRCS = gfileutils-2.8.c gwin32-2.8.c
|
||||
REALHDRS = gfileutils-2.8.h gstdio-2.8.h gwin32-2.8.h
|
||||
|
||||
if HAVE_GLIB_2_8
|
||||
libgnc_glib_la_SOURCES = ${DUMMYSRCS}
|
||||
else
|
||||
libgnc_glib_la_SOURCES = ${REALSRCS}
|
||||
noinst_HEADERS = ${REALHDRS}
|
||||
endif
|
||||
|
||||
libgnc_glib_la_LIBADD = ${GLIB26_LIBS}
|
||||
|
||||
AM_CFLAGS = ${GLIB_CFLAGS}
|
||||
|
||||
EXTRA_DIST = $(DUMMYSRCS) ${REALSRCS} $(REALHDRS)
|
||||
6
lib/glib28/dummy.c
Normal file
6
lib/glib28/dummy.c
Normal file
@@ -0,0 +1,6 @@
|
||||
void g_my_dummy_function (void);
|
||||
|
||||
void
|
||||
g_my_dummy_function (void)
|
||||
{
|
||||
}
|
||||
433
lib/glib28/gfileutils-2.8.c
Normal file
433
lib/glib28/gfileutils-2.8.c
Normal file
@@ -0,0 +1,433 @@
|
||||
/* gfileutils.c - File utility functions
|
||||
*
|
||||
* Copyright 2000 Red Hat, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
/* Contains all #includes, but otherwise only relevant differences between
|
||||
* GLib 2.6 and GLib 2.8 */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifndef G_OS_WIN32
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#endif /* G_OS_WIN32 */
|
||||
|
||||
#ifndef S_ISLNK
|
||||
#define S_ISLNK(x) 0
|
||||
#endif
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
|
||||
static gboolean
|
||||
rename_file (const char *old_name,
|
||||
const char *new_name,
|
||||
GError **err)
|
||||
{
|
||||
errno = 0;
|
||||
if (g_rename (old_name, new_name) == -1)
|
||||
{
|
||||
int save_errno = errno;
|
||||
gchar *display_old_name = g_filename_display_name (old_name);
|
||||
gchar *display_new_name = g_filename_display_name (new_name);
|
||||
|
||||
g_set_error (err,
|
||||
G_FILE_ERROR,
|
||||
g_file_error_from_errno (save_errno),
|
||||
"Failed to rename file '%s' to '%s': g_rename() failed: %s",
|
||||
display_old_name,
|
||||
display_new_name,
|
||||
g_strerror (save_errno));
|
||||
|
||||
g_free (display_old_name);
|
||||
g_free (display_new_name);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_umask_permissions (int fd,
|
||||
GError **err)
|
||||
{
|
||||
#ifdef G_OS_WIN32
|
||||
|
||||
return TRUE;
|
||||
|
||||
#else
|
||||
/* All of this function is just to work around the fact that
|
||||
* there is no way to get the umask without changing it.
|
||||
*
|
||||
* We can't just change-and-reset the umask because that would
|
||||
* lead to a race condition if another thread tried to change
|
||||
* the umask in between the getting and the setting of the umask.
|
||||
* So we have to do the whole thing in a child process.
|
||||
*/
|
||||
|
||||
int save_errno;
|
||||
pid_t pid;
|
||||
|
||||
pid = fork ();
|
||||
|
||||
if (pid == -1)
|
||||
{
|
||||
save_errno = errno;
|
||||
g_set_error (err,
|
||||
G_FILE_ERROR,
|
||||
g_file_error_from_errno (save_errno),
|
||||
_("Could not change file mode: fork() failed: %s"),
|
||||
g_strerror (save_errno));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
else if (pid == 0)
|
||||
{
|
||||
/* child */
|
||||
mode_t mask = umask (0666);
|
||||
|
||||
errno = 0;
|
||||
if (fchmod (fd, 0666 & ~mask) == -1)
|
||||
_exit (errno);
|
||||
else
|
||||
_exit (0);
|
||||
|
||||
return TRUE; /* To quiet gcc */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* parent */
|
||||
int status;
|
||||
|
||||
errno = 0;
|
||||
if (waitpid (pid, &status, 0) == -1)
|
||||
{
|
||||
save_errno = errno;
|
||||
|
||||
g_set_error (err,
|
||||
G_FILE_ERROR,
|
||||
g_file_error_from_errno (save_errno),
|
||||
_("Could not change file mode: waitpid() failed: %s"),
|
||||
g_strerror (save_errno));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (WIFEXITED (status))
|
||||
{
|
||||
save_errno = WEXITSTATUS (status);
|
||||
|
||||
if (save_errno == 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_error (err,
|
||||
G_FILE_ERROR,
|
||||
g_file_error_from_errno (save_errno),
|
||||
_("Could not change file mode: chmod() failed: %s"),
|
||||
g_strerror (save_errno));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (WIFSIGNALED (status))
|
||||
{
|
||||
g_set_error (err,
|
||||
G_FILE_ERROR,
|
||||
G_FILE_ERROR_FAILED,
|
||||
_("Could not change file mode: Child terminated by signal: %s"),
|
||||
g_strsignal (WTERMSIG (status)));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This shouldn't happen */
|
||||
g_set_error (err,
|
||||
G_FILE_ERROR,
|
||||
G_FILE_ERROR_FAILED,
|
||||
_("Could not change file mode: Child terminated abnormally"));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static gchar *
|
||||
write_to_temp_file (const gchar *contents,
|
||||
gssize length,
|
||||
const gchar *template,
|
||||
GError **err)
|
||||
{
|
||||
gchar *tmp_name;
|
||||
gchar *display_name;
|
||||
gchar *retval;
|
||||
FILE *file;
|
||||
gint fd;
|
||||
int save_errno;
|
||||
|
||||
retval = NULL;
|
||||
|
||||
tmp_name = g_strdup_printf ("%s.XXXXXX", template);
|
||||
|
||||
errno = 0;
|
||||
fd = g_mkstemp (tmp_name);
|
||||
display_name = g_filename_display_name (tmp_name);
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
save_errno = errno;
|
||||
g_set_error (err,
|
||||
G_FILE_ERROR,
|
||||
g_file_error_from_errno (save_errno),
|
||||
"Failed to create file '%s': %s",
|
||||
display_name, g_strerror (save_errno));
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!set_umask_permissions (fd, err))
|
||||
{
|
||||
close (fd);
|
||||
g_unlink (tmp_name);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
file = fdopen (fd, "wb");
|
||||
if (!file)
|
||||
{
|
||||
save_errno = errno;
|
||||
g_set_error (err,
|
||||
G_FILE_ERROR,
|
||||
g_file_error_from_errno (save_errno),
|
||||
"Failed to open file '%s' for writing: fdopen() failed: %s",
|
||||
display_name,
|
||||
g_strerror (save_errno));
|
||||
|
||||
close (fd);
|
||||
g_unlink (tmp_name);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
size_t n_written;
|
||||
|
||||
errno = 0;
|
||||
|
||||
n_written = fwrite (contents, 1, length, file);
|
||||
|
||||
if (n_written < length)
|
||||
{
|
||||
save_errno = errno;
|
||||
|
||||
g_set_error (err,
|
||||
G_FILE_ERROR,
|
||||
g_file_error_from_errno (save_errno),
|
||||
"Failed to write file '%s': fwrite() failed: %s",
|
||||
display_name,
|
||||
g_strerror (save_errno));
|
||||
|
||||
fclose (file);
|
||||
g_unlink (tmp_name);
|
||||
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
if (fclose (file) == EOF)
|
||||
{
|
||||
save_errno = 0;
|
||||
|
||||
g_set_error (err,
|
||||
G_FILE_ERROR,
|
||||
g_file_error_from_errno (save_errno),
|
||||
"Failed to close file '%s': fclose() failed: %s",
|
||||
display_name,
|
||||
g_strerror (save_errno));
|
||||
|
||||
g_unlink (tmp_name);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
retval = g_strdup (tmp_name);
|
||||
|
||||
out:
|
||||
g_free (tmp_name);
|
||||
g_free (display_name);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_file_set_contents:
|
||||
* @filename: name of a file to write @contents to, in the GLib file name
|
||||
* encoding
|
||||
* @contents: string to write to the file
|
||||
* @length: length of @contents, or -1 if @contents is a nul-terminated string
|
||||
* @error: return location for a #GError, or %NULL
|
||||
*
|
||||
* Writes all of @contents to a file named @filename, with good error checking.
|
||||
* If a file called @filename already exists it will be overwritten.
|
||||
*
|
||||
* This write is atomic in the sense that it is first written to a temporary
|
||||
* file which is then renamed to the final name. Notes:
|
||||
* <itemizedlist>
|
||||
* <listitem>
|
||||
* On Unix, if @filename already exists hard links to @filename will break.
|
||||
* Also since the file is recreated, existing permissions, access control
|
||||
* lists, metadata etc. may be lost. If @filename is a symbolic link,
|
||||
* the link itself will be replaced, not the linked file.
|
||||
* </listitem>
|
||||
* <listitem>
|
||||
* On Windows renaming a file will not remove an existing file with the
|
||||
* new name, so on Windows there is a race condition between the existing
|
||||
* file being removed and the temporary file being renamed.
|
||||
* </listitem>
|
||||
* <listitem>
|
||||
* On Windows there is no way to remove a file that is open to some
|
||||
* process, or mapped into memory. Thus, this function will fail if
|
||||
* @filename already exists and is open.
|
||||
* </listitem>
|
||||
* </itemizedlist>
|
||||
*
|
||||
* If the call was sucessful, it returns %TRUE. If the call was not successful,
|
||||
* it returns %FALSE and sets @error. The error domain is #G_FILE_ERROR.
|
||||
* Possible error codes are those in the #GFileError enumeration.
|
||||
*
|
||||
* Return value: %TRUE on success, %FALSE if an error occurred
|
||||
*
|
||||
* Since: 2.8
|
||||
**/
|
||||
gboolean
|
||||
g_file_set_contents (const gchar *filename,
|
||||
const gchar *contents,
|
||||
gssize length,
|
||||
GError **error)
|
||||
{
|
||||
gchar *tmp_filename;
|
||||
gboolean retval;
|
||||
GError *rename_error = NULL;
|
||||
|
||||
g_return_val_if_fail (filename != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
g_return_val_if_fail (contents != NULL || length == 0, FALSE);
|
||||
g_return_val_if_fail (length >= -1, FALSE);
|
||||
|
||||
if (length == -1)
|
||||
length = strlen (contents);
|
||||
|
||||
tmp_filename = write_to_temp_file (contents, length, filename, error);
|
||||
|
||||
if (!tmp_filename)
|
||||
{
|
||||
retval = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!rename_file (tmp_filename, filename, &rename_error))
|
||||
{
|
||||
#ifndef G_OS_WIN32
|
||||
|
||||
g_unlink (tmp_filename);
|
||||
g_propagate_error (error, rename_error);
|
||||
retval = FALSE;
|
||||
goto out;
|
||||
|
||||
#else /* G_OS_WIN32 */
|
||||
|
||||
/* Renaming failed, but on Windows this may just mean
|
||||
* the file already exists. So if the target file
|
||||
* exists, try deleting it and do the rename again.
|
||||
*/
|
||||
if (!g_file_test (filename, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_unlink (tmp_filename);
|
||||
g_propagate_error (error, rename_error);
|
||||
retval = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
g_error_free (rename_error);
|
||||
|
||||
if (g_unlink (filename) == -1)
|
||||
{
|
||||
gchar *display_filename = g_filename_display_name (filename);
|
||||
|
||||
int save_errno = errno;
|
||||
|
||||
g_set_error (error,
|
||||
G_FILE_ERROR,
|
||||
g_file_error_from_errno (save_errno),
|
||||
"Existing file '%s' could not be removed: g_unlink() failed: %s",
|
||||
display_filename,
|
||||
g_strerror (save_errno));
|
||||
|
||||
g_free (display_filename);
|
||||
g_unlink (tmp_filename);
|
||||
retval = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!rename_file (tmp_filename, filename, error))
|
||||
{
|
||||
g_unlink (tmp_filename);
|
||||
retval = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
out:
|
||||
g_free (tmp_filename);
|
||||
return retval;
|
||||
}
|
||||
34
lib/glib28/gfileutils-2.8.h
Normal file
34
lib/glib28/gfileutils-2.8.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/* gfileutils.h - File utility functions
|
||||
*
|
||||
* Copyright 2000 Red Hat, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
/* Contains only relevant differences between GLib 2.6 and GLib 2.8 */
|
||||
|
||||
#ifndef __G_FILEUTILS_2_8_H__
|
||||
#define __G_FILEUTILS_2_8_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gboolean g_file_set_contents (const gchar *filename,
|
||||
const gchar *contents,
|
||||
gssize length,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __G_FILEUTILS_2_8_H__ */
|
||||
38
lib/glib28/gstdio-2.8.h
Normal file
38
lib/glib28/gstdio-2.8.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* 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.
|
||||
*/
|
||||
/* Contains only relevant differences between GLib 2.6 and GLib 2.8 */
|
||||
|
||||
#ifndef __G_STDIO_28_H__
|
||||
#define __G_STDIO_28_H__
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
#error "On Windows HAVE_GLIB_2_8 must be defined and gstdio28.h not included."
|
||||
#endif
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define g_access access
|
||||
#define g_chmod chmod
|
||||
#define g_creat creat
|
||||
#define g_chdir chdir
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __G_STDIO_H__ */
|
||||
101
lib/glib28/gwin32-2.8.c
Normal file
101
lib/glib28/gwin32-2.8.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/* GLIB - Library of useful routines for C programming
|
||||
* Copyright (C) 1995-1998 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
* Copyright (C) 1998-1999 Tor Lillqvist
|
||||
*
|
||||
* This library 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.
|
||||
*
|
||||
* This library 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 this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/* Contains all #includes, but otherwise only relevant differences between
|
||||
* GLib 2.6 and GLib 2.8 */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glibconfig.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define STRICT /* Strict typing, please */
|
||||
#include <windows.h>
|
||||
#undef STRICT
|
||||
#ifndef G_WITH_CYGWIN
|
||||
#include <direct.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#ifdef _MSC_VER
|
||||
# include <io.h>
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
|
||||
/**
|
||||
* g_win32_locale_filename_from_utf8:
|
||||
* @utf8filename: a UTF-8 encoded filename.
|
||||
*
|
||||
* Converts a filename from UTF-8 to the system codepage.
|
||||
*
|
||||
* On NT-based Windows, on NTFS file systems, file names are in
|
||||
* Unicode. It is quite possible that Unicode file names contain
|
||||
* characters not representable in the system codepage. (For instance,
|
||||
* Greek or Cyrillic characters on Western European or US Windows
|
||||
* installations, or various less common CJK characters on CJK Windows
|
||||
* installations.)
|
||||
*
|
||||
* In such a case, and if the filename refers to an existing file, and
|
||||
* the file system stores alternate short (8.3) names for directory
|
||||
* entries, the short form of the filename is returned. Note that the
|
||||
* "short" name might in fact be longer than the Unicode name if the
|
||||
* Unicode name has very short pathname components containing
|
||||
* non-ASCII characters. If no system codepage name for the file is
|
||||
* possible, %NULL is returned.
|
||||
*
|
||||
* The return value is dynamically allocated and should be freed with
|
||||
* g_free() when no longer needed.
|
||||
*
|
||||
* Return value: The converted filename, or %NULL on conversion
|
||||
* failure and lack of short names.
|
||||
*
|
||||
* Since: 2.8
|
||||
*/
|
||||
gchar *
|
||||
g_win32_locale_filename_from_utf8 (const gchar *utf8filename)
|
||||
{
|
||||
gchar *retval = g_locale_from_utf8 (utf8filename, -1, NULL, NULL, NULL);
|
||||
|
||||
if (retval == NULL && G_WIN32_HAVE_WIDECHAR_API ())
|
||||
{
|
||||
/* Conversion failed, so convert to wide chars, check if there
|
||||
* is a 8.3 version, and use that.
|
||||
*/
|
||||
wchar_t *wname = g_utf8_to_utf16 (utf8filename, -1, NULL, NULL, NULL);
|
||||
if (wname != NULL)
|
||||
{
|
||||
wchar_t wshortname[MAX_PATH + 1];
|
||||
if (GetShortPathNameW (wname, wshortname, G_N_ELEMENTS (wshortname)))
|
||||
{
|
||||
gchar *tem = g_utf16_to_utf8 (wshortname, -1, NULL, NULL, NULL);
|
||||
retval = g_locale_from_utf8 (tem, -1, NULL, NULL, NULL);
|
||||
g_free (tem);
|
||||
}
|
||||
g_free (wname);
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
30
lib/glib28/gwin32-2.8.h
Normal file
30
lib/glib28/gwin32-2.8.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/* GLIB - Library of useful routines for C programming
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* This library 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.
|
||||
*
|
||||
* This library 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 this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/* Contains only relevant differences between GLib 2.6 and GLib 2.8 */
|
||||
|
||||
#ifndef __G_WIN32_2_8_H__
|
||||
#define __G_WIN32_2_8_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gchar* g_win32_locale_filename_from_utf8 (const gchar *utf8filename);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __G_WIN32_2_8_H__ */
|
||||
@@ -33,9 +33,11 @@
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <glib/gstdio.h>
|
||||
#ifndef HAVE_GLIB_2_8
|
||||
#include <gstdio-2.8.h>
|
||||
#endif
|
||||
#include <libintl.h>
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -288,18 +290,7 @@ file_session_end(QofBackend *be_start)
|
||||
#ifdef G_OS_WIN32
|
||||
/* On windows, we need to allow write-access before
|
||||
g_unlink() can succeed */
|
||||
wchar_t *wlock = g_utf8_to_utf16 (be->lockfile, -1, NULL, NULL, NULL);
|
||||
if (wlock) {
|
||||
rv = _wchmod (wlock, _S_IWRITE);
|
||||
} else {
|
||||
errno = EINVAL;
|
||||
rv = 1;
|
||||
}
|
||||
if (rv) {
|
||||
PWARN("Error on chmod(%s): %d: %s", be->lockfile,
|
||||
errno, strerror(errno) ? strerror(errno) : "");
|
||||
}
|
||||
g_free (wlock);
|
||||
rv = g_chmod (be->lockfile, S_IWRITE | S_IREAD);
|
||||
#endif
|
||||
rv = g_unlink (be->lockfile);
|
||||
if (rv) {
|
||||
|
||||
@@ -26,8 +26,11 @@
|
||||
|
||||
#include <gnome.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <glib/gstdio.h>
|
||||
#ifndef HAVE_GLIB_2_8
|
||||
#include <gstdio-2.8.h>
|
||||
#endif
|
||||
#include <libguile.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -477,17 +480,7 @@ gnc_ui_qif_import_load_file_next_cb(GnomeDruidPage * page,
|
||||
gnc_error_dialog(wind->window, _("Please select a file to load."));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
{
|
||||
wchar_t *wpath = g_utf8_to_utf16(path_to_load, -1, NULL, NULL, NULL);
|
||||
rv = wpath ? _waccess(wpath, R_OK) : -1;
|
||||
g_free(wpath);
|
||||
}
|
||||
#else
|
||||
rv = access(path_to_load, R_OK);
|
||||
#endif
|
||||
if (rv < 0) {
|
||||
else if (g_access(path_to_load, R_OK) < 0) {
|
||||
/* stay here if bad file */
|
||||
gnc_error_dialog(wind->window,
|
||||
_("File not found or read permission denied. "
|
||||
|
||||
Reference in New Issue
Block a user