[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