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.
CURL_CHECK_FUNC_MEMRCHR
CURL_CHECK_FUNC_POLL
CURL_CHECK_FUNC_SETSOCKOPT
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
CURL_CHECK_FUNC_SIGACTION
CURL_CHECK_FUNC_SIGINTERRUPT
CURL_CHECK_FUNC_SIGNAL
-dnl CURL_CHECK_FUNC_SETXATTR
+dnl CURL_CHECK_FUNC_FSETXATTR
dnl -------------------------------------------------
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 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
#
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_LANG_FUNC_LINK_TRY([setxattr])
+ AC_LANG_FUNC_LINK_TRY([fsetxattr])
- tst_links_setxattr="yes"
+ tst_links_fsetxattr="yes"
- 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])
$curl_includes_sys_xattr
],[
AC_MSG_RESULT([yes])
- tst_proto_setxattr="yes"
+ tst_proto_fsetxattr="yes"
- tst_proto_setxattr="no"
+ tst_proto_fsetxattr="no"
- 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
]],[[
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])
return 1;
]])
],[
AC_MSG_RESULT([yes])
- tst_compi_setxattr="yes"
+ tst_compi_fsetxattr="yes"
- tst_compi_setxattr="no"
+ tst_compi_fsetxattr="no"
- 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
- tst_allow_setxattr="yes"
+ tst_allow_fsetxattr="yes"
- tst_allow_setxattr="no"
+ tst_allow_fsetxattr="no"
- 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_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"
- ac_cv_func_setxattr="no"
+ ac_cv_func_fsetxattr="no"
if(outfile && !curlx_strequal(outfile, "-") && outs.stream) {
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;
if(!res && rc) {
/* something went wrong in the writing process */
res = CURLE_WRITE_ERROR;
- 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 */
#ifdef HAVE_UTIME
/* Important that we set the time _after_ the file has been
closed, as is done above here */
#include <curl/curl.h>
#include "xattr.h"
#include <curl/curl.h>
#include "xattr.h"
#include <sys/types.h>
#include <string.h>
#include <sys/xattr.h> /* include header from libc, not from libattr */
#include <sys/types.h>
#include <string.h>
#include <sys/xattr.h> /* include header from libc, not from libattr */
/* store metadata from the curl request alongside the downloaded
* file using extended attributes
*/
/* 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;
{
int i = 0;
int err = 0;
char *value = NULL;
CURLcode rc = curl_easy_getinfo(curl, mappings[i].info, &value);
if ( rc == CURLE_OK && value ) {
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
}
i++;
}
return err;
}
#else
-int write_xattr(CURL *curl, const char *filename)
+int fwrite_xattr(CURL *curl, int fd)
* KIND, either express or implied.
*
***************************************************************************/
* KIND, either express or implied.
*
***************************************************************************/
-int write_xattr( CURL *curl, const char *filename );
+int fwrite_xattr(CURL *curl, int fd);