This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git


The following commit(s) were added to refs/heads/master by this push:
     new 4da9affc9 system/popen: Remove it and use the popen() of libc.
4da9affc9 is described below

commit 4da9affc96bdb426cd241de7e05e822ee2031414
Author: Marco Casaroli <[email protected]>
AuthorDate: Mon Oct 19 15:54:16 2026 +0200

    system/popen: Remove it and use the popen() of libc.
    
    libc has popen(), pclose(), dpopen() and dpclose() when CONFIG_PIPES,
    CONFIG_LIBC_EXECFUNCS and CONFIG_SCHED_WAITPID are set, and no
    configuration in nuttx enables CONFIG_SYSTEM_POPEN any more.
    
    Remove the code of system/popen.  The fastboot shell command, the popen
    test, the popen example, dhcpd and gdbstub now depend on the libc
    conditions only.
    
    Remove CONFIG_SYSTEM_POPEN too.  It selected CONFIG_LIBC_EXECFUNCS and
    CONFIG_SCHED_WAITPID, so a configuration that sets only it must now set
    these two options in its place.
    
    The options of the old copy for the priority, the stack size, the shell
    path and the number of arguments have no replacement: popen() uses the
    posix_spawn() defaults.  popen() does not accept the modes "r+" and "w+";
    dpopen() with O_RDWR gives a bidirectional pipe.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 examples/popen/Kconfig      |   2 +-
 netutils/dhcpd/dhcpd.c      |   4 +-
 system/fastboot/Kconfig     |   2 +-
 system/gdbstub/gdbstub.c    |   4 +-
 system/popen/CMakeLists.txt |  25 ---
 system/popen/Kconfig        |  73 ---------
 system/popen/Make.defs      |  25 ---
 system/popen/Makefile       |  29 ----
 system/popen/dpopen.c       | 374 --------------------------------------------
 system/popen/popen.c        | 277 --------------------------------
 testing/libc/popen/Kconfig  |   2 +-
 11 files changed, 7 insertions(+), 810 deletions(-)

diff --git a/examples/popen/Kconfig b/examples/popen/Kconfig
index ebe65d468..f27b2a164 100644
--- a/examples/popen/Kconfig
+++ b/examples/popen/Kconfig
@@ -6,7 +6,7 @@
 config EXAMPLES_POPEN
        tristate "popen() example"
        default n
-       depends on SYSTEM_POPEN || (PIPES && LIBC_EXECFUNCS && SCHED_WAITPID)
+       depends on PIPES && LIBC_EXECFUNCS && SCHED_WAITPID
        depends on !DISABLE_POSIX_TIMERS
        ---help---
                Enable the popen() example
diff --git a/netutils/dhcpd/dhcpd.c b/netutils/dhcpd/dhcpd.c
index 47e7b737d..9fdca8cc9 100644
--- a/netutils/dhcpd/dhcpd.c
+++ b/netutils/dhcpd/dhcpd.c
@@ -1525,8 +1525,8 @@ static pid_t dhcpd_get_pid(void)
 
 #if !defined(CONFIG_BUILD_KERNEL)
   pid = g_dhcpd_daemon.ds_pid;
-#elif defined(CONFIG_SYSTEM_POPEN) || (defined(CONFIG_PIPES) && \
-      defined(CONFIG_LIBC_EXECFUNCS) && defined(CONFIG_SCHED_WAITPID))
+#elif defined(CONFIG_PIPES) && defined(CONFIG_LIBC_EXECFUNCS) && \
+      defined(CONFIG_SCHED_WAITPID)
   FAR FILE *fp;
   char line[32];
 
diff --git a/system/fastboot/Kconfig b/system/fastboot/Kconfig
index fe0183ac5..fa551d26f 100644
--- a/system/fastboot/Kconfig
+++ b/system/fastboot/Kconfig
@@ -58,7 +58,7 @@ config SYSTEM_FASTBOOTD_SHELL
        bool "Execute custom commands"
        default n
        depends on SCHED_CHILD_STATUS
