diff --git a/include/nfsc/libnfs.h b/include/nfsc/libnfs.h index ff7350e3..c2fd7313 100644 --- a/include/nfsc/libnfs.h +++ b/include/nfsc/libnfs.h @@ -455,13 +455,14 @@ EXTERN uint16_t nfs_umask(struct nfs_context *nfs, uint16_t mask); * Async open() * * mode is a combination of the flags : - * O_RDONLY, O_WRONLY, O_RDWR , O_SYNC, O_APPEND, O_TRUNC + * O_RDONLY, O_WRONLY, O_RDWR , O_SYNC, O_APPEND, O_TRUNC, O_NOFOLLOW * * 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. * * Supported flags are + * O_NOFOLLOW * O_APPEND * O_RDONLY * O_WRONLY @@ -812,6 +813,7 @@ EXTERN int nfs_creat(struct nfs_context *nfs, const char *path, int mode, struct * Async create() * * Same as nfs_creat_async but allows passing flags: + * O_NOFOLLOW * O_APPEND * O_SYNC * O_EXCL diff --git a/lib/libnfs.c b/lib/libnfs.c index 77d95348..6ef50202 100644 --- a/lib/libnfs.c +++ b/lib/libnfs.c @@ -1461,28 +1461,35 @@ static int nfs_lookup_path_async_internal(struct nfs_context *nfs, fattr3 *attr, path = data->path; slash = strchr(path, '/'); - if (attr && attr->type == NF3LNK && (!data->no_follow || *path != '\0')) { - READLINK3args rl_args; - - if (data->link_count++ >= MAX_LINK_COUNT) { - data->cb(-ELOOP, nfs, "Too many levels of symbolic links", data->private_data); + if (attr && attr->type == NF3LNK) { + if (data->continue_int & O_NOFOLLOW) { + data->cb(-ELOOP, nfs, "Symbolic link encountered", data->private_data); free_nfs_cb_data(data); return -1; } + if (!data->no_follow || *path != '\0') { + READLINK3args rl_args; - rl_args.symlink = *fh; + if (data->link_count++ >= MAX_LINK_COUNT) { + data->cb(-ELOOP, nfs, "Too many levels of symbolic links", data->private_data); + free_nfs_cb_data(data); + return -1; + } - if (rpc_nfs3_readlink_async(nfs->rpc, nfs_lookup_path_2_cb, &rl_args, data) != 0) { - rpc_set_error(nfs->rpc, "RPC error: Failed to send READLINK call for %s", data->path); - data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); - free_nfs_cb_data(data); - return -1; - } + rl_args.symlink = *fh; - if (slash != NULL) { - *slash = '/'; + if (rpc_nfs3_readlink_async(nfs->rpc, nfs_lookup_path_2_cb, &rl_args, data) != 0) { + rpc_set_error(nfs->rpc, "RPC error: Failed to send READLINK call for %s", data->path); + data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); + free_nfs_cb_data(data); + return -1; + } + + if (slash != NULL) { + *slash = '/'; + } + return 0; } - return 0; } if (slash != NULL) {