eio: more xattr support.

SVN revision: 60824
This commit is contained in:
Cedric BAIL 2011-06-29 17:28:55 +00:00
parent b24e04ac82
commit 73edb0433f
3 changed files with 241 additions and 0 deletions

View File

@ -90,6 +90,17 @@ enum _Eio_File_Op
EIO_FILE_GETGRNAM /**< IO operation is trying to get gid from user name */
};
/**
* @enum Eio_Xattr_Flags
* Xattr creation flags
*/
typedef enum
{
EIO_XATTR_INSERT = 0, /**< Xattr will always be set */
EIO_XATTR_CREATED, /**< Xattr will be created, but will fail if already exists */
EIO_XATTR_REPLACE /**< Xattr will replace the existing value or fail if no value exist before */
} Eio_Xattr_Flags;
/**
* @typedef Eio_File_Op
* Input/Output operations on files.
@ -117,6 +128,8 @@ typedef void (*Eio_Main_Direct_Cb)(void *data, Eio_File *handler, const Eina_Fil
typedef void (*Eio_Stat_Cb)(void *data, Eio_File *handler, const struct stat *stat);
typedef void (*Eio_Progress_Cb)(void *data, Eio_File *handler, const Eio_Progress *info);
typedef void (*Eio_Done_Length_Cb)(void *data, Eio_File *handler, const char *xattr_data, unsigned int xattr_size);
typedef void (*Eio_Done_Cb)(void *data, Eio_File *handler);
typedef void (*Eio_Error_Cb)(void *data, Eio_File *handler, int error);
@ -236,6 +249,21 @@ EAPI Eio_File *eio_file_xattr(const char *path,
Eio_Error_Cb error_cb,
const void *data);
EAPI Eio_File *eio_file_xattr_set(const char *path,
const char *attribute,
const char *xattr_data,
unsigned int xattr_size,
Eio_Xattr_Flags flags,
Eio_Done_Cb done_cb,
Eio_Error_Cb error_cb,
const void *data);
EAPI Eio_File *eio_file_xattr_get(const char *path,
const char *attribute,
Eio_Done_Length_Cb done_cb,
Eio_Error_Cb error_cb,
const void *data);
EAPI void *eio_file_container_get(Eio_File *ls);
EAPI Eina_Bool eio_file_cancel(Eio_File *ls);

View File

@ -61,6 +61,8 @@ typedef struct _Eio_File_Move Eio_File_Move;
typedef struct _Eio_File_Chown Eio_File_Chown;
typedef struct _Eio_Monitor_Backend Eio_Monitor_Backend;
typedef struct _Eio_File_Xattr Eio_File_Xattr;
typedef struct _Eio_Dir_Copy Eio_Dir_Copy;
typedef struct _Eio_File_Direct_Info Eio_File_Direct_Info;
@ -152,6 +154,20 @@ struct _Eio_File_Stat
const char *path;
};
struct _Eio_File_Xattr
{
Eio_File common;
Eio_Done_Length_Cb done_cb;
const char *path;
const char *attribute;
int flags;
char *xattr_data;
unsigned int xattr_size;
};
struct _Eio_File_Progress
{
Eio_File common;

View File

@ -78,6 +78,95 @@ _eio_ls_xattr_notify(void *data, Ecore_Thread *thread __UNUSED__, void *msg_data
async->main_cb((void*) async->ls.common.data, &async->ls.common, xattr);
}
static void
_eio_file_xattr_get(void *data, Ecore_Thread *thread)
{
Eio_File_Xattr *async = data;
ssize_t sz;
async->xattr_size = 0;
async->xattr_data = NULL;
sz = getxattr(async->path, async->attribute, NULL, 0);
if (sz > 0 && sz < 2 * 1024 * 1024) /* sz should be smaller than 2MB (already huge in my opinion) */
{
async->xattr_data = malloc(sz);
async->xattr_size = (unsigned int) sz;
sz = getxattr(async->path, async->attribute, async->xattr_data, async->xattr_size);
if (sz != async->xattr_size)
{
free(async->xattr_data);
async->xattr_data = NULL;
async->xattr_size = 0;
ecore_thread_cancel(thread);
}
}
else
ecore_thread_cancel(thread);
}
static void
_eio_file_xattr_free(Eio_File_Xattr *async)
{
eina_stringshare_del(async->path);
eina_stringshare_del(async->attribute);
free(async->xattr_data);
free(async);
}
static void
_eio_file_xattr_get_done(void *data, Ecore_Thread *thread __UNUSED__)
{
Eio_File_Xattr *async = data;
if (async->done_cb)
async->done_cb((void *) async->common.data, &async->common, async->xattr_data, async->xattr_size);
_eio_file_xattr_free(async);
}
static void
_eio_file_xattr_get_error(void *data, Ecore_Thread *thread __UNUSED__)
{
Eio_File_Xattr *async = data;
eio_file_error(&async->common);
_eio_file_xattr_free(async);
}
static void
_eio_file_xattr_set(void *data, Ecore_Thread *thread)
{
Eio_File_Xattr *async = data;
if (setxattr(async->path, async->attribute, async->xattr_data, async->xattr_size, async->flags))
eio_file_thread_error(&async->common, thread);
async->xattr_data = NULL;
}
static void
_eio_file_xattr_set_done(void *data, Ecore_Thread *thread __UNUSED__)
{
Eio_File_Xattr *async = data;
if (async->common.done_cb)
async->common.done_cb((void*) async->common.data, &async->common);
_eio_file_xattr_free(async);
}
static void
_eio_file_xattr_set_error(void *data, Ecore_Thread *thread __UNUSED__)
{
Eio_File_Xattr *async = data;
eio_file_error(&async->common);
_eio_file_xattr_free(async);
}
#endif
/**
@ -147,6 +236,114 @@ eio_file_xattr(const char *path,
#endif
}
/**
* @brief Retrieve the extended attribute of a file/directory.
* @param path The path to retrieve the extended attribute from.
* @param attribute The name of the attribute to retrieve.
* @param done_cb Callback called from the main loop when getxattr succeeded.
* @param error_cb Callback called from the main loop when getxattr failed or has been canceled.
* @param data Private data given to callback.
* @return A reference to the IO operation.
*
* eio_file_xattr_get call getxattr from another thread. This prevent lock in your apps.
*/
EAPI Eio_File *
eio_file_xattr_get(const char *path,
const char *attribute,
Eio_Done_Length_Cb done_cb,
Eio_Error_Cb error_cb,
const void *data)
{
#ifdef HAVE_XATTR
Eio_File_Xattr *async;
if (!path || !attribute || !done_cb || !error_cb)
return NULL;
async = malloc(sizeof (Eio_File_Xattr));
if (!async) return NULL;
async->path = eina_stringshare_add(path);
async->attribute = eina_stringshare_add(attribute);
async->done_cb = done_cb;
if (!eio_file_set(&async->common,
NULL,
error_cb,
data,
_eio_file_xattr_get,
_eio_file_xattr_get_done,
_eio_file_xattr_get_error))
return NULL;
return &async->common;
#else
return NULL;
#endif
}
/**
* @brief Define the extented attribute on a file/directory.
* @param path The path to set the attribute on.
* @param attribute The name of the attribute to define.
* @param xattr_data The data to link the attribute with.
* @param xattr_size The size of the data to set.
* @param done_cb The callback called from the main loop when setxattr succeeded.
* @param error_cb The callback called from the main loop when setxattr failed.
* @param data Private data given to callback.
* @return A reference to the IO operation.
*
* eio_file_xattr_set call setxattr from another thread. This prevent lock in your apps. If
* the writing succeeded, the done_cb will be called even if a cancel was requested, but came to late.
*/
EAPI Eio_File *
eio_file_xattr_set(const char *path,
const char *attribute,
const char *xattr_data,
unsigned int xattr_size,
Eio_Xattr_Flags flags,
Eio_Done_Cb done_cb,
Eio_Error_Cb error_cb,
const void *data)
{
Eio_File_Xattr *async;
int iflags;
if (!path || !attribute || !done_cb || !xattr_data || !xattr_size || !error_cb)
return NULL;
switch (flags)
{
case EIO_XATTR_INSERT: iflags = 0; break;
case EIO_XATTR_REPLACE: iflags = XATTR_REPLACE; break;
case EIO_XATTR_CREATED: iflags = XATTR_CREATE; break;
default:
return NULL;
}
async = malloc(sizeof (Eio_File_Xattr) + xattr_size);
if (!async) return NULL;
async->path = eina_stringshare_add(path);
async->attribute = eina_stringshare_add(attribute);
async->xattr_size = xattr_size;
async->xattr_data = (char*) (async + 1);
memcpy(async->xattr_data, xattr_data, xattr_size);
async->flags = iflags;
if (!eio_file_set(&async->common,
done_cb,
error_cb,
data,
_eio_file_xattr_set,
_eio_file_xattr_set_done,
_eio_file_xattr_set_error))
return NULL;
return &async->common;
}
/**
* @}
*/