Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support O_NOFOLLOW in nfs_open() #191

Closed
earlchew opened this issue May 3, 2017 · 3 comments
Closed

Support O_NOFOLLOW in nfs_open() #191

earlchew opened this issue May 3, 2017 · 3 comments

Comments

@earlchew
Copy link
Contributor

earlchew commented May 3, 2017

http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html

O_NOFOLLOW
If path names a symbolic link, fail and set errno to [ELOOP].

This option is relatively easy to support because the implementation has to go to some trouble to parse and follow symbolic links.

This patch looks rather larger than it actually is because I chose to break apart the predicate of the if-statement to insert the new code to implement O_NOFOLLOW semantics, and re-indent the body of the if-statement unchanged.

--- a/include/nfsc/libnfs.h
+++ b/include/nfsc/libnfs.h
@@ -455,13 +455,14 @@
  * Async open(<filename>)
  *
  * 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 @@
  * Async create()
  *
  * Same as nfs_creat_async but allows passing flags:
+ * O_NOFOLLOW
  * O_APPEND
  * O_SYNC
  * O_EXCL
--- a/lib/libnfs.c
+++ b/lib/libnfs.c
@@ -1467,28 +1467,35 @@
 	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);
-			free_nfs_cb_data(data);
-			return -1;
-		}
-
-		rl_args.symlink = *fh;
-
-		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);
+	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;

-		if (slash != NULL) {
-			*slash = '/';
+			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;
+                        }
+
+			rl_args.symlink = *fh;
+
+			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) {
@sahlberg
Copy link
Owner

sahlberg commented May 3, 2017 via email

@earlchew
Copy link
Contributor Author

earlchew commented May 3, 2017

Thanks for the feedback. I'll follow up with a pull request.

@sahlberg
Copy link
Owner

sahlberg commented May 9, 2017

Merged, thanks!

@sahlberg sahlberg closed this as completed May 9, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants