apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michael Clark <mich...@metaparadigm.com>
Subject Extended Attributes Support
Date Thu, 20 Dec 2007 05:02:43 GMT
Hi Folks,

I have been doing some work on implementing extended attributes
support for apr.

I am doing this as I would like to add a property provider to
mod_dav_fs that uses extended attributes instead of a db per file
(TwistedDAV on Mac OS X also uses extended attributes for this BTW)
and I want to do this portably so it could potentially be included.

Extended attributes can also be used for setting mime-types on files
(mod_mime_xattr uses the native Linux API so this could be ported
to use portable apr xattrs and work on more platforms). Another nice
idea is setting file listing 'description' attributes and getting
mod_autoindex to look at them.

I have looked at a few of the OS extended attributes interface and
have come up with an API proposal (at the end of this mail).

It addresses:
  * setting, getting, listing and removing of 'user' extended attributes
    on a file specified by its filepath.

It does not address:
  * system namespaces on platforms with more than one attribute namespace
    (only the user namespace is accessible on platforms with multiple
     attr namespaces, new flags could potentially be added to access
     platform specific system namespaces)
  * setting, getting, listing and removing attributes on a file
    specified by a file descriptor (apr_os_file_t)

I have working sample implementations for Linux, Mac OS X, FreeBSD 6
and Solaris 10 (which each have different APIs BTW):

* Linux impl use l?(get|set|list|remove)xattr
* Mac OS X impl use (get|set|list|remove)xattr (different args to linux)
* FreeBSD impl uses extattr_(get|set|list|delete)_(file|link)
* Solaris impl uses subfiles (attropen,unlinkat and friends)

Not implemented:

* Windows - should be able to use named :streams (similar to Solaris)
* OS/2 - it has extended attributes but that's all I know.
* Irix/HPUX/AIX/OS390/netware/... - unknown? do they have them?

Any ideas on feasibility on these and other apr supported platforms?

I'll send some initial patches soon. They still need a little work
and some more test cases.

I have some questions on build structure...

Should I put the declarations in apr_file_info.h or would it be
better to add a apr_file_xattr.h header?

I have all the unix implementations rolled into one file
(file_io/unix/xattr.c) with many #if's. Should I perhaps have
a linux.c, darwin.c, freebsd.c, solaris.c in a subdirectory?
Not sure how I would integrate this into the build (perhaps
having a single #if that create empty compilation units for
the inactive platforms?).

Test cases should go into a new unit - not linked into testall?

Also what is the procedure for proposing and adding a new API like
this. I guess my patch should have it disabled by default and enabled
with a configure flag - say --enable-xattrs (or autodetected and enabled
on supported platforms)?

Proposed API:

/**
  * @defgroup apr_file_xattr File Extended Attribute Functions
  * @{
  */

/** Don't follow symbolic links flag for apr_file_xattr functions */
#define APR_XATTR_NOFOLLOW    1

/** When setting values, fail if the attribute already exists */
#define APR_XATTR_CREATE      2

/** When setting values, fail if the attribute does not already exist */
#define APR_XATTR_REPLACE     4

/**
* Set an extended attribute on the file specificed by filepath
* @param filepath the full path to the file
* @param name the attribute name to set
* @param value the attribute value
* @param size the size in bytes of the attribute value
* @param flags to control how the attribute is set
* <PRE>
*         APR_XATTR_NOFOLLOW    if the file is a symbolic link then the
*                               attribute will be set on the link.
*         APR_XATTR_CREATE      return an error if the attribute name
*                               already exists.
*         APR_XATTR_REPLACE     return an error if the attribute name
*                               does not already exist.
* </PRE>
* @param p the pool to allocate any memory from if required
* @remark if neither flag APR_XATTR_CREATE or APR_XATTR_REPLACE are
* given then the attribute will either be created if it does not
* already exist or replaced if it does exist.
*/
APR_DECLARE(apr_status_t) apr_file_xattr_set(const char *filepath,
                                             const char *name,
                                             const void *value,
                                             apr_size_t size,
                                             apr_int32_t flags,
                                             apr_pool_t *p);

/**
* Get an extended attribute from the file specificed by filepath
* @param filepath the full path to the file
* @param name the attribute name to get
* @param value the returned attribute value, if value is NULL then only
* the size of the attribute value is returned
* @param size the returned size of the attribute value
* @param flags to control how the attribute is got
* <PRE>
*         APR_XATTR_NOFOLLOW    if the file is a symbolic link then the
*                               attribute will be gotten from the link.
* </PRE>
* @param p the pool to allocate any memory from if required
*/
APR_DECLARE(apr_status_t) apr_file_xattr_get(const char *filepath,
                                             const char *name,
                                             void **value,
                                             apr_size_t *size,
                                             apr_int32_t flags,
                                             apr_pool_t *p);

/**
  * List the extended attributes for the file specificed by filepath
  * @param filepath the full path to the file
  * @param list the returned array of attributes names
  * @param flags to control how the file is listed
  * <PRE>
  *         APR_XATTR_NOFOLLOW    if the file is a symbolic link then the
  *                               attributes of the link will be listed.
  * </PRE>
  * @param p the pool to allocate any memory from if required
  * @remark list is an array containing simple null terminated strings.
  */
APR_DECLARE(apr_status_t) apr_file_xattr_list(const char *filepath,
                                               apr_array_header_t **list,
                                               apr_int32_t flags,
                                               apr_pool_t *p);

/**
* Remove an extended attribute from the file specificed by filepath
* @param filepath the full path to the file
* @param name the attribute name to remove
* @param flags to control how the attribute is removed
* <PRE>
*         APR_XATTR_NOFOLLOW    if the file is a symbolic link then the
*                               attribute will be removed from the link.
* </PRE>
* @param p the pool to allocate any memory from if required
*/
APR_DECLARE(apr_status_t) apr_file_xattr_remove(const char *filepath,
                                                const char *name,
                                                apr_int32_t flags,
                                                apr_pool_t *p);

/** @} */


Mime
View raw message