You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/07/30 03:30:00 UTC
[nuttx-apps] 01/02: system/popen: support r+, w+ mode
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git
commit e86f6c12a55e22d01516c7af416f28ec94b998a9
Author: dongjiuzhu1 <do...@xiaomi.com>
AuthorDate: Sat Jul 29 09:51:32 2023 +0800
system/popen: support r+, w+ mode
The standard popen uses the pipeline internally, so the stream
returned by it can only support read-only or write-only.
Now this patch is expanded through sockpair, which can support both
read and write. Therefore, we can use the stream to read and write
access this task (posix_spawn start).
Signed-off-by: dongjiuzhu1 <do...@xiaomi.com>
---
system/popen/popen.c | 78 +++++++++++++++++++++++++++++++++++++---------------
1 file changed, 56 insertions(+), 22 deletions(-)
diff --git a/system/popen/popen.c b/system/popen/popen.c
index 805667da1..8e09edcd0 100644
--- a/system/popen/popen.c
+++ b/system/popen/popen.c
@@ -115,11 +115,12 @@ FILE *popen(FAR const char *command, FAR const char *mode)
posix_spawn_file_actions_t file_actions;
FAR char *argv[4];
int fd[2];
- int oldfd;
- int newfd;
+ int oldfd[2];
+ int newfd[2];
int retfd;
int errcode;
- int result;
+ int result = 0;
+ bool rw = false;
/* Allocate a container for returned FILE stream */
@@ -130,34 +131,51 @@ FILE *popen(FAR const char *command, FAR const char *mode)
goto errout;
}
+ oldfd[1] = 0;
+ newfd[1] = 0;
+
/* Create a pipe. fd[0] refers to the read end of the pipe; fd[1] refers
* to the write end of the pipe.
+ * Is the pipe the input to the shell? Or the output?
*/
- result = pipe(fd);
- if (result < 0)
- {
- errcode = errno;
- goto errout_with_container;
- }
-
- /* Is the pipe the input to the shell? Or the output? */
-
- if (strcmp(mode, "r") == 0)
+ if (strcmp(mode, "r") == 0 && (result = pipe(fd)) >= 0)
{
/* Pipe is the output from the shell */
- oldfd = 1; /* Replace stdout with the write side of the pipe */
- newfd = fd[1];
- retfd = fd[0]; /* Use read side of the pipe to create the return stream */
+ oldfd[0] = 1; /* Replace stdout with the write side of the pipe */
+ newfd[0] = fd[1];
+ retfd = fd[0]; /* Use read side of the pipe to create the return stream */
}
- else if (strcmp(mode, "w") == 0)
+ else if (strcmp(mode, "w") == 0 && (result = pipe(fd)) >= 0)
{
/* Pipe is the input to the shell */
- oldfd = 0; /* Replace stdin with the read side of the pipe */
- newfd = fd[0];
- retfd = fd[1]; /* Use write side of the pipe to create the return stream */
+ oldfd[0] = 0; /* Replace stdin with the read side of the pipe */
+ newfd[0] = fd[0];
+ retfd = fd[1]; /* Use write side of the pipe to create the return stream */
+ }
+
+ /* Create a socketpair. Using fd[0] as the input and output to the shell */
+
+#if defined(CONFIG_NET_LOCAL) && defined(CONFIG_NET_LOCAL_STREAM)
+ else if ((strcmp(mode, "r+") == 0 || strcmp(mode, "w+") == 0) &&
+ (result = socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) >= 0)
+ {
+ /* Socketpair is the input/output to the shell */
+
+ rw = true;
+ oldfd[0] = 0; /* Replace stdin with the one side of a socket pair */
+ newfd[0] = fd[0];
+ oldfd[1] = 1; /* Replace stdout with the one side of a socket pair */
+ newfd[1] = fd[0];
+ retfd = fd[1]; /* Use other side of the socket pair to create the return stream */
+ }
+#endif
+ else if (result < 0)
+ {
+ errcode = errno;
+ goto errout_with_container;
}
else
{
@@ -236,12 +254,23 @@ FILE *popen(FAR const char *command, FAR const char *mode)
/* Redirect input or output as determined by the mode parameter */
- errcode = posix_spawn_file_actions_adddup2(&file_actions, newfd, oldfd);
+ errcode = posix_spawn_file_actions_adddup2(&file_actions,
+ newfd[0], oldfd[0]);
if (errcode != 0)
{
goto errout_with_actions;
}
+ if (rw)
+ {
+ errcode = posix_spawn_file_actions_adddup2(&file_actions,
+ newfd[1], oldfd[1]);
+ if (errcode != 0)
+ {
+ goto errout_with_actions;
+ }
+ }
+
/* Call task_spawn() (or posix_spawn), re-directing stdin or stdout
* appropriately.
*/
@@ -273,7 +302,12 @@ FILE *popen(FAR const char *command, FAR const char *mode)
* the interface.
*/
- close(newfd);
+ close(newfd[0]);
+
+ if (rw)
+ {
+ close(newfd[1]);
+ }
/* Free attributes and file actions. Ignoring return values in the case
* of an error.