Patch for bug 286102 from upstream git. It includes the following 5 commits: commit 3826963e65d8c4c68bcd3e4066505f63ef734b95 Author: Benjamin Otte Date: Tue Sep 1 21:53:35 2009 +0200 commit 48e0af0157f52ac12b904bd92540432a18b139c7 Author: Benjamin Otte Date: Tue Sep 1 21:26:08 2009 +0200 commit bb7852e34b1845e516290e1b45a960a345ee8a43 Author: Benjamin Otte Date: Tue Sep 1 20:36:31 2009 +0200 commit fc44bf40a4eff8e122b223e97ee5efcbc548be03 Author: Benjamin Otte Date: Tue Sep 1 12:48:55 2009 +0200 commit e695c0932f5d02f3b222f0b7a3de1f8c00ba7b81 Author: Benjamin Otte Date: Tue Sep 1 11:54:48 2009 +0200 Patch generated by a3li@gentoo.org diff --git a/configure.in b/configure.in index 7bda924..e2a33b5 100644 --- a/configure.in +++ b/configure.in @@ -952,7 +952,7 @@ AC_MSG_RESULT(unsigned $glib_size_type) # Check for some functions AC_CHECK_FUNCS(lstat strerror strsignal memmove vsnprintf stpcpy strcasecmp strncasecmp poll getcwd vasprintf setenv unsetenv getc_unlocked readlink symlink fdwalk) -AC_CHECK_FUNCS(chown lchown fchmod fchown link statvfs statfs utimes getgrgid getpwuid) +AC_CHECK_FUNCS(chown lchmod lchown fchmod fchown link statvfs statfs utimes getgrgid getpwuid) AC_CHECK_FUNCS(getmntent_r setmntent endmntent hasmntopt getmntinfo) # Check for high-resolution sleep functions AC_CHECK_FUNCS(nanosleep nsleep) diff --git a/gio/gcancellable.c b/gio/gcancellable.c index 209f5f1..e73d384 100644 --- a/gio/gcancellable.c +++ b/gio/gcancellable.c @@ -495,10 +495,10 @@ g_cancellable_get_fd (GCancellable *cancellable) * readable status. Reading to unset the readable status is done * with g_cancellable_reset(). * - * @Returns: %TRUE if @pollfd was successfully initialized, %FALSE on - * failure to prepare the cancellable. + * Returns: %TRUE if @pollfd was successfully initialized, %FALSE on + * failure to prepare the cancellable. * - * @Since: 2.22 + * Since: 2.22 **/ gboolean g_cancellable_make_pollfd (GCancellable *cancellable, GPollFD *pollfd) @@ -558,7 +558,7 @@ g_cancellable_make_pollfd (GCancellable *cancellable, GPollFD *pollfd) * is not called. This can cause the application to run out of file * descriptors when many #GCancellables are used at the same time. * - * @Since: 2.22 + * Since: 2.22 **/ void g_cancellable_release_fd (GCancellable *cancellable) diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c index 72a59b5..a61cc55 100644 --- a/gio/glocalfileinfo.c +++ b/gio/glocalfileinfo.c @@ -1869,15 +1869,40 @@ get_string (const GFileAttributeValue *value, static gboolean set_unix_mode (char *filename, + GFileQueryInfoFlags flags, const GFileAttributeValue *value, GError **error) { guint32 val; + int res = 0; if (!get_uint32 (value, &val, error)) return FALSE; - - if (g_chmod (filename, val) == -1) + +#ifdef HAVE_SYMLINK + if (flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) { +#ifdef HAVE_LCHMOD + res = lchmod (filename, val); +#else + struct stat statbuf; + /* Calling chmod on a symlink changes permissions on the symlink. + * We don't want to do this, so we need to check for a symlink */ + res = g_lstat (filename, &statbuf); + if (res == 0 && S_ISLNK (statbuf.st_mode)) + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Cannot set permissions on symlinks")); + return FALSE; + } + else if (res == 0) + res = g_chmod (filename, val); +#endif + } else +#endif + res = g_chmod (filename, val); + + if (res == -1) { int errsv = errno; @@ -2172,7 +2197,7 @@ _g_local_file_info_set_attribute (char *filename, _g_file_attribute_value_set_from_pointer (&value, type, value_p, FALSE); if (strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_MODE) == 0) - return set_unix_mode (filename, &value, error); + return set_unix_mode (filename, flags, &value, error); #ifdef HAVE_CHOWN else if (strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_UID) == 0) @@ -2316,7 +2341,7 @@ _g_local_file_info_set_attributes (char *filename, value = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_UNIX_MODE); if (value) { - if (!set_unix_mode (filename, value, error)) + if (!set_unix_mode (filename, flags, value, error)) { value->status = G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING; res = FALSE;