* eio: add eio_file_chmod and eio_file_chown.

SVN revision: 53678
This commit is contained in:
Cedric BAIL 2010-10-20 16:42:45 +00:00
parent 534c5d617d
commit 06ea9c415d
3 changed files with 209 additions and 1 deletions

View File

@ -79,7 +79,9 @@ typedef enum _Eio_File_Op
EIO_FILE_MOVE, /**< IO operation is about a specific file move */
EIO_DIR_COPY, /**< IO operation is about a specific directory copy */
EIO_DIR_MOVE, /**< IO operation is about a specific directory move */
EIO_UNLINK /**< IO operation is about a destroying a path (source will point to base path to be destroyed and dest to path destroyed by this IO */
EIO_UNLINK, /**< IO operation is about a destroying a path (source will point to base path to be destroyed and dest to path destroyed by this IO */
EIO_FILE_GETPWNAM, /**< IO operation is trying to get uid from user name */
EIO_FILE_GETGRNAM /**< IO operation is trying to get gid from user name */
} Eio_File_Op;
typedef struct _Eio_File Eio_File; /**< Generic asynchronous IO reference */
@ -131,6 +133,19 @@ EAPI Eio_File *eio_file_direct_stat(const char *path,
Eio_Error_Cb error_cb,
const void *data);
EAPI Eio_File *eio_file_chmod(const char *path,
mode_t mode,
Eio_Done_Cb done_cb,
Eio_Error_Cb error_cb,
const void *data);
EAPI Eio_File *eio_file_chown(const char *path,
const char *user,
const char *group,
Eio_Done_Cb done_cb,
Eio_Error_Cb error_cb,
const void *data);
EAPI Eio_File *eio_file_unlink(const char *path,
Eio_Done_Cb done_cb,
Eio_Error_Cb error_cb,

View File

@ -33,6 +33,8 @@
#include <sys/mman.h>
#include <fcntl.h>
#include <pthread.h>
#include <pwd.h>
#include <grp.h>
#include <Ecore.h>
@ -49,10 +51,12 @@ typedef struct _Eio_File_Ls Eio_File_Ls;
typedef struct _Eio_File_Direct_Ls Eio_File_Direct_Ls;
typedef struct _Eio_File_Char_Ls Eio_File_Char_Ls;
typedef struct _Eio_File_Mkdir Eio_File_Mkdir;
typedef struct _Eio_File_Mkdir Eio_File_Chmod;
typedef struct _Eio_File_Unlink Eio_File_Unlink;
typedef struct _Eio_File_Stat Eio_File_Stat;
typedef struct _Eio_File_Progress Eio_File_Progress;
typedef struct _Eio_File_Move Eio_File_Move;
typedef struct _Eio_File_Chown Eio_File_Chown;
typedef struct _Eio_Dir_Copy Eio_Dir_Copy;
@ -141,6 +145,15 @@ struct _Eio_Dir_Copy
Eina_List *dirs;
};
struct _Eio_File_Chown
{
Eio_File common;
const char *path;
const char *user;
const char *group;
};
/* Be aware that ecore_thread_run could call cancel_cb if something goes wrong. */
Eina_Bool eio_file_set(Eio_File *common,
Eio_Done_Cb done_cb,

View File

@ -202,6 +202,100 @@ _eio_file_stat_error(void *data)
_eio_stat_free(s);
}
static void
_eio_file_chmod(Ecore_Thread *thread, void *data)
{
Eio_File_Chmod *ch = data;
if (chmod(ch->path, ch->mode) != 0)
eio_file_thread_error(&ch->common, thread);
}
static void
_eio_file_chown(Ecore_Thread *thread, void *data)
{
Eio_File_Chown *own = data;
char *tmp;
uid_t owner = -1;
gid_t group = -1;
own->common.error = 0;
if (own->user)
{
owner = strtol(own->user, &tmp, 10);
if (*tmp != '\0')
{
struct passwd *pw = NULL;
own->common.error = EIO_FILE_GETPWNAM;
pw = getpwnam(own->user);
if (!pw) goto on_error;
owner = pw->pw_uid;
}
}
if (own->group)
{
group = strtol(own->group, &tmp, 10);
if (*tmp != '\0')
{
struct group *grp = NULL;
own->common.error = EIO_FILE_GETGRNAM;
grp = getgrnam(own->group);
if (!grp) goto on_error;
group = grp->gr_gid;
}
}
if (owner == (uid_t) -1 && group == (gid_t) -1)
goto on_error;
if (chown(own->path, owner, group) != 0)
eio_file_thread_error(&own->common, thread);
return ;
on_error:
ecore_thread_cancel(thread);
return ;
}
static void
_eio_chown_free(Eio_File_Chown *ch)
{
if (ch->user) eina_stringshare_del(ch->user);
if (ch->group) eina_stringshare_del(ch->group);
eina_stringshare_del(ch->path);
free(ch);
}
static void
_eio_file_chown_done(void *data)
{
Eio_File_Chown *ch = data;
if (ch->common.done_cb)
ch->common.done_cb((void*) ch->common.data);
_eio_chown_free(ch);
}
static void
_eio_file_chown_error(void *data)
{
Eio_File_Chown *ch = data;
eio_file_error(&ch->common);
_eio_chown_free(ch);
}
/**
* @addtogroup Eio_Group Asynchronous Inout/Output library
@ -327,6 +421,92 @@ eio_file_mkdir(const char *path,
return &r->common;
}
/**
* @brief Change right of a path.
* @param path The directory path to change access right.
* @param mode The permission to set, follow (mode & ~umask & 0777).
* @param done_cb Callback called from the main loop when the directory has been created.
* @param error_cb Callback called from the main loop when the directory failed to be created or has been canceled.
* @param data Private data given to callback.
* @return A reference to the IO operation.
*
* eio_file_chmod basically call chmod in another thread. This prevent any lock in your apps.
*/
EAPI Eio_File *
eio_file_chmod(const char *path,
mode_t mode,
Eio_Done_Cb done_cb,
Eio_Error_Cb error_cb,
const void *data)
{
Eio_File_Mkdir *r = NULL;
if (!path || !done_cb || !error_cb)
return NULL;
r = malloc(sizeof (Eio_File_Mkdir));
if (!r) return NULL;
r->path = eina_stringshare_add(path);
r->mode = mode;
if (!eio_file_set(&r->common,
done_cb,
error_cb,
data,
_eio_file_chmod,
_eio_file_mkdir_done,
_eio_file_mkdir_error))
return NULL;
return &r->common;
}
/**
* @brief Change owner of a path.
* @param path The directory path to change owner.
* @param user The new user to set (could be NULL).
* @param group The new group to set (could be NULL).
* @param done_cb Callback called from the main loop when the directory has been created.
* @param error_cb Callback called from the main loop when the directory failed to be created or has been canceled.
* @param data Private data given to callback.
* @return A reference to the IO operation.
*
* eio_file_chown determine the uid/gid that correspond to both user and group string and then call chown. This prevent any lock in your apps by calling
* this function from another thread. The string could be the name of the user or the name of the group or directly their numerical value.
*/
EAPI Eio_File *eio_file_chown(const char *path,
const char *user,
const char *group,
Eio_Done_Cb done_cb,
Eio_Error_Cb error_cb,
const void *data)
{
Eio_File_Chown *c = NULL;
if (!path || !done_cb || !error_cb)
return NULL;
c = malloc(sizeof (Eio_File_Chown));
if (!c) return NULL;
c->path = eina_stringshare_add(path);
c->user = eina_stringshare_add(user);
c->group = eina_stringshare_add(group);
if (!eio_file_set(&c->common,
done_cb,
error_cb,
data,
_eio_file_chown,
_eio_file_chown_done,
_eio_file_chown_error))
return NULL;
return &c->common;
}
/**
* @}
*/