-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
What are your thoughts on using Extended Attributes for items such as: * Dos Attributes (like samba's "store dos attributes = yes") * File Creation Times (like samba's proposed user.crtime) * An option for alternate storage of NT ACLs (like samba's "vfs object = acl-xattr")
Are Extended Attributes acceptable? Or should they never touch the wine source?
Where would the portability functions for Extended Attributes on Linux, Mac OS X, FreeBSD and Solaris belong? I would think in libport.
Attached is a patch to add extended attribute portability functions for fgetxattr, fsetxattr and fremovexattr to libport.
Please give me any comments on this patch, and the idea of using extended attributes.
From 2ef84c7f8c849db18ce15366e72c6787fa83597d Mon Sep 17 00:00:00 2001
From: Benjamin Peddell klightspeed@netspace.net.au Date: Mon, 16 Nov 2009 01:23:28 +1000 Subject: [PATCH] Add Extended Attribute support to libport
--- configure | 178 ++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 45 ++++++++++++ include/config.h.in | 39 ++++++++++ include/wine/port.h | 36 +++++++++ libs/port/Makefile.in | 3 + libs/port/fgetxattr.c | 96 +++++++++++++++++++++++++ libs/port/fremovexattr.c | 75 +++++++++++++++++++ libs/port/fsetxattr.c | 102 ++++++++++++++++++++++++++ 8 files changed, 574 insertions(+), 0 deletions(-) create mode 100644 libs/port/fgetxattr.c create mode 100644 libs/port/fremovexattr.c create mode 100644 libs/port/fsetxattr.c
diff --git a/configure b/configure index 15652b4..c9322b3 100755 --- a/configure +++ b/configure @@ -5747,6 +5747,7 @@ for ac_header in \ sys/errno.h \ sys/event.h \ sys/exec_elf.h \ + sys/extattr.h \ sys/filio.h \ sys/inotify.h \ sys/ioctl.h \ @@ -5782,6 +5783,7 @@ for ac_header in \ sys/utsname.h \ sys/vm86.h \ sys/wait.h \ + sys/xattr.h \ syscall.h \ termios.h \ unistd.h \ @@ -12084,6 +12086,9 @@ for ac_func in \ chsize \ dlopen \ epoll_create \ + extattr_delete_fd \ + extattr_get_fd \ + extattr_set_fd \ ffs \ finite \ fnmatch \ @@ -12105,6 +12110,7 @@ for ac_func in \ lstat \ memmove \ mmap \ + openat \ pclose \ pipe2 \ poll \ @@ -12137,6 +12143,7 @@ for ac_func in \ tcgetattr \ thr_kill2 \ timegm \ + unlinkat \ usleep \ vsnprintf \ wait4 \ @@ -12262,6 +12269,81 @@ fi
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing fgetxattr" >&5 +$as_echo_n "checking for library containing fgetxattr... " >&6; } +if test "${ac_cv_search_fgetxattr+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char fgetxattr (); +int +main () +{ +return fgetxattr (); + ; + return 0; +} +_ACEOF +for ac_lib in '' attr; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_fgetxattr=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_fgetxattr+set}" = set; then : + break +fi +done +if test "${ac_cv_search_fgetxattr+set}" = set; then : + +else + ac_cv_search_fgetxattr=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_fgetxattr" >&5 +$as_echo "$ac_cv_search_fgetxattr" >&6; } +ac_res=$ac_cv_search_fgetxattr +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + +for ac_func in \ + fgetxattr \ + fremovexattr \ + fsetxattr \ + +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +eval as_val=$$as_ac_var + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname" >&5 $as_echo_n "checking for library containing gethostbyname... " >&6; } if test "${ac_cv_search_gethostbyname+set}" = set; then : @@ -12616,6 +12698,102 @@ $as_echo "#define HAVE_ONE_ARG_MKDIR 1" >>confdefs.h
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fgetxattr takes six arguments" >&5 +$as_echo_n "checking whether fgetxattr takes six arguments... " >&6; } +if test "${wine_cv_six_arg_fgetxattr+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/xattr.h> +int +main () +{ +fgetxattr(0, "foo", "foo", 3, 0, 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + wine_cv_six_arg_fgetxattr=yes +else + wine_cv_six_arg_fgetxattr=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $wine_cv_six_arg_fgetxattr" >&5 +$as_echo "$wine_cv_six_arg_fgetxattr" >&6; } +if test "$wine_cv_six_arg_fgetxattr" = "yes" +then + +$as_echo "#define HAVE_SIX_ARG_FGETXATTR 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fsetxattr takes six arguments" >&5 +$as_echo_n "checking whether fsetxattr takes six arguments... " >&6; } +if test "${wine_cv_six_arg_fsetxattr+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/xattr.h> +int +main () +{ +fsetxattr(0, "foo", "foo", 3, 0, 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + wine_cv_six_arg_fsetxattr=yes +else + wine_cv_six_arg_fsetxattr=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $wine_cv_six_arg_fsetxattr" >&5 +$as_echo "$wine_cv_six_arg_fsetxattr" >&6; } +if test "$wine_cv_six_arg_fsetxattr" = "yes" +then + +$as_echo "#define HAVE_SIX_ARG_FSETXATTR 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fremovexattr takes three arguments" >&5 +$as_echo_n "checking whether fremovexattr takes three arguments... " >&6; } +if test "${wine_cv_three_arg_fremovexattr+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/xattr.h> +int +main () +{ +fremovexattr("foo", "foo", 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + wine_cv_three_arg_fremovexattr=yes +else + wine_cv_three_arg_fremovexattr=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $wine_cv_three_arg_fremovexattr" >&5 +$as_echo "$wine_cv_three_arg_fremovexattr" >&6; } +if test "$wine_cv_three_arg_fremovexattr" = "yes" +then + +$as_echo "#define HAVE_THREE_ARG_FREMOVEXATTR 1" >>confdefs.h + +fi +
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } diff --git a/configure.ac b/configure.ac index a5f1b8a..c0f5380 100644 --- a/configure.ac +++ b/configure.ac @@ -384,6 +384,7 @@ AC_CHECK_HEADERS(\ sys/errno.h \ sys/event.h \ sys/exec_elf.h \ + sys/extattr.h \ sys/filio.h \ sys/inotify.h \ sys/ioctl.h \ @@ -419,6 +420,7 @@ AC_CHECK_HEADERS(\ sys/utsname.h \ sys/vm86.h \ sys/wait.h \ + sys/xattr.h \ syscall.h \ termios.h \ unistd.h \ @@ -1684,6 +1686,9 @@ AC_CHECK_FUNCS(\ chsize \ dlopen \ epoll_create \ + extattr_delete_fd \ + extattr_get_fd \ + extattr_set_fd \ ffs \ finite \ fnmatch \ @@ -1705,6 +1710,7 @@ AC_CHECK_FUNCS(\ lstat \ memmove \ mmap \ + openat \ pclose \ pipe2 \ poll \ @@ -1737,6 +1743,7 @@ AC_CHECK_FUNCS(\ tcgetattr \ thr_kill2 \ timegm \ + unlinkat \ usleep \ vsnprintf \ wait4 \ @@ -1757,6 +1764,16 @@ then AC_CHECK_LIB(poll,poll,[AC_DEFINE(HAVE_POLL,1) AC_SUBST(LIBPOLL,"-lpoll")]) fi
+dnl Check for -lattr for the old attr package +AC_SEARCH_LIBS(fgetxattr,attr) + +dnl Check for xattr functions which may rely on -lattr on Linux +AC_CHECK_FUNCS(\ + fgetxattr \ + fremovexattr \ + fsetxattr \ +) + dnl Check for -lnsl for Solaris AC_SEARCH_LIBS(gethostbyname, nsl)
@@ -1816,6 +1833,34 @@ then AC_DEFINE(HAVE_ONE_ARG_MKDIR, 1, [Define if mkdir takes only one argument]) fi
+dnl Check xattr functions +AC_CACHE_CHECK([whether fgetxattr takes six arguments], + wine_cv_six_arg_fgetxattr, + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/xattr.h>]],[[fgetxattr(0, "foo", "foo", 3, 0, 0);]])], + [wine_cv_six_arg_fgetxattr=yes],[wine_cv_six_arg_fgetxattr=no])) +if test "$wine_cv_six_arg_fgetxattr" = "yes" +then + AC_DEFINE(HAVE_SIX_ARG_FGETXATTR, 1, [Define if fgetxattr takes six arguments, as in Mac OS X]) +fi + +AC_CACHE_CHECK([whether fsetxattr takes six arguments], + wine_cv_six_arg_fsetxattr, + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/xattr.h>]],[[fsetxattr(0, "foo", "foo", 3, 0, 0);]])], + [wine_cv_six_arg_fsetxattr=yes],[wine_cv_six_arg_fsetxattr=no])) +if test "$wine_cv_six_arg_fsetxattr" = "yes" +then + AC_DEFINE(HAVE_SIX_ARG_FSETXATTR, 1, [Define if fsetxattr takes six arguments, as in Mac OS X]) +fi + +AC_CACHE_CHECK([whether fremovexattr takes three arguments], + wine_cv_three_arg_fremovexattr, + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/xattr.h>]],[[fremovexattr("foo", "foo", 0);]])], + [wine_cv_three_arg_fremovexattr=yes],[wine_cv_three_arg_fremovexattr=no])) +if test "$wine_cv_three_arg_fremovexattr" = "yes" +then + AC_DEFINE(HAVE_THREE_ARG_FREMOVEXATTR, 1, [Define if fremovexattr takes three arguments, as in Mac OS X]) +fi + dnl **** Check for types ****
AC_C_CONST diff --git a/include/config.h.in b/include/config.h.in index 16b2e90..1c6ec57 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -93,9 +93,21 @@ /* Define if you have EsounD sound server */ #undef HAVE_ESD
+/* Define to 1 if you have the `extattr_delete_fd' function. */ +#undef HAVE_EXTATTR_DELETE_FD + +/* Define to 1 if you have the `extattr_get_fd' function. */ +#undef HAVE_EXTATTR_GET_FD + +/* Define to 1 if you have the `extattr_set_fd' function. */ +#undef HAVE_EXTATTR_SET_FD + /* Define to 1 if you have the `ffs' function. */ #undef HAVE_FFS
+/* Define to 1 if you have the `fgetxattr' function. */ +#undef HAVE_FGETXATTR + /* Define to 1 if you have the `finite' function. */ #undef HAVE_FINITE
@@ -156,9 +168,15 @@ /* Define to 1 if you have the <freetype/tttables.h> header file. */ #undef HAVE_FREETYPE_TTTABLES_H
+/* Define to 1 if you have the `fremovexattr' function. */ +#undef HAVE_FREMOVEXATTR + /* Define to 1 if the system has the type `fsblkcnt_t'. */ #undef HAVE_FSBLKCNT_T
+/* Define to 1 if you have the `fsetxattr' function. */ +#undef HAVE_FSETXATTR + /* Define to 1 if the system has the type `fsfilcnt_t'. */ #undef HAVE_FSFILCNT_T
@@ -561,6 +579,9 @@ /* Define to 1 if you have the <OpenAL/al.h> header file. */ #undef HAVE_OPENAL_AL_H
+/* Define to 1 if you have the `openat' function. */ +#undef HAVE_OPENAT + /* Define if OpenGL is present on the system */ #undef HAVE_OPENGL
@@ -699,6 +720,12 @@ /* Define to 1 if the system has the type `sigset_t'. */ #undef HAVE_SIGSET_T
+/* Define if fgetxattr takes six arguments, as in Mac OS X */ +#undef HAVE_SIX_ARG_FGETXATTR + +/* Define if fsetxattr takes six arguments, as in Mac OS X */ +#undef HAVE_SIX_ARG_FSETXATTR + /* Define to 1 if the system has the type `size_t'. */ #undef HAVE_SIZE_T
@@ -855,6 +882,9 @@ /* Define to 1 if you have the <sys/exec_elf.h> header file. */ #undef HAVE_SYS_EXEC_ELF_H
+/* Define to 1 if you have the <sys/extattr.h> header file. */ +#undef HAVE_SYS_EXTATTR_H + /* Define to 1 if you have the <sys/filio.h> header file. */ #undef HAVE_SYS_FILIO_H
@@ -984,12 +1014,18 @@ /* Define to 1 if you have the <sys/wait.h> header file. */ #undef HAVE_SYS_WAIT_H
+/* Define to 1 if you have the <sys/xattr.h> header file. */ +#undef HAVE_SYS_XATTR_H + /* Define to 1 if you have the `tcgetattr' function. */ #undef HAVE_TCGETATTR
/* Define to 1 if you have the <termios.h> header file. */ #undef HAVE_TERMIOS_H
+/* Define if fremovexattr takes three arguments, as in Mac OS X */ +#undef HAVE_THREE_ARG_FREMOVEXATTR + /* Define to 1 if you have the `thr_kill2' function. */ #undef HAVE_THR_KILL2
@@ -1005,6 +1041,9 @@ /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H
+/* Define to 1 if you have the `unlinkat' function. */ +#undef HAVE_UNLINKAT + /* Define to 1 if you have the `usleep' function. */ #undef HAVE_USLEEP
diff --git a/include/wine/port.h b/include/wine/port.h index 61c8399..6568dae 100644 --- a/include/wine/port.h +++ b/include/wine/port.h @@ -48,6 +48,9 @@ # include <unistd.h> #endif
+#ifdef HAVE_SYS_XATTR_H +# include <sys/xattr.h> +#endif
/**************************************************************** * Type definitions @@ -117,6 +120,18 @@ struct statvfs #define mkdir(path,mode) mkdir(path) #endif
+#ifdef HAVE_SIX_ARG_FGETXATTR +#define fgetxattr(fd,name,val,size) fgetxattr(fd,name,val,size,0,0) +#endif + +#ifdef HAVE_SIX_ARG_FSETXATTR +#define fsetxattr(fd,name,val,size,opts) fsetxattr(fd,name,val,size,0,opts) +#endif + +#ifdef HAVE_THREE_ARG_FREMOVEXATTR +#define fremovexattr(fd,name) fremovexattr(fd,name,0) +#endif + #if !defined(HAVE_FTRUNCATE) && defined(HAVE_CHSIZE) #define ftruncate chsize #endif @@ -328,6 +343,21 @@ int symlink(const char *from, const char *to); int usleep (unsigned int useconds); #endif /* !defined(HAVE_USLEEP) */
+#ifndef HAVE_FGETXATTR +size_t fgetxattr (int fd, const char *name, void *value, size_t size); +#endif /* !defined(HAVE_FGETXATTR) */ + +#ifndef HAVE_FSETXATTR +#define XATTR_CREATE 1 +#define XATTR_REPLACE 2 +size_t fsetxattr (int fd, const char *name, const void *value, size_t size, + int opts); +#endif /* !defined(HAVE_FSETXATTR) */ + +#ifndef HAVE_FREMOVEXATTR +size_t fremovexattr (int fd, const char *name); +#endif /* !defined(HAVE_FREMOVEXATTR) */ + #ifdef __i386__ static inline void *memcpy_unaligned( void *dst, const void *src, size_t size ) { @@ -470,6 +500,12 @@ extern unsigned char interlocked_cmpxchg128( __int64 *dest, __int64 xchg_high, #define strerror __WINE_NOT_PORTABLE(strerror) #define strncasecmp __WINE_NOT_PORTABLE(strncasecmp) #define usleep __WINE_NOT_PORTABLE(usleep) +#undef fgetxattr +#define fgetxattr __WINE_NOT_PORTABLE(fgetxattr) +#undef fsetxattr +#define fsetxattr __WINE_NOT_PORTABLE(fsetxattr) +#undef fremovexattr +#define fremovexattr __WINE_NOT_PORTABLE(fremovexattr)
#endif /* NO_LIBWINE_PORT */
diff --git a/libs/port/Makefile.in b/libs/port/Makefile.in index c4c0127..e046562 100644 --- a/libs/port/Makefile.in +++ b/libs/port/Makefile.in @@ -8,6 +8,9 @@ MODULE = libwine_port.a
C_SRCS = \ ffs.c \ + fgetxattr.c \ + fremovexattr.c \ + fsetxattr.c \ fstatvfs.c \ futimes.c \ getopt.c \ diff --git a/libs/port/fgetxattr.c b/libs/port/fgetxattr.c new file mode 100644 index 0000000..196d11a --- /dev/null +++ b/libs/port/fgetxattr.c @@ -0,0 +1,96 @@ +/* + * fgetxattr function + * + * Copyright 2009 Benjamin Peddell + * + * 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.1 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#ifndef HAVE_FGETXATTR + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#ifdef HAVE_SYS_EXTATTR_H +# include <sys/extattr.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif +#include <errno.h> + +size_t fgetxattr (int fd, const char *name, void *value, size_t size){ +/* Solaris openat(fd,path,O_XATTR) support */ +#ifdef defined(HAVE_OPENAT) && defined(O_XATTR) + int ret; + size_t attrsize = -1; + off_t pos; + struct stat statbuf; + int attrfd; + if (strchr(name, '/') != NULL){ + errno = EINVAL; + return -1; + } + attrfd = openat(fd, name, O_XATTR | O_RDONLY); + if (attrfd >= 0){ + ret = fstat(attrfd, &statbuf); + if (ret >= 0){ + attrsize = (size_t)statbuf.st_size; + if (attrsize >= 0 && attrsize <= size){ + pos = 0; + while (pos < attrsize){ + ret = read(attrfd, value + pos, attrsize - pos); + if (ret > 0){ + pos += ret; + } else { + attrsize = pos; + } + } + } else { + errno = ERANGE; + } + } + close(attrfd); + } + if (attrsize >= 0){ + return attrsize; + } else { + return (size_t)ret; + } +/* FreeBSD extattr_get_fd support */ +#elif defined(HAVE_EXTATTR_GET_FD) + int nameofs; + int namespace; + if (strncmp (name, "user.", 5) == 0){ + namespace = EXTATTR_NAMESPACE_USER; + nameofs = 5; + } else if (strncmp (name, "system.", 7) == 0){ + namespace = EXTATTR_NAMESPACE_SYSTEM; + nameofs = 7; + } else { + errno = ENOENT; + return -1; + } + return extattr_get_fd (fd, namespace, name + nameofs, value, size); +#else + errno = ENOSYS; + return -1; +#endif +} + +#endif /* HAVE_FGETXATTR */ diff --git a/libs/port/fremovexattr.c b/libs/port/fremovexattr.c new file mode 100644 index 0000000..b752fb8 --- /dev/null +++ b/libs/port/fremovexattr.c @@ -0,0 +1,75 @@ +/* + * fremovexattr function + * + * Copyright 2009 Benjamin Peddell + * + * 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.1 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#ifndef HAVE_FREMOVEXATTR + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#ifdef HAVE_SYS_EXTATTR_H +# include <sys/extattr.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif +#include <errno.h> + +size_t fremovexattr (int fd, const char *name){ +/* Solaris openat(fd,path,O_XATTR) support */ +#ifdef defined(HAVE_UNLINKAT) && defined(HAVE_OPENAT) && defined(O_XATTR) + int ret; + int attrfd; + if (strchr(name, '/') != NULL){ + errno = EINVAL; + return -1; + } + attrfd = openat(fd, ".", O_RDONLY | O_XATTR); + if (attrfd >= 0){ + ret = unlinkat(attrfd, name, 0); + close(attrfd); + } else { + ret = attrfd; + } + return ret; +/* FreeBSD extattr_delete_fd support */ +#elif defined(HAVE_EXTATTR_SET_FD) + int nameofs; + int namespace; + if (strncmp (name, "user.", 5) == 0){ + namespace = EXTATTR_NAMESPACE_USER; + nameofs = 5; + } else if (strncmp (name, "system.", 7) == 0){ + namespace = EXTATTR_NAMESPACE_SYSTEM; + nameofs = 7; + } else { + errno = ENOENT; + return -1; + } + return extattr_delete_fd (fd, namespace, name + nameofs); +#else + errno = ENOSYS; + return -1; +#endif +} + +#endif /* HAVE_FREMOVEXATTR */ diff --git a/libs/port/fsetxattr.c b/libs/port/fsetxattr.c new file mode 100644 index 0000000..7640f81 --- /dev/null +++ b/libs/port/fsetxattr.c @@ -0,0 +1,102 @@ +/* + * fsetxattr function + * + * Copyright 2009 Benjamin Peddell + * + * 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.1 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#ifndef HAVE_FSETXATTR +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#ifdef HAVE_SYS_EXTATTR_H +# include <sys/extattr.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif +#include <errno.h> + +size_t fsetxattr (int fd, const char *name, const void *value, size_t size, + int opts){ +/* Solaris openat(fd,path,O_XATTR) support */ +#ifdef defined(HAVE_OPENAT) && defined(O_XATTR) + int ret; + size_t attrsize = -1; + off_t pos; + struct stat statbuf; + int attrfd; + int flags = O_XATTR | O_WRONLY | O_CREAT; + if (strchr(name, '/') != NULL){ + errno = EINVAL; + return -1; + } else if (strncmp (name, "SUNW", 4) == 0){ + errno = EINVAL; + return -1; + } else if (opts & XATTR_CREATE && opts & XATTR_REPLACE){ + errno = EINVAL; + return -1; + } else if (opts & XATTR_CREATE){ + flags |= O_EXCL; + } else if (opts & XATTR_REPLACE){ + flags &= ~O_CREAT; + } + attrfd = openat(fd, name, flags, 0666); + if (attrfd >= 0){ + pos = 0; + attrsize = size; + while (pos < attrsize){ + ret = write(attrfd, value + pos, attrsize - pos); + if (ret > 0){ + pos += ret; + } else { + attrsize = pos; + } + } + close(attrfd); + } else { + ret = attrfd; + } + if (attrsize >= 0){ + return attrsize; + } else { + return (size_t)ret; + } +/* FreeBSD extattr_set_fd support */ +#elif defined(HAVE_EXTATTR_SET_FD) + int nameofs; + int namespace; + if (strncmp (name, "user.", 5) == 0){ + namespace = EXTATTR_NAMESPACE_USER; + nameofs = 5; + } else if (strncmp (name, "system.", 7) == 0){ + namespace = EXTATTR_NAMESPACE_SYSTEM; + nameofs = 7; + } else { + errno = ENOENT; + return -1; + } + return extattr_set_fd (fd, namespace, name + nameofs, value, size); +#else + errno = ENOSYS; + return -1; +#endif +} + +#endif /* HAVE_FSETXATTR */