aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Tomanek <stefan.tomanek@wertarbyte.de>2010-11-07 16:54:49 +0100
committerDaniel Stenberg <daniel@haxx.se>2010-11-10 10:43:05 +0100
commitf1db21218b35b618f622deb94b6e5ab2c62bbd17 (patch)
tree54673bd388300203faf724cf8034b2ce278014f0
parent892cacef43b4871d8ce50b2e61a143ede1b3083e (diff)
write extended attributes by using fsetxattr
Instead of reopening the downloaded file, fsetxattr uses the (already open) file descriptor to attach extended attributes. This makes the procedure more robust against errors caused by moved or deleted files.
-rw-r--r--configure.ac2
-rw-r--r--m4/curl-functions.m474
-rw-r--r--src/main.c19
-rw-r--r--src/xattr.c10
-rw-r--r--src/xattr.h2
5 files changed, 54 insertions, 53 deletions
diff --git a/configure.ac b/configure.ac
index 893e53c0c..cc2b6f4d2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2349,7 +2349,7 @@ CURL_CHECK_FUNC_LOCALTIME_R
CURL_CHECK_FUNC_MEMRCHR
CURL_CHECK_FUNC_POLL
CURL_CHECK_FUNC_SETSOCKOPT
-CURL_CHECK_FUNC_SETXATTR
+CURL_CHECK_FUNC_FSETXATTR
CURL_CHECK_FUNC_SIGACTION
CURL_CHECK_FUNC_SIGINTERRUPT
CURL_CHECK_FUNC_SIGNAL
diff --git a/m4/curl-functions.m4 b/m4/curl-functions.m4
index ca5b86fc3..7f7cb8610 100644
--- a/m4/curl-functions.m4
+++ b/m4/curl-functions.m4
@@ -5924,86 +5924,86 @@ AC_DEFUN([CURL_CHECK_FUNC_WRITEV], [
fi
])
-dnl CURL_CHECK_FUNC_SETXATTR
+dnl CURL_CHECK_FUNC_FSETXATTR
dnl -------------------------------------------------
-dnl Verify if setxattr is available, prototyped, and
+dnl Verify if fsetxattr is available, prototyped, and
dnl can be compiled. If all of these are true, and
dnl usage has not been previously disallowed with
-dnl shell variable curl_disallow_setxattr, then
-dnl HAVE_SETXATTR will be defined.
+dnl shell variable curl_disallow_fsetxattr, then
+dnl HAVE_FSETXATTR will be defined.
-AC_DEFUN([CURL_CHECK_FUNC_SETXATTR], [
+AC_DEFUN([CURL_CHECK_FUNC_FSETXATTR], [
AC_REQUIRE([CURL_INCLUDES_SYS_XATTR])dnl
#
- tst_links_setxattr="unknown"
- tst_proto_setxattr="unknown"
- tst_compi_setxattr="unknown"
- tst_allow_setxattr="unknown"
+ tst_links_fsetxattr="unknown"
+ tst_proto_fsetxattr="unknown"
+ tst_compi_fsetxattr="unknown"
+ tst_allow_fsetxattr="unknown"
#
- AC_MSG_CHECKING([if setxattr can be linked])
+ AC_MSG_CHECKING([if fsetxattr can be linked])
AC_LINK_IFELSE([
- AC_LANG_FUNC_LINK_TRY([setxattr])
+ AC_LANG_FUNC_LINK_TRY([fsetxattr])
],[
AC_MSG_RESULT([yes])
- tst_links_setxattr="yes"
+ tst_links_fsetxattr="yes"
],[
AC_MSG_RESULT([no])
- tst_links_setxattr="no"
+ tst_links_fsetxattr="no"
])
#
- if test "$tst_links_setxattr" = "yes"; then
- AC_MSG_CHECKING([if setxattr is prototyped])
- AC_EGREP_CPP([setxattr],[
+ if test "$tst_links_fsetxattr" = "yes"; then
+ AC_MSG_CHECKING([if fsetxattr is prototyped])
+ AC_EGREP_CPP([fsetxattr],[
$curl_includes_sys_xattr
],[
AC_MSG_RESULT([yes])
- tst_proto_setxattr="yes"
+ tst_proto_fsetxattr="yes"
],[
AC_MSG_RESULT([no])
- tst_proto_setxattr="no"
+ tst_proto_fsetxattr="no"
])
fi
#
- if test "$tst_proto_setxattr" = "yes"; then
- AC_MSG_CHECKING([if setxattr is compilable])
+ if test "$tst_proto_fsetxattr" = "yes"; then
+ AC_MSG_CHECKING([if fsetxattr is compilable])
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_sys_xattr
]],[[
- if(0 != setxattr(0, 0, 0, 0, 0))
+ if(0 != fsetxattr("", "", "", 0, 0))
return 1;
]])
],[
AC_MSG_RESULT([yes])
- tst_compi_setxattr="yes"
+ tst_compi_fsetxattr="yes"
],[
AC_MSG_RESULT([no])
- tst_compi_setxattr="no"
+ tst_compi_fsetxattr="no"
])
fi
#
- if test "$tst_compi_setxattr" = "yes"; then
- AC_MSG_CHECKING([if setxattr usage allowed])
- if test "x$curl_disallow_setxattr" != "xyes"; then
+ if test "$tst_compi_fsetxattr" = "yes"; then
+ AC_MSG_CHECKING([if fsetxattr usage allowed])
+ if test "x$curl_disallow_fsetxattr" != "xyes"; then
AC_MSG_RESULT([yes])
- tst_allow_setxattr="yes"
+ tst_allow_fsetxattr="yes"
else
AC_MSG_RESULT([no])
- tst_allow_setxattr="no"
+ tst_allow_fsetxattr="no"
fi
fi
#
- AC_MSG_CHECKING([if setxattr might be used])
- if test "$tst_links_setxattr" = "yes" &&
- test "$tst_proto_setxattr" = "yes" &&
- test "$tst_compi_setxattr" = "yes" &&
- test "$tst_allow_setxattr" = "yes"; then
+ AC_MSG_CHECKING([if fsetxattr might be used])
+ if test "$tst_links_fsetxattr" = "yes" &&
+ test "$tst_proto_fsetxattr" = "yes" &&
+ test "$tst_compi_fsetxattr" = "yes" &&
+ test "$tst_allow_fsetxattr" = "yes"; then
AC_MSG_RESULT([yes])
- AC_DEFINE_UNQUOTED(HAVE_SETXATTR, 1,
- [Define to 1 if you have the setxattr function.])
- ac_cv_func_setxattr="yes"
+ AC_DEFINE_UNQUOTED(HAVE_FSETXATTR, 1,
+ [Define to 1 if you have the fsetxattr function.])
+ ac_cv_func_fsetxattr="yes"
else
AC_MSG_RESULT([no])
- ac_cv_func_setxattr="no"
+ ac_cv_func_fsetxattr="no"
fi
])
diff --git a/src/main.c b/src/main.c
index deca6c979..2f81ef4e8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -5633,9 +5633,17 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
}
}
}
-
if(outfile && !curlx_strequal(outfile, "-") && outs.stream) {
- int rc = fclose(outs.stream);
+ int rc;
+
+ if(config->xattr) {
+ rc = fwrite_xattr(curl, fileno(outs.stream) );
+ if(rc)
+ warnf(config, "Error setting extended attributes: %s\n",
+ strerror(errno) );
+ }
+
+ rc = fclose(outs.stream);
if(!res && rc) {
/* something went wrong in the writing process */
res = CURLE_WRITE_ERROR;
@@ -5643,13 +5651,6 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
}
}
- if(config->xattr && outs.filename) {
- int err = write_xattr(curl, outs.filename );
- if(err)
- warnf( config, "Error setting extended attributes: %s\n",
- strerror(errno) );
- }
-
#ifdef HAVE_UTIME
/* Important that we set the time _after_ the file has been
closed, as is done above here */
diff --git a/src/xattr.c b/src/xattr.c
index e03509680..a770405c9 100644
--- a/src/xattr.c
+++ b/src/xattr.c
@@ -25,7 +25,7 @@
#include <curl/curl.h>
#include "xattr.h"
-#ifdef HAVE_SETXATTR
+#ifdef HAVE_FSETXATTR
#include <sys/types.h>
#include <string.h>
#include <sys/xattr.h> /* include header from libc, not from libattr */
@@ -46,7 +46,7 @@ static const struct xattr_mapping {
/* store metadata from the curl request alongside the downloaded
* file using extended attributes
*/
-int write_xattr(CURL *curl, const char *filename)
+int fwrite_xattr(CURL *curl, int fd)
{
int i = 0;
int err = 0;
@@ -55,17 +55,17 @@ int write_xattr(CURL *curl, const char *filename)
char *value = NULL;
CURLcode rc = curl_easy_getinfo(curl, mappings[i].info, &value);
if ( rc == CURLE_OK && value ) {
- err = setxattr( filename, mappings[i].attr, value, strlen(value), 0 );
+ err = fsetxattr( fd, mappings[i].attr, value, strlen(value), 0 );
}
i++;
}
return err;
}
#else
-int write_xattr(CURL *curl, const char *filename)
+int fwrite_xattr(CURL *curl, int fd)
{
(void)curl;
- (void)filename;
+ (void)fd;
return 0;
}
#endif
diff --git a/src/xattr.h b/src/xattr.h
index df62066c8..fea98f188 100644
--- a/src/xattr.h
+++ b/src/xattr.h
@@ -21,6 +21,6 @@
* KIND, either express or implied.
*
***************************************************************************/
-int write_xattr( CURL *curl, const char *filename );
+int fwrite_xattr(CURL *curl, int fd);
#endif