X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=glib%2Fgfileutils.c;h=0db07c541e973d470c9ef03f9c1771fe5b2e6aca;hb=35eaf037bdfca985abf5d349e7355f1d2ed9c77b;hp=0db964a4b5d98dead474c9df2cd6854887de03a5;hpb=33dd6d12d7478df22b7759f0ed26f81187ad2a54;p=platform%2Fupstream%2Fglib.git diff --git a/glib/gfileutils.c b/glib/gfileutils.c index 0db964a..0db07c5 100644 --- a/glib/gfileutils.c +++ b/glib/gfileutils.c @@ -14,8 +14,7 @@ * * 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. + * see . */ #include "config.h" @@ -73,8 +72,8 @@ * * 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 - * G_FILENAME_ENCODING environment variable), or not. + * to the locale settings of the process (or the `G_FILENAME_ENCODING` + * 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 @@ -271,11 +270,11 @@ g_mkdir_with_parents (const gchar *pathname, * @test: bitfield of #GFileTest flags * * Returns %TRUE if any of the tests in the bitfield @test are - * %TRUE. For example, (G_FILE_TEST_EXISTS | - * G_FILE_TEST_IS_DIR) will return %TRUE if the file exists; - * the check whether it's a directory doesn't matter since the existence - * test is %TRUE. With the current set of available tests, there's no point - * passing in more than one test at a time. + * %TRUE. For example, `(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)` + * will return %TRUE if the file exists; the check whether it's a + * directory doesn't matter since the existence test is %TRUE. With + * the current set of available tests, there's no point passing in + * more than one test at a time. * * Apart from %G_FILE_TEST_IS_SYMLINK all tests follow symbolic links, * so for a symbolic link to a regular file g_file_test() will return @@ -290,12 +289,12 @@ g_mkdir_with_parents (const gchar *pathname, * For example, you might think you could use %G_FILE_TEST_IS_SYMLINK * to know whether it is safe to write to a file without being * tricked into writing into a different location. It doesn't work! - * |[ - * /* DON'T DO THIS */ + * |[ + * // DON'T DO THIS * if (!g_file_test (filename, G_FILE_TEST_IS_SYMLINK)) * { * fd = g_open (filename, O_WRONLY); - * /* write to fd */ + * // write to fd * } * ]| * @@ -310,9 +309,9 @@ g_mkdir_with_parents (const gchar *pathname, * %G_FILE_TEST_IS_SYMLINK will always return %FALSE. Testing for * %G_FILE_TEST_IS_EXECUTABLE will just check that the file exists and * its name indicates that it is executable, checking for well-known - * extensions and those listed in the PATHEXT environment variable. + * extensions and those listed in the `PATHEXT` environment variable. * - * Return value: whether a test was %TRUE + * Returns: whether a test was %TRUE **/ gboolean g_file_test (const gchar *filename, @@ -466,15 +465,15 @@ G_DEFINE_QUARK (g-file-error-quark, g_file_error) * @err_no: an "errno" value * * Gets a #GFileError constant based on the passed-in @err_no. - * For example, if you pass in EEXIST this function returns - * #G_FILE_ERROR_EXIST. Unlike errno values, you can portably + * For example, if you pass in `EEXIST` this function returns + * #G_FILE_ERROR_EXIST. Unlike `errno` values, you can portably * assume that all #GFileError values will exist. * * Normally a #GFileError value goes into a #GError returned * from a function that manipulates files. So you would use * g_file_error_from_errno() when constructing a #GError. * - * Return value: #GFileError corresponding to the given @errno + * Returns: #GFileError corresponding to the given @errno **/ GFileError g_file_error_from_errno (gint err_no) @@ -606,8 +605,51 @@ g_file_error_from_errno (gint err_no) } } +static char * +format_error_message (const gchar *filename, + const gchar *format_string, + int saved_errno) G_GNUC_FORMAT(2); + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" + +static char * +format_error_message (const gchar *filename, + const gchar *format_string, + int saved_errno) +{ + gchar *display_name; + gchar *msg; + + display_name = g_filename_display_name (filename); + msg = g_strdup_printf (format_string, display_name, g_strerror (saved_errno)); + g_free (display_name); + + return msg; +} + +#pragma GCC diagnostic pop + +/* format string must have two '%s': + * + * - the place for the filename + * - the place for the strerror + */ +static void +set_file_error (GError **error, + const gchar *filename, + const gchar *format_string, + int saved_errno) +{ + char *msg = format_error_message (filename, format_string, saved_errno); + + g_set_error_literal (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno), + msg); + g_free (msg); +} + static gboolean -get_contents_stdio (const gchar *display_filename, +get_contents_stdio (const gchar *filename, FILE *f, gchar **contents, gsize *length, @@ -619,6 +661,7 @@ get_contents_stdio (const gchar *display_filename, gsize total_bytes = 0; gsize total_allocated = 0; gchar *tmp; + gchar *display_filename; g_assert (f != NULL); @@ -650,12 +693,14 @@ get_contents_stdio (const gchar *display_filename, if (tmp == NULL) { + display_filename = g_filename_display_name (filename); g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOMEM, g_dngettext (GETTEXT_PACKAGE, "Could not allocate %lu byte to read file \"%s\"", "Could not allocate %lu bytes to read file \"%s\"", (gulong)total_allocated), (gulong) total_allocated, display_filename); + g_free (display_filename); goto error; } @@ -665,12 +710,14 @@ get_contents_stdio (const gchar *display_filename, if (ferror (f)) { + display_filename = g_filename_display_name (filename); g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (save_errno), _("Error reading file '%s': %s"), display_filename, g_strerror (save_errno)); + g_free (display_filename); goto error; } @@ -699,11 +746,13 @@ get_contents_stdio (const gchar *display_filename, return TRUE; file_too_large: + display_filename = g_filename_display_name (filename); g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("File \"%s\" is too large"), display_filename); + g_free (display_filename); error: @@ -716,7 +765,7 @@ get_contents_stdio (const gchar *display_filename, #ifndef G_OS_WIN32 static gboolean -get_contents_regfile (const gchar *display_filename, +get_contents_regfile (const gchar *filename, struct stat *stat_buf, gint fd, gchar **contents, @@ -727,6 +776,7 @@ get_contents_regfile (const gchar *display_filename, gsize bytes_read; gsize size; gsize alloc_size; + gchar *display_filename; size = stat_buf->st_size; @@ -735,13 +785,14 @@ get_contents_regfile (const gchar *display_filename, if (buf == NULL) { + display_filename = g_filename_display_name (filename); g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOMEM, g_dngettext (GETTEXT_PACKAGE, "Could not allocate %lu byte to read file \"%s\"", "Could not allocate %lu bytes to read file \"%s\"", (gulong)alloc_size), (gulong) alloc_size, display_filename); - + g_free (display_filename); goto error; } @@ -759,13 +810,14 @@ get_contents_regfile (const gchar *display_filename, int save_errno = errno; g_free (buf); + display_filename = g_filename_display_name (filename); g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (save_errno), _("Failed to read from file '%s': %s"), display_filename, g_strerror (save_errno)); - + g_free (display_filename); goto error; } } @@ -801,22 +853,17 @@ get_contents_posix (const gchar *filename, { struct stat stat_buf; gint fd; - gchar *display_filename = g_filename_display_name (filename); /* O_BINARY useful on Cygwin */ fd = open (filename, O_RDONLY|O_BINARY); if (fd < 0) { - int save_errno = errno; - - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to open file '%s': %s"), - display_filename, - g_strerror (save_errno)); - g_free (display_filename); + int saved_errno = errno; + set_file_error (error, + filename, + _("Failed to open file '%s': %s"), + saved_errno); return FALSE; } @@ -824,29 +871,24 @@ get_contents_posix (const gchar *filename, /* I don't think this will ever fail, aside from ENOMEM, but. */ if (fstat (fd, &stat_buf) < 0) { - int save_errno = errno; - + int saved_errno = errno; + set_file_error (error, + filename, + _("Failed to get attributes of file '%s': fstat() failed: %s"), + saved_errno); close (fd); - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to get attributes of file '%s': fstat() failed: %s"), - display_filename, - g_strerror (save_errno)); - g_free (display_filename); return FALSE; } if (stat_buf.st_size > 0 && S_ISREG (stat_buf.st_mode)) { - gboolean retval = get_contents_regfile (display_filename, + gboolean retval = get_contents_regfile (filename, &stat_buf, fd, contents, length, error); - g_free (display_filename); return retval; } @@ -859,21 +901,16 @@ get_contents_posix (const gchar *filename, if (f == NULL) { - int save_errno = errno; - - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to open file '%s': fdopen() failed: %s"), - display_filename, - g_strerror (save_errno)); - g_free (display_filename); + int saved_errno = errno; + set_file_error (error, + filename, + _("Failed to open file '%s': fdopen() failed: %s"), + saved_errno); return FALSE; } - retval = get_contents_stdio (display_filename, f, contents, length, error); - g_free (display_filename); + retval = get_contents_stdio (filename, f, contents, length, error); return retval; } @@ -889,27 +926,21 @@ get_contents_win32 (const gchar *filename, { FILE *f; gboolean retval; - gchar *display_filename = g_filename_display_name (filename); - int save_errno; f = g_fopen (filename, "rb"); - save_errno = errno; if (f == NULL) { - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to open file '%s': %s"), - display_filename, - g_strerror (save_errno)); - g_free (display_filename); + int saved_errno = errno; + set_file_error (error, + filename, + _("Failed to open file '%s': %s"), + saved_errno); return FALSE; } - retval = get_contents_stdio (display_filename, f, contents, length, error); - g_free (display_filename); + retval = get_contents_stdio (filename, f, contents, length, error); return retval; } @@ -935,7 +966,7 @@ get_contents_win32 (const gchar *filename, * codes are those in the #GFileError enumeration. In the error case, * @contents is set to %NULL and @length is set to zero. * - * Return value: %TRUE on success, %FALSE if an error occurred + * Returns: %TRUE on success, %FALSE if an error occurred **/ gboolean g_file_get_contents (const gchar *filename, @@ -986,49 +1017,6 @@ rename_file (const char *old_name, return TRUE; } -static char * -format_error_message (const gchar *filename, - const gchar *format_string) G_GNUC_FORMAT(2); - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat-nonliteral" - -static char * -format_error_message (const gchar *filename, - const gchar *format_string) -{ - gint saved_errno = errno; - gchar *display_name; - gchar *msg; - - display_name = g_filename_display_name (filename); - msg = g_strdup_printf (format_string, display_name, g_strerror (saved_errno)); - g_free (display_name); - - return msg; -} - -#pragma GCC diagnostic pop - -/* format string must have two '%s': - * - * - the place for the filename - * - the place for the strerror - */ -static void -set_file_error (GError **error, - const gchar *filename, - const gchar *format_string) - -{ - int saved_errno = errno; - char *msg = format_error_message (filename, format_string); - - g_set_error_literal (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno), - msg); - g_free (msg); -} - static gchar * write_to_temp_file (const gchar *contents, gssize length, @@ -1048,7 +1036,10 @@ write_to_temp_file (const gchar *contents, if (fd == -1) { - set_file_error (err, tmp_name, _("Failed to create file '%s': %s")); + int saved_errno = errno; + set_file_error (err, + tmp_name, _("Failed to create file '%s': %s"), + saved_errno); goto out; } @@ -1069,10 +1060,13 @@ write_to_temp_file (const gchar *contents, if (s < 0) { - if (errno == EINTR) + int saved_errno = errno; + if (saved_errno == EINTR) continue; - set_file_error (err, tmp_name, _("Failed to write file '%s': write() failed: %s")); + set_file_error (err, + tmp_name, _("Failed to write file '%s': write() failed: %s"), + saved_errno); close (fd); g_unlink (tmp_name); @@ -1112,7 +1106,10 @@ write_to_temp_file (const gchar *contents, */ if (g_lstat (dest_file, &statbuf) == 0 && statbuf.st_size > 0 && fsync (fd) != 0) { - set_file_error (err, tmp_name, _("Failed to write file '%s': fsync() failed: %s")); + int saved_errno = errno; + set_file_error (err, + tmp_name, _("Failed to write file '%s': fsync() failed: %s"), + saved_errno); close (fd); g_unlink (tmp_name); @@ -1154,24 +1151,19 @@ write_to_temp_file (const gchar *contents, * * 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: - * - * - * 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. - * - * - * On Windows renaming a file will not remove an existing file with the + * + * - 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. + * + * - 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. - * - * - * On Windows there is no way to remove a file that is open to some + * + * - 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. - * - * * * If the call was successful, it returns %TRUE. If the call was not successful, * it returns %FALSE and sets @error. The error domain is #G_FILE_ERROR. @@ -1180,10 +1172,10 @@ write_to_temp_file (const gchar *contents, * Note that the name for the temporary file is constructed by appending up * to 7 characters to @filename. * - * Return value: %TRUE on success, %FALSE if an error occurred + * Returns: %TRUE on success, %FALSE if an error occurred * * Since: 2.8 - **/ + */ gboolean g_file_set_contents (const gchar *filename, const gchar *contents, @@ -1237,18 +1229,11 @@ g_file_set_contents (const gchar *filename, 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); + int saved_errno = errno; + set_file_error (error, + filename, + _("Existing file '%s' could not be removed: g_unlink() failed: %s"), + saved_errno); g_unlink (tmp_filename); retval = FALSE; goto out; @@ -1380,7 +1365,7 @@ wrap_g_open (const gchar *filename, * in the GLib file name encoding. Most importantly, on Windows it * should be in UTF-8. * - * Return value: A pointer to @tmpl, which has been modified + * Returns: A pointer to @tmpl, which has been modified * to hold the directory name. In case of errors, %NULL is * returned, and %errno will be set. * @@ -1412,7 +1397,7 @@ g_mkdtemp_full (gchar *tmpl, * The string should be in the GLib file name encoding. Most importantly, * on Windows it should be in UTF-8. * - * Return value: A pointer to @tmpl, which has been modified + * Returns: A pointer to @tmpl, which has been modified * to hold the directory name. In case of errors, %NULL is * returned and %errno will be set. * @@ -1443,7 +1428,7 @@ g_mkdtemp (gchar *tmpl) * The string should be in the GLib file name encoding. Most importantly, * on Windows it should be in UTF-8. * - * Return value: A file handle (as from open()) to the file + * Returns: A file handle (as from open()) to the file * opened for reading and writing. The file handle should be * closed with close(). In case of errors, -1 is returned * and %errno will be set. @@ -1475,7 +1460,7 @@ g_mkstemp_full (gchar *tmpl, * didn't exist. The string should be in the GLib file name encoding. * Most importantly, on Windows it should be in UTF-8. * - * Return value: A file handle (as from open()) to the file + * Returns: A file handle (as from open()) to the file * opened for reading and writing. The file is opened in binary * mode on platforms where there is a difference. The file handle * should be closed with close(). In case of errors, -1 is @@ -1549,15 +1534,11 @@ g_get_tmp_name (const gchar *tmpl, retval = get_tmp_file (fulltemplate, f, flags, mode); if (retval == -1) { - int save_errno = errno; - gchar *display_fulltemplate = g_filename_display_name (fulltemplate); - - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to create file '%s': %s"), - display_fulltemplate, g_strerror (save_errno)); - g_free (display_fulltemplate); + int saved_errno = errno; + set_file_error (error, + fulltemplate, + _("Failed to create file '%s': %s"), + saved_errno); g_free (fulltemplate); return -1; } @@ -1592,7 +1573,7 @@ g_get_tmp_name (const gchar *tmpl, * when not needed any longer. The returned name is in the GLib file * name encoding. * - * Return value: A file handle (as from open()) to the file opened for + * Returns: A file handle (as from open()) to the file opened for * reading and writing. The file is opened in binary mode on platforms * where there is a difference. The file handle should be closed with * close(). In case of errors, -1 is returned and @error will be set. @@ -1639,7 +1620,7 @@ g_file_open_tmp (const gchar *tmpl, * Note that in contrast to g_mkdtemp() (and mkdtemp()) @tmpl is not * modified, and might thus be a read-only literal string. * - * Return value: (type filename): The actual name used. This string + * Returns: (type filename): The actual name used. This string * should be freed with g_free() when not needed any longer and is * is in the GLib file name encoding. In case of errors, %NULL is * returned and @error will be set. @@ -1770,7 +1751,7 @@ g_build_path_va (const gchar *separator, * as a string array, instead of varargs. This function is mainly * meant for language bindings. * - * Return value: a newly-allocated string that must be freed with g_free(). + * Returns: a newly-allocated string that must be freed with g_free(). * * Since: 2.8 */ @@ -1807,8 +1788,7 @@ g_build_pathv (const gchar *separator, * the same as the number of trailing copies of the separator on * the last non-empty element. (Determination of the number of * trailing copies is done without stripping leading copies, so - * if the separator is ABA, ABABA - * has 1 trailing copy.) + * if the separator is `ABA`, then `ABABA` has 1 trailing copy.) * * However, if there is only a single non-empty element, and there * are no characters in that element not part of the leading or @@ -1819,7 +1799,7 @@ g_build_pathv (const gchar *separator, * copies of the separator, elements consisting only of copies * of the separator are ignored. * - * Return value: a newly-allocated string that must be freed with g_free(). + * Returns: a newly-allocated string that must be freed with g_free(). **/ gchar * g_build_path (const gchar *separator, @@ -1962,7 +1942,7 @@ g_build_pathname_va (const gchar *first_element, * as a string array, instead of varargs. This function is mainly * meant for language bindings. * - * Return value: a newly-allocated string that must be freed with g_free(). + * Returns: a newly-allocated string that must be freed with g_free(). * * Since: 2.8 */ @@ -1988,21 +1968,20 @@ g_build_filenamev (gchar **args) * Creates a filename from a series of elements using the correct * separator for filenames. * - * On Unix, this function behaves identically to g_build_path - * (G_DIR_SEPARATOR_S, first_element, ....). + * On Unix, this function behaves identically to `g_build_path + * (G_DIR_SEPARATOR_S, first_element, ....)`. * * On Windows, it takes into account that either the backslash - * (\ or slash (/) can be used - * as separator in filenames, but otherwise behaves as on Unix. When - * file pathname separators need to be inserted, the one that last - * previously occurred in the parameters (reading from left to right) - * is used. + * (`\` or slash (`/`) can be used as separator in filenames, but + * otherwise behaves as on UNIX. When file pathname separators need + * to be inserted, the one that last previously occurred in the + * parameters (reading from left to right) is used. * * No attempt is made to force the resulting filename to be an absolute * path. If the first element is a relative path, the result will * be a relative path. * - * Return value: a newly-allocated string that must be freed with g_free(). + * Returns: a newly-allocated string that must be freed with g_free(). **/ gchar * g_build_filename (const gchar *first_element, @@ -2051,27 +2030,22 @@ g_file_read_link (const gchar *filename, while (TRUE) { read_size = readlink (filename, buffer, size); - if (read_size < 0) { - int save_errno = errno; - gchar *display_filename = g_filename_display_name (filename); - - g_free (buffer); - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to read the symbolic link '%s': %s"), - display_filename, - g_strerror (save_errno)); - g_free (display_filename); - - return NULL; - } + if (read_size < 0) + { + int saved_errno = errno; + set_file_error (error, + filename, + _("Failed to read the symbolic link '%s': %s"), + saved_errno); + g_free (buffer); + return NULL; + } if (read_size < size) - { - buffer[read_size] = 0; - return buffer; - } + { + buffer[read_size] = 0; + return buffer; + } size *= 2; buffer = g_realloc (buffer, size); @@ -2213,7 +2187,7 @@ g_path_skip_root (const gchar *file_name) * components. It returns a pointer into the given file name * string. * - * Return value: the name of the file without any leading + * Returns: the name of the file without any leading * directory components * * Deprecated:2.2: Use g_path_get_basename() instead, but notice @@ -2261,7 +2235,7 @@ g_basename (const gchar *file_name) * separators (and on Windows, possibly a drive letter), a single * separator is returned. If @file_name is empty, it gets ".". * - * Return value: a newly allocated string containing the last + * Returns: a newly allocated string containing the last * component of the filename */ gchar * @@ -2451,6 +2425,11 @@ g_path_get_dirname (const gchar *file_name) * The encoding of the returned string is system defined. * On Windows, it is always UTF-8. * + * Since GLib 2.40, this function will return the value of the "PWD" + * environment variable if it is set and it happens to be the same as + * the current directory. This can make a difference in the case that + * the current directory is the target of a symbolic link. + * * Returns: the current directory */ gchar * @@ -2476,10 +2455,17 @@ g_get_current_dir (void) return dir; #else - + const gchar *pwd; gchar *buffer = NULL; gchar *dir = NULL; static gulong max_len = 0; + struct stat pwdbuf, dotbuf; + + pwd = g_getenv ("PWD"); + if (pwd != NULL && + g_stat (".", &dotbuf) == 0 && g_stat (pwd, &pwdbuf) == 0 && + dotbuf.st_dev == pwdbuf.st_dev && dotbuf.st_ino == pwdbuf.st_ino) + return g_strdup (pwd); if (max_len == 0) max_len = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH;