From: Ross Lagerwall Date: Sun, 27 Jul 2014 19:21:33 +0000 (+0100) Subject: libnfs: Add lchown X-Git-Tag: upstream/1.9.6^2~15^2~3 X-Git-Url: https://git.piment-noir.org/?p=deb_libnfs.git;a=commitdiff_plain;h=5935a28a0e8cb9751f89ed7085b8e1d37c44d9d1 libnfs: Add lchown Add lchown which is like chown but operates on the symbolic link itself if the destination is a symbolic link. Signed-off-by: Ross Lagerwall --- diff --git a/include/nfsc/libnfs.h b/include/nfsc/libnfs.h index 2149b8a..a806fdb 100644 --- a/include/nfsc/libnfs.h +++ b/include/nfsc/libnfs.h @@ -1047,6 +1047,34 @@ EXTERN int nfs_chown_async(struct nfs_context *nfs, const char *path, int uid, i * -errno : The command failed. */ EXTERN int nfs_chown(struct nfs_context *nfs, const char *path, int uid, int gid); +/* + * Async chown() + * + * Like chown except if the destination is a symbolic link, it acts on the + * symbolic link itself. + * + * Function returns + * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. + * <0 : An error occured when trying to set up the operation. The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_lchown_async(struct nfs_context *nfs, const char *path, int uid, int gid, nfs_cb cb, void *private_data); +/* + * Sync chown() + * + * Like chown except if the destination is a symbolic link, it acts on the + * symbolic link itself. + * + * Function returns + * 0 : The operation was successfull. + * -errno : The command failed. + */ +EXTERN int nfs_lchown(struct nfs_context *nfs, const char *path, int uid, int gid); diff --git a/lib/libnfs-sync.c b/lib/libnfs-sync.c index 9d351f7..a31a607 100644 --- a/lib/libnfs-sync.c +++ b/lib/libnfs-sync.c @@ -1068,6 +1068,25 @@ int nfs_chown(struct nfs_context *nfs, const char *path, int uid, int gid) return cb_data.status; } +/* + * lchown() + */ +int nfs_lchown(struct nfs_context *nfs, const char *path, int uid, int gid) +{ + struct sync_cb_data cb_data; + + cb_data.is_finished = 0; + + if (nfs_lchown_async(nfs, path, uid, gid, chown_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_lchown_async failed"); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + + return cb_data.status; +} + /* * fchown() */ diff --git a/lib/libnfs.c b/lib/libnfs.c index 2acd172..a7ac3ef 100644 --- a/lib/libnfs.c +++ b/lib/libnfs.c @@ -4076,7 +4076,7 @@ static int nfs_chown_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_ } -int nfs_chown_async(struct nfs_context *nfs, const char *path, int uid, int gid, nfs_cb cb, void *private_data) +int nfs_chown_async_internal(struct nfs_context *nfs, const char *path, int no_follow, int uid, int gid, nfs_cb cb, void *private_data) { struct nfs_chown_data *chown_data; @@ -4089,7 +4089,7 @@ int nfs_chown_async(struct nfs_context *nfs, const char *path, int uid, int gid, chown_data->uid = uid; chown_data->gid = gid; - if (nfs_lookuppath_async(nfs, path, 0, cb, private_data, nfs_chown_continue_internal, chown_data, free, 0) != 0) { + if (nfs_lookuppath_async(nfs, path, no_follow, cb, private_data, nfs_chown_continue_internal, chown_data, free, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } @@ -4097,6 +4097,15 @@ int nfs_chown_async(struct nfs_context *nfs, const char *path, int uid, int gid, return 0; } +int nfs_chown_async(struct nfs_context *nfs, const char *path, int uid, int gid, nfs_cb cb, void *private_data) +{ + return nfs_chown_async_internal(nfs, path, 0, uid, gid, cb, private_data); +} + +int nfs_lchown_async(struct nfs_context *nfs, const char *path, int uid, int gid, nfs_cb cb, void *private_data) +{ + return nfs_chown_async_internal(nfs, path, 1, uid, gid, cb, private_data); +} /* * Async fchown()