Index: file_io/unix/xattr/darwin.c
===================================================================
--- file_io/unix/xattr/darwin.c	(revision 0)
+++ file_io/unix/xattr/darwin.c	(revision 0)
@@ -0,0 +1,131 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_strings.h"
+#include "apr_tables.h"
+#include "apr_file_xattr.h"
+#include "apr_arch_file_io.h"
+
+#if APR_HAVE_SYS_XATTR_H
+#include <sys/xattr.h>
+#endif
+#if APR_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+
+APR_DECLARE(apr_status_t) apr_file_xattr_set(apr_file_t *file,
+                                             const char *name,
+                                             const void *value,
+                                             apr_size_t size,
+                                             apr_uint32_t flags,
+                                             apr_pool_t *p)
+{
+    int ret;
+    int osflags = 0;
+
+    if (flags & APR_XATTR_CREATE) {
+        osflags |= XATTR_CREATE;
+    }
+    if (flags & APR_XATTR_REPLACE) {
+        osflags |= XATTR_REPLACE;
+    }
+
+    ret = fsetxattr(file->filedes, name, value, size, 0, osflags);
+
+    if (ret < 0) {
+        return errno;
+    }
+    return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_file_xattr_get(apr_file_t *file,
+                                             const char *name,
+                                             void **value,
+                                             apr_size_t *size,
+                                             apr_uint32_t flags,
+                                             apr_pool_t *p)
+{
+    apr_ssize_t ret;
+
+    ret = fgetxattr(file->filedes, name, NULL, 0, 0, 0);
+
+    if (ret < 0) {
+        return errno;
+    }
+    if (!value) {
+        *size = ret;
+        return APR_SUCCESS;
+    }
+    *value = apr_palloc(p, ret);
+
+    ret = fgetxattr(file->filedes, name, *value, ret, 0, 0);
+
+    if (ret < 0) {
+        return errno;
+    }
+    *size = ret;
+    return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_file_xattr_list(apr_file_t *file,
+                                              apr_array_header_t **list,
+                                              apr_uint32_t flags,
+                                              apr_pool_t *p)
+{
+    apr_ssize_t lsize;
+    char *listbuf, *listp;
+
+    lsize = flistxattr(file->filedes, NULL, 0, 0);
+
+    if (lsize < 0) {
+        return errno;
+    }
+    if (lsize == 0) {
+        *list = apr_array_make(p, 0, sizeof(char*));
+        return APR_SUCCESS;
+    }
+    listbuf = apr_palloc(p, lsize);
+
+    lsize = flistxattr(file->filedes, listbuf, lsize, 0);
+
+    if (lsize < 0) {
+        return errno;
+    }
+    *list = apr_array_make(p, 1, sizeof(char*));
+    listp = listbuf;
+    while (listp < listbuf + lsize) {
+        int attrlen = strlen(listp) + 1;
+        *(char**)apr_array_push(*list) = listp;
+        listp += attrlen;
+    }
+    return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_file_xattr_remove(apr_file_t *file,
+                                                const char *name,
+                                                apr_uint32_t flags,
+                                                apr_pool_t *p)
+{
+    int ret;
+
+    ret = fremovexattr(file->filedes, name, 0);
+
+    if (ret < 0) {
+        return errno;
+    }
+    return APR_SUCCESS;
+}

