-----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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAksAm/4ACgkQTHDAI68NsumFzwCbBDcRbB8kFXroLeskA+hzgswu i0UAn3NHbau8AjSgtoruggBH3py+orcZ =tEvP -----END PGP SIGNATURE-----
>From 2ef84c7f8c849db18ce15366e72c6787fa83597d Mon Sep 17 00:00:00 2001 From: Benjamin Peddell <klightsp...@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 */ -- 1.6.4.4
<<attachment: klightspeed.vcf>>