-       depends on SYSTEM_POPEN || (PIPES && LIBC_EXECFUNCS && SCHED_WAITPID)
+       depends on PIPES && LIBC_EXECFUNCS && SCHED_WAITPID
        ---help---
                Enable to support executing custom commands.
                e.g. fastboot oem shell ps
diff --git a/system/gdbstub/gdbstub.c b/system/gdbstub/gdbstub.c
index a93c8c78d..9085a0860 100644
--- a/system/gdbstub/gdbstub.c
+++ b/system/gdbstub/gdbstub.c
@@ -38,8 +38,8 @@
 
 static int gdb_monitor(FAR struct gdb_state_s *state, FAR const char *cmd)
 {
-#if defined(CONFIG_SYSTEM_POPEN) || (defined(CONFIG_PIPES) && \
-    defined(CONFIG_LIBC_EXECFUNCS) && defined(CONFIG_SCHED_WAITPID))
+#if defined(CONFIG_PIPES) && defined(CONFIG_LIBC_EXECFUNCS) && \
+    defined(CONFIG_SCHED_WAITPID)
   FAR FILE *file;
 
   file = popen(cmd, "r");
diff --git a/system/popen/CMakeLists.txt b/system/popen/CMakeLists.txt
deleted file mode 100644
index 353205d24..000000000
--- a/system/popen/CMakeLists.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-# 
##############################################################################
-# apps/system/popen/CMakeLists.txt
-#
-# SPDX-License-Identifier: Apache-2.0
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more 
contributor
-# license agreements.  See the NOTICE file distributed with this work for
-# additional information regarding copyright ownership.  The ASF licenses this
-# file to you under the Apache License, Version 2.0 (the "License"); you may 
not
-# use this file except in compliance with the License.  You may obtain a copy 
of
-# the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations under
-# the License.
-#
-# 
##############################################################################
-
-if(CONFIG_SYSTEM_POPEN)
-  target_sources(apps PRIVATE dpopen.c popen.c)
-endif()
diff --git a/system/popen/Kconfig b/system/popen/Kconfig
deleted file mode 100644
index 6256af7c4..000000000
--- a/system/popen/Kconfig
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see the file kconfig-language.txt in the NuttX tools repository.
-#
-
-config SYSTEM_POPEN
-       bool "popen()/pclose()/dpopen()/dpclose() Functions"
-       default n
-       select SCHED_WAITPID
-       depends on PIPES
-       ---help---
-               Enable support for the popen(), pclose(), dpopen(), and
-               dpclose() interfaces.
-
-               dpopen()/dpclose() are the descriptor-based counterparts
-               of popen()/pclose(), analogous to how dprintf() relates
-               to fprintf().  They return a raw file descriptor instead
-               of a FILE stream, avoiding the stdio.h dependency.
-
-               popen()/pclose() are thin wrappers around dpopen()/dpclose()
-               that additionally wrap the fd in a FILE stream.
-
-               When NSH is available (NSH_LIBRARY), commands are executed
-               through the shell (sh -c command), supporting full shell
-               syntax including pipes, redirects, and globbing.
-
-               When NSH is not available, commands are executed directly
-               via posix_spawnp(). The command string must be a simple
-               "program arg1 arg2" form without shell syntax.
-
-if SYSTEM_POPEN
-
-config SYSTEM_POPEN_SHPATH
-       string "Path to shell command"
-       default "/bin/sh"
-       depends on (SYSTEM_NSH=m || BUILD_KERNEL) && NSH_LIBRARY
-       ---help---
-               This is the full path to the program in a mounted file system 
that
-               implements the system() command.  That is, a program that 
starts the
-               NSH shell, executes one command (in argv[1]), then exits.
-
-config SYSTEM_POPEN_STACKSIZE
-       int "Shell stack size"
-       default DEFAULT_TASK_STACKSIZE
-       ---help---
-               The size of stack allocated for the shell.
-
-               NOTE: I needed to set the stack size quite large to get this 
example
-               working on the simulated target (perhaps because of the 64-bit
-               stack?  Or perhaps that is a sneak call into the host libc that 
I
-               have not caught).  I assume that a smaller stack would be okay 
on
-               real hardware, but I have not yet verified that.
-
-config SYSTEM_POPEN_PRIORITY
-       int "Shell priority"
-       default 100
-       ---help---
-               The priority of the shell.
-
-config SYSTEM_POPEN_MAXARGUMENTS
-       int "Maximum number of command arguments (no-shell mode)"
-       default 7
-       depends on !NSH_LIBRARY
-       ---help---
-               When NSH is not available, dpopen()/popen() splits the command
-               string by whitespace into an argv array.  This sets the maximum
-               number of arguments (excluding the program name and the
-               terminating NULL).
-
-               This is analogous to CONFIG_NSH_MAXARGUMENTS but applies
-               only to the no-shell path.
-
-endif
diff --git a/system/popen/Make.defs b/system/popen/Make.defs
deleted file mode 100644
index 9ecee32e9..000000000
--- a/system/popen/Make.defs
+++ /dev/null
@@ -1,25 +0,0 @@
-############################################################################
-# apps/system/popen/Make.defs
-#
-# SPDX-License-Identifier: Apache-2.0
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-#
-############################################################################
-
-ifneq ($(CONFIG_SYSTEM_POPEN),)
-CONFIGURED_APPS += $(APPDIR)/system/popen
-endif
diff --git a/system/popen/Makefile b/system/popen/Makefile
deleted file mode 100644
index 7e8887de6..000000000
--- a/system/popen/Makefile
+++ /dev/null
@@ -1,29 +0,0 @@
-############################################################################
-# apps/system/popen/Makefile
-#
-# SPDX-License-Identifier: Apache-2.0
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-#
-############################################################################
-
-include $(APPDIR)/Make.defs
-
-# dpopen()/dpclose() core and popen()/pclose() FILE wrappers
-
-CSRCS = dpopen.c popen.c
-
-include $(APPDIR)/Application.mk
diff --git a/system/popen/dpopen.c b/system/popen/dpopen.c
deleted file mode 100644
index 8e57371b7..000000000
--- a/system/popen/dpopen.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/****************************************************************************
- * apps/system/popen/dpopen.c
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.  The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/wait.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-#include <string.h>
-#include <sched.h>
-#include <spawn.h>
-#include <debug.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#if defined(CONFIG_NET_LOCAL) && defined(CONFIG_NET_LOCAL_STREAM)
-#  include <sys/socket.h>
-#endif
-
-#ifdef CONFIG_NSH_LIBRARY
-#  include "nshlib/nshlib.h"
-#endif
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-#ifndef CONFIG_NSH_LIBRARY
-#  define DPOPEN_MAX_ARGV (CONFIG_SYSTEM_POPEN_MAXARGUMENTS + 1)
-#endif
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: dpopen
- *
- * Description:
- *   Execute a command and return a raw file descriptor connected to the
- *   child process via a pipe, along with the child PID.
- *
- *   This is the descriptor-based counterpart of popen(), analogous to how
- *   dprintf() relates to fprintf().  It avoids the FILE stream layer,
- *   making it suitable for callers that only need a raw fd and want to
- *   avoid the stdio.h dependency.
- *
- *   When NSH is available, commands are executed through the shell
- *   (sh -c command), supporting full shell syntax.
- *
- *   When NSH is not available, the command is split by whitespace and
- *   executed directly via posix_spawnp().  Shell syntax (pipes, redirects,
- *   globbing) is not supported in this mode.
- *
- * Input Parameters:
- *   command - The command string to execute
- *   oflag   - O_RDONLY to read child stdout, O_WRONLY to write child stdin,
- *             O_RDWR for bidirectional socket mode
- *   pid     - Location to return the child process ID
- *
- * Returned Value:
- *   A valid file descriptor on success, or -1 on failure with errno set.
- *
- ****************************************************************************/
-
-int dpopen(FAR const char *command, int oflag, FAR pid_t *pid)
-{
-  struct sched_param param;
-  posix_spawnattr_t attr;
-  posix_spawn_file_actions_t file_actions;
-#ifdef CONFIG_NSH_LIBRARY
-  FAR char *argv[4];
-#else
-  char cmdbuf[PATH_MAX];
-  FAR char *argv[DPOPEN_MAX_ARGV];
-  FAR char *saveptr;
-  int argc = 0;
-#endif
-  int fd[2];
-  int childfd;
-  int parentfd;
-  int errcode;
-
-  if (command == NULL || pid == NULL)
-    {
-      errno = EINVAL;
-      return -1;
-    }
-
-  /* Create a pipe or socketpair.  fd[0] refers to the read end of the
-   * pipe; fd[1] refers to the write end of the pipe.
-   */
-
-  if ((oflag & O_ACCMODE) == O_RDWR)
-    {
-#if defined(CONFIG_NET_LOCAL) && defined(CONFIG_NET_LOCAL_STREAM)
-      /* Create a socketpair for bidirectional communication */
-
-      if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fd) < 0)
-        {
-          return -1;
-        }
-
-      childfd  = fd[0];
-      parentfd = fd[1];
-#else
-      errno = ENOTSUP;
-      return -1;
-#endif
-    }
-  else if (pipe2(fd, O_CLOEXEC) < 0)
-    {
-      return -1;
-    }
-  else if ((oflag & O_ACCMODE) == O_RDONLY)
-    {
-      /* Pipe is the output from the child */
-
-      childfd  = fd[1];  /* Child writes to pipe */
-      parentfd = fd[0];  /* Parent reads from pipe */
-    }
-  else if ((oflag & O_ACCMODE) == O_WRONLY)
-    {
-      /* Pipe is the input to the child */
-
-      childfd  = fd[0];  /* Child reads from pipe */
-      parentfd = fd[1];  /* Parent writes to pipe */
-    }
-  else
-    {
-      errcode = EINVAL;
-      goto errout_with_pipe;
-    }
-
-  /* Initialize attributes for task_spawn() (or posix_spawn()). */
-
-  errcode = posix_spawnattr_init(&attr);
-  if (errcode != 0)
-    {
-      goto errout_with_pipe;
-    }
-
-  errcode = posix_spawn_file_actions_init(&file_actions);
-  if (errcode != 0)
-    {
-      goto errout_with_attr;
-    }
-
-  /* Set the correct stack size and priority */
-
-  param.sched_priority = CONFIG_SYSTEM_POPEN_PRIORITY;
-  errcode = posix_spawnattr_setschedparam(&attr, &param);
-  if (errcode != 0)
-    {
-      goto errout_with_actions;
-    }
-
-#ifndef CONFIG_SYSTEM_POPEN_SHPATH
-  errcode = posix_spawnattr_setstacksize(&attr,
-                                         CONFIG_SYSTEM_POPEN_STACKSIZE);
-  if (errcode != 0)
-    {
-      goto errout_with_actions;
-    }
-#endif
-
-  /* If robin robin scheduling is enabled, then set the scheduling policy
-   * of the new task to SCHED_RR before it has a chance to run.
-   */
-
-#if CONFIG_RR_INTERVAL > 0
-  errcode = posix_spawnattr_setschedpolicy(&attr, SCHED_RR);
-  if (errcode != 0)
-    {
-      goto errout_with_actions;
-    }
-
-  errcode = posix_spawnattr_setflags(&attr,
-                                     POSIX_SPAWN_SETSCHEDPARAM |
-                                     POSIX_SPAWN_SETSCHEDULER);
-  if (errcode != 0)
-    {
-      goto errout_with_actions;
-    }
-
-#else
-  errcode = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSCHEDPARAM);
-  if (errcode != 0)
-    {
-      goto errout_with_actions;
-    }
-
-#endif
-
-  /* Redirect child's stdin or stdout to the pipe */
-
-  if ((oflag & O_ACCMODE) == O_RDWR)
-    {
-      errcode = posix_spawn_file_actions_adddup2(&file_actions, childfd,
-                                                 STDIN_FILENO);
-      if (errcode != 0)
-        {
-          goto errout_with_actions;
-        }
-
-      errcode = posix_spawn_file_actions_adddup2(&file_actions, childfd,
-                                                 STDOUT_FILENO);
-      if (errcode != 0)
-        {
-          goto errout_with_actions;
-        }
-    }
-  else
-    {
-      errcode = posix_spawn_file_actions_adddup2(&file_actions, childfd,
-                   (oflag & O_ACCMODE) == O_RDONLY ?
-                   STDOUT_FILENO : STDIN_FILENO);
-      if (errcode != 0)
-        {
-          goto errout_with_actions;
-        }
-    }
-
-  /* Call task_spawn() (or posix_spawn), re-directing stdin or stdout
-   * appropriately.
-   */
-
-#ifdef CONFIG_NSH_LIBRARY
-  /* Shell mode: execute command through sh -c */
-
-  argv[1] = "-c";
-  argv[2] = (FAR char *)command;
-  argv[3] = NULL;
-
-#  ifdef CONFIG_SYSTEM_POPEN_SHPATH
-  argv[0] = CONFIG_SYSTEM_POPEN_SHPATH;
-  errcode = posix_spawn(pid, argv[0], &file_actions,
-                        &attr, argv, NULL);
-#  else
-  *pid = task_spawn("dpopen", nsh_system, &file_actions,
-                    &attr, argv + 1, NULL);
-  if (*pid < 0)
-    {
-      errcode = -*pid;
-    }
-#  endif
-#else
-  /* No-shell mode: split command and execute directly via posix_spawnp.
-   * The command must be in "program arg1 arg2" form -- no shell syntax.
-   */
-
-  if (strlcpy(cmdbuf, command, sizeof(cmdbuf)) >= sizeof(cmdbuf))
-    {
-      errcode = ENAMETOOLONG;
-      goto errout_with_actions;
-    }
-
-  do
-    {
-      argv[argc] = strtok_r(argc ? NULL : cmdbuf, " \t", &saveptr);
-    }
-  while (argv[argc] != NULL && ++argc < DPOPEN_MAX_ARGV - 1);
-
-  argv[argc] = NULL;
-
-  if (argc == 0)
-    {
-      errcode = EINVAL;
-      goto errout_with_actions;
-    }
-
-  errcode = posix_spawnp(pid, argv[0], &file_actions,
-                         &attr, argv, NULL);
-#endif
-
-  if (errcode != 0)
-    {
-      serr("ERROR: dpopen spawn failed: %d\n", errcode);
-      goto errout_with_pipe;
-    }
-
-  /* Free attributes and file actions */
-
-  posix_spawn_file_actions_destroy(&file_actions);
-  posix_spawnattr_destroy(&attr);
-
-  /* Close the child's end in the parent */
-
-  if (!(oflag & O_CLOEXEC))
-    {
-      ioctl(parentfd, FIONCLEX, 0);
-    }
-
-  close(childfd);
-
-  return parentfd;
-
-errout_with_actions:
-  posix_spawn_file_actions_destroy(&file_actions);
-
-errout_with_attr:
-  posix_spawnattr_destroy(&attr);
-
-errout_with_pipe:
-  close(fd[0]);
-  close(fd[1]);
-  errno = errcode;
-  return -1;
-}
-
-/****************************************************************************
- * Name: dpclose
- *
- * Description:
- *   Close a file descriptor opened by dpopen() and wait for the child
- *   process to terminate.
- *
- *   This is the descriptor-based counterpart of pclose().
- *
- * Input Parameters:
- *   fd  - The file descriptor returned by dpopen()
- *   pid - The child process ID returned by dpopen()
- *
- * Returned Value:
- *   The child termination status on success, or -1 on failure with
- *   errno set.
- *
- ****************************************************************************/
-
-int dpclose(int fd, pid_t pid)
-{
-#ifdef CONFIG_SCHED_WAITPID
-  int status;
-  int ret;
-#endif
-
-  if (fd >= 0)
-    {
-      close(fd);
-    }
-
-#ifdef CONFIG_SCHED_WAITPID
-  ret = waitpid(pid, &status, 0);
-  if (ret < 0)
-    {
-      return ERROR;
-    }
-
-  return status;
-#else
-  return 0;
-#endif
-}
diff --git a/system/popen/popen.c b/system/popen/popen.c
deleted file mode 100644
index 012ca808d..000000000
--- a/system/popen/popen.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/****************************************************************************
- * apps/system/popen/popen.c
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.  The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-struct popen_file_s
-{
-  int fd;
-  pid_t shell;
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: popen_file_read
- ****************************************************************************/
-
-static ssize_t popen_file_read(FAR void *cookie, FAR char *buf,
-                               size_t size)
-{
-  FAR struct popen_file_s *filep = (FAR struct popen_file_s *)cookie;
-
-  return read(filep->fd, buf, size);
-}
-
-/****************************************************************************
- * Name: popen_file_write
- ****************************************************************************/
-
-static ssize_t popen_file_write(FAR void *cookie, FAR const char *buf,
-                                size_t size)
-{
-  FAR struct popen_file_s *filep = (FAR struct popen_file_s *)cookie;
-
-  return write(filep->fd, buf, size);
-}
-
-/****************************************************************************
- * Name: popen_file_seek
- ****************************************************************************/
-
-static off_t popen_file_seek(FAR void *cookie, FAR off_t *offset,
-                             int whence)
-{
-  set_errno(ESPIPE);
-  return ERROR;
-}
-
-/****************************************************************************
- * Name: popen_file_close
- ****************************************************************************/
-
-static int popen_file_close(FAR void *cookie)
-{
-  FAR struct popen_file_s *filep = (FAR struct popen_file_s *)cookie;
-  int ret;
-
-  ret = close(filep->fd);
-  free(filep);
-  return ret;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: popen
- *
- * Description:
- *   The popen() function will execute the command specified by the string
- *   command. It will create a pipe between the calling program and the
- *   executed command, and will return a pointer to a stream that can be
- *   used to either read from or write to the pipe.
- *
- *   This is a thin wrapper around dpopen() that wraps the returned file
- *   descriptor in a FILE stream, analogous to how fprintf() relates to
- *   dprintf().
- *
- *   The mode argument to popen() is a string that specifies I/O mode:
- *
- *     - If mode is r, when the child process is started, its file descriptor
- *       STDOUT_FILENO will be the writable end of the pipe, and the file
- *       descriptor fileno(stream) in the calling process, where stream is
- *       the stream pointer returned by popen(), will be the readable end of
- *       the pipe.
- *
- *     - If mode is w, when the child process is started its file descriptor
- *       STDIN_FILENO will be the readable end of the pipe, and the file
- *       descriptor fileno(stream) in the calling process, where stream is
- *       the stream pointer returned by popen(), will be the writable end of
- *       the pipe.
- *
- * Input Parameters:
- *   command - The command string to execute
- *   mode    - "r" or "w"
- *
- * Returned Value:
- *   A non-NULL FILE stream connected to the child process is returned on
- *   success.  NULL is returned on any failure with the errno variable set
- *   appropriately.
- *
- ****************************************************************************/
-
-FILE *popen(FAR const char *command, FAR const char *mode)
-{
-  FAR struct popen_file_s *container;
-  FAR FILE *stream;
-  cookie_io_functions_t popen_io =
-    {
-      .read  = popen_file_read,
-      .write = popen_file_write,
-      .seek  = popen_file_seek,
-      .close = popen_file_close
-    };
-
-  int oflag;
-  int fd;
-
-  /* Allocate a container for returned FILE stream */
-
-  container = (FAR struct popen_file_s *)malloc(sizeof(struct popen_file_s));
-  if (container == NULL)
-    {
-      errno = ENOMEM;
-      return NULL;
-    }
-
-  /* Map mode string to open flags */
-
-  if (strstr(mode, "r+") || strstr(mode, "w+"))
-    {
-      oflag = O_RDWR;
-    }
-  else if (strstr(mode, "r"))
-    {
-      oflag = O_RDONLY;
-    }
-  else if (strstr(mode, "w"))
-    {
-      oflag = O_WRONLY;
-    }
-  else
-    {
-      free(container);
-      errno = EINVAL;
-      return NULL;
-    }
-
-  if (strchr(mode, 'e') != NULL)
-    {
-      oflag |= O_CLOEXEC;
-    }
-
-  /* Use dpopen() to do the real work */
-
-  fd = dpopen(command, oflag, &container->shell);
-  if (fd < 0)
-    {
-      free(container);
-      return NULL;
-    }
-
-  /* Wrap the raw fd in a FILE stream */
-
-  container->fd = fd;
-  stream = fopencookie(container, mode, popen_io);
-  if (stream == NULL)
-    {
-      int errcode = errno;
-
-      dpclose(fd, container->shell);
-      free(container);
-      errno = errcode;
-      return NULL;
-    }
-
-  return stream;
-}
-
-/****************************************************************************
- * Name: pclose
- *
- * Description:
- *   The pclose() function will close a stream that was opened by popen(),
- *   wait for the command to terminate, and return the termination status of
- *   the process that was running the command language interpreter. However,
- *   if a call caused the termination status to be unavailable to pclose(),
- *   then pclose() will return -1 with errno set to ECHILD to report this
- *   situation. This can happen if the application calls one of the following
- *   functions:
- *
- *     wait()
- *     waitpid() with a pid argument less than or equal to 0 or equal to the
- *               process ID of the command line interpreter
- *
- *   Any other function not defined in this volume of IEEE Std 1003.1-2001
- *   that could do one of the above
- *
- *   In any case, pclose() will not return before the child process created
- *   by popen() has terminated.
- *
- *   If the command language interpreter cannot be executed, the child
- *   termination status returned by pclose() will be as if the command
- *   language interpreter terminated using exit(127) or _exit(127).
- *
- *   The pclose() function will not affect the termination status of any
- *   child of the calling process other than the one created by popen() for
- *   the associated stream.
- *
- *   If the argument stream to pclose() is not a pointer to a stream created
- *   by popen(), the result of pclose() is undefined.
- *
- * Input Parameters:
- *   stream - The stream reference returned by a previous call to popen()
- *
- * Returned Value:
- *   The termination status of the command is returned on success;
- *   otherwise -1 (ERROR) is returned and errno is set appropriately.
- *
- ****************************************************************************/
-
-int pclose(FILE *stream)
-{
-  FAR struct popen_file_s *filep;
-  pid_t shell;
-
-  if (stream == NULL || stream->fs_iofunc.close != popen_file_close)
-    {
-      set_errno(EINVAL);
-      return ERROR;
-    }
-
-  /* fclose() frees the cookie, so keep the process ID */
-
-  filep = stream->fs_cookie;
-  shell = filep->shell;
-  fclose(stream);
-
-  return dpclose(-1, shell);
-}
diff --git a/testing/libc/popen/Kconfig b/testing/libc/popen/Kconfig
index acb2dacc5..945a3a355 100644
--- a/testing/libc/popen/Kconfig
+++ b/testing/libc/popen/Kconfig
@@ -6,7 +6,7 @@
 config TESTING_POPEN
        tristate "popen()/dpopen() test"
        default n
-       depends on SYSTEM_POPEN || (PIPES && LIBC_EXECFUNCS && SCHED_WAITPID)
+       depends on PIPES && LIBC_EXECFUNCS && SCHED_WAITPID
        ---help---
                Test popen()/pclose() and dpopen()/dpclose() in both shell
                and no-shell modes. The test binary doubles as its own

Reply via email to