[PATCH] Add Extended Attribute support to libport

Benjamin Peddell klightspeed at netspace.net.au
Sun Nov 15 09:23:28 CST 2009


---
 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


--------------070406010207070401020609
Content-Type: text/x-vcard; charset=utf-8;
 name="klightspeed.vcf"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="klightspeed.vcf"

begin:vcard
fn:Ben Peddell
n:Peddell;Ben
email;internet:klighspeed at netspace.net.au
tel;home:+61747865419
tel;cell:+61431800195
x-mozilla-html:FALSE
version:2.1
end:vcard


--------------070406010207070401020609--



More information about the wine-devel mailing list