[libc-commits] [libc] 28943d6 - [libc] Add POSIX functions posix_spawn_file_actions_*.

Siva Chandra Reddy via libc-commits libc-commits at lists.llvm.org
Mon Oct 10 21:55:10 PDT 2022


Author: Siva Chandra Reddy
Date: 2022-10-11T04:54:44Z
New Revision: 28943d617a478cbaf032f9c7ff3c9830e62bd0af

URL: https://github.com/llvm/llvm-project/commit/28943d617a478cbaf032f9c7ff3c9830e62bd0af
DIFF: https://github.com/llvm/llvm-project/commit/28943d617a478cbaf032f9c7ff3c9830e62bd0af.diff

LOG: [libc] Add POSIX functions posix_spawn_file_actions_*.

Namely, posix_spawn_file_actions_addclose,
posix_spawn_file_actions_adddup2, posix_spawn_file_actions_addopen,
posix_spawn_file_actions_destroy, posix_spawn_file_actions_init have
been added.

Reviewed By: michaelrj, lntue

Differential Revision: https://reviews.llvm.org/D135603

Added: 
    libc/include/llvm-libc-types/posix_spawn_file_actions_t.h
    libc/include/spawn.h.def
    libc/src/spawn/CMakeLists.txt
    libc/src/spawn/file_actions.h
    libc/src/spawn/posix_spawn_file_actions_addclose.cpp
    libc/src/spawn/posix_spawn_file_actions_addclose.h
    libc/src/spawn/posix_spawn_file_actions_adddup2.cpp
    libc/src/spawn/posix_spawn_file_actions_adddup2.h
    libc/src/spawn/posix_spawn_file_actions_addopen.cpp
    libc/src/spawn/posix_spawn_file_actions_addopen.h
    libc/src/spawn/posix_spawn_file_actions_destroy.cpp
    libc/src/spawn/posix_spawn_file_actions_destroy.h
    libc/src/spawn/posix_spawn_file_actions_init.cpp
    libc/src/spawn/posix_spawn_file_actions_init.h
    libc/test/src/spawn/CMakeLists.txt
    libc/test/src/spawn/posix_spawn_file_actions_test.cpp

Modified: 
    libc/config/linux/api.td
    libc/config/linux/x86_64/entrypoints.txt
    libc/include/CMakeLists.txt
    libc/include/llvm-libc-types/CMakeLists.txt
    libc/spec/posix.td
    libc/src/CMakeLists.txt
    libc/test/src/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/config/linux/api.td b/libc/config/linux/api.td
index ca79eb76b69ae..fff1ff0c6211d 100644
--- a/libc/config/linux/api.td
+++ b/libc/config/linux/api.td
@@ -289,3 +289,7 @@ def SysSendfileAPI : PublicAPI<"sys/sendfile.h"> {
 def SysUtsNameAPI : PublicAPI<"sys/utsname.h"> {
   let Types = ["struct utsname"];
 }
+
+def SpawnAPI : PublicAPI<"spawn.h"> {
+  let Types = ["mode_t", "posix_spawn_file_actions_t"];
+}

diff  --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 2a2a03106ed74..2855096ebe674 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -390,6 +390,13 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.signal.sigfillset
     libc.src.signal.signal
 
+    # spawn.h entrypoints
+    libc.src.spawn.posix_spawn_file_actions_addclose
+    libc.src.spawn.posix_spawn_file_actions_adddup2
+    libc.src.spawn.posix_spawn_file_actions_addopen
+    libc.src.spawn.posix_spawn_file_actions_destroy
+    libc.src.spawn.posix_spawn_file_actions_init
+
     # threads.h entrypoints
     libc.src.threads.call_once
     libc.src.threads.cnd_broadcast

diff  --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index a4a6a1477fdf7..4d77ddf27d59e 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -213,6 +213,16 @@ add_gen_header(
     .llvm-libc-macros.sched_macros
 )
 
+add_gen_header(
+  spawn
+  DEF_FILE spawn.h.def
+  GEN_HDR spawn.h
+  DEPENDS
+    .llvm_libc_common_h
+    .llvm-libc-types.mode_t
+    .llvm-libc-types.posix_spawn_file_actions_t
+)
+
 # TODO: Not all platforms will have a include/sys directory. Add the sys
 # directory and the targets for sys/*.h files conditional to the OS requiring
 # them.

diff  --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index 900eec8b9e65d..46b7393fea642 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -39,6 +39,7 @@ add_header(nlink_t HDR nlink_t.h)
 add_header(off_t HDR off_t.h)
 add_header(once_flag HDR once_flag.h DEPENDS .__futex_word)
 add_header(pid_t HDR pid_t.h)
+add_header(posix_spawn_file_actions_t HDR posix_spawn_file_actions_t.h)
 add_header(pthread_attr_t HDR pthread_attr_t.h DEPENDS .size_t)
 add_header(pthread_key_t HDR pthread_key_t.h)
 add_header(pthread_mutex_t HDR pthread_mutex_t.h DEPENDS .__futex_word .__mutex_type)

diff  --git a/libc/include/llvm-libc-types/posix_spawn_file_actions_t.h b/libc/include/llvm-libc-types/posix_spawn_file_actions_t.h
new file mode 100644
index 0000000000000..55adbd198de85
--- /dev/null
+++ b/libc/include/llvm-libc-types/posix_spawn_file_actions_t.h
@@ -0,0 +1,17 @@
+//===-- Definition of type posix_spawn_file_actions_t ---------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __LLVM_LIBC_TYPES_POSIX_SPAWN_FILE_ACTIONS_T_T_H
+#define __LLVM_LIBC_TYPES_POSIX_SPAWN_FILE_ACTIONS_T_T_H
+
+typedef struct {
+  void *__front;
+  void *__back;
+} posix_spawn_file_actions_t;
+
+#endif // __LLVM_LIBC_TYPES_POSIX_SPAWN_FILE_ACTIONS_T_T_H

diff  --git a/libc/include/spawn.h.def b/libc/include/spawn.h.def
new file mode 100644
index 0000000000000..95c24bba0df36
--- /dev/null
+++ b/libc/include/spawn.h.def
@@ -0,0 +1,16 @@
+//===-- POSIX header spawn.h ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SPAWN_H
+#define LLVM_LIBC_SPAWN_H
+
+#include <__llvm-libc-common.h>
+
+%%public_api()
+
+#endif // LLVM_LIBC_SPAWN_H 

diff  --git a/libc/spec/posix.td b/libc/spec/posix.td
index bab275089f99d..431a57108ac89 100644
--- a/libc/spec/posix.td
+++ b/libc/spec/posix.td
@@ -50,6 +50,10 @@ def ExecEnvpT : NamedType<"__exec_envp_t">;
 
 def AtForkCallbackT : NamedType<"__atfork_callback_t">;
 
+def PosixSpawnFileActionsT : NamedType<"posix_spawn_file_actions_t">;
+def PosixSpawnFileActionsTPtr : PtrType<PosixSpawnFileActionsT>;
+def PosixSpawnFileActionsTRestrictedPtr : RestrictedPtrType<PosixSpawnFileActionsT>;
+
 def POSIX : StandardSpec<"POSIX"> {
   PtrType CharPtr = PtrType<CharType>;
   RestrictedPtrType RestrictedCharPtr = RestrictedPtrType<CharType>;
@@ -1045,6 +1049,41 @@ def POSIX : StandardSpec<"POSIX"> {
     []  // Functions
   >;
 
+  HeaderSpec Spawn = HeaderSpec<
+    "spawn.h",
+    [], // Macros
+    [PosixSpawnFileActionsT, ModeTType],
+    [], // Enumerations
+    [
+      FunctionSpec<
+        "posix_spawn_file_actions_addclose",
+        RetValSpec<IntType>,
+        [ArgSpec<PosixSpawnFileActionsTPtr>, ArgSpec<IntType>]
+      >,
+      FunctionSpec<
+        "posix_spawn_file_actions_adddup2",
+        RetValSpec<IntType>,
+        [ArgSpec<PosixSpawnFileActionsTPtr>, ArgSpec<IntType>, ArgSpec<IntType>]
+      >,
+      FunctionSpec<
+        "posix_spawn_file_actions_addopen",
+        RetValSpec<IntType>,
+        [ArgSpec<PosixSpawnFileActionsTRestrictedPtr>, ArgSpec<IntType>,
+         ArgSpec<ConstCharRestrictedPtr>, ArgSpec<IntType>, ArgSpec<ModeTType>]
+      >,
+      FunctionSpec<
+        "posix_spawn_file_actions_destroy",
+        RetValSpec<IntType>,
+        [ArgSpec<PosixSpawnFileActionsTPtr>]
+      >,
+      FunctionSpec<
+        "posix_spawn_file_actions_init",
+        RetValSpec<IntType>,
+        [ArgSpec<PosixSpawnFileActionsTPtr>]
+      >,
+    ]
+  >;
+
   let Headers = [
     CType,
     Dirent,
@@ -1052,6 +1091,7 @@ def POSIX : StandardSpec<"POSIX"> {
     FCntl,
     PThread,
     Signal,
+    Spawn,
     StdIO,
     StdLib,
     SysIOctl,

diff  --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt
index 8c689d2e3935f..3d594af393794 100644
--- a/libc/src/CMakeLists.txt
+++ b/libc/src/CMakeLists.txt
@@ -26,5 +26,6 @@ endif()
 # since assert uses the signal API, we disable assert also.
 # add_subdirectory(assert)
 add_subdirectory(signal)
+add_subdirectory(spawn)
 add_subdirectory(threads)
 add_subdirectory(time)

diff  --git a/libc/src/spawn/CMakeLists.txt b/libc/src/spawn/CMakeLists.txt
new file mode 100644
index 0000000000000..95a0c7436d263
--- /dev/null
+++ b/libc/src/spawn/CMakeLists.txt
@@ -0,0 +1,65 @@
+add_header_library(
+  file_actions
+  HDRS
+    file_actions.h
+  DEPENDS
+    libc.include.spawn
+)
+
+add_entrypoint_object(
+  posix_spawn_file_actions_init
+  SRCS
+    posix_spawn_file_actions_init.cpp
+  HDRS
+    posix_spawn_file_actions_init.h
+  DEPENDS
+    libc.include.spawn
+)
+
+add_entrypoint_object(
+  posix_spawn_file_actions_destroy
+  SRCS
+    posix_spawn_file_actions_destroy.cpp
+  HDRS
+    posix_spawn_file_actions_destroy.h
+  DEPENDS
+    .file_actions
+    libc.include.errno
+    libc.include.spawn
+)
+
+add_entrypoint_object(
+  posix_spawn_file_actions_adddup2
+  SRCS
+    posix_spawn_file_actions_adddup2.cpp
+  HDRS
+    posix_spawn_file_actions_adddup2.h
+  DEPENDS
+    .file_actions
+    libc.include.errno
+    libc.include.spawn
+)
+
+add_entrypoint_object(
+  posix_spawn_file_actions_addopen
+  SRCS
+    posix_spawn_file_actions_addopen.cpp
+  HDRS
+    posix_spawn_file_actions_addopen.h
+  DEPENDS
+    .file_actions
+    libc.include.errno
+    libc.include.spawn
+)
+
+add_entrypoint_object(
+  posix_spawn_file_actions_addclose
+  SRCS
+    posix_spawn_file_actions_addclose.cpp
+  HDRS
+    posix_spawn_file_actions_addclose.h
+  DEPENDS
+    .file_actions
+    libc.include.errno
+    libc.include.spawn
+)

diff  --git a/libc/src/spawn/file_actions.h b/libc/src/spawn/file_actions.h
new file mode 100644
index 0000000000000..11d9fb70d193d
--- /dev/null
+++ b/libc/src/spawn/file_actions.h
@@ -0,0 +1,58 @@
+//===-- Spawn file actions  -------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SPAWN_FILE_ACTIONS_H
+#define LLVM_LIBC_SRC_SPAWN_FILE_ACTIONS_H
+
+#include <spawn.h> // For mode_t
+#include <stdint.h>
+
+namespace __llvm_libc {
+
+struct BaseSpawnFileAction {
+  enum ActionType {
+    OPEN = 111,
+    CLOSE = 222,
+    DUP2 = 333,
+  };
+
+  ActionType type;
+  BaseSpawnFileAction *next;
+};
+
+struct SpawnFileOpenAction : public BaseSpawnFileAction {
+  const char *path;
+  int fd;
+  int oflag;
+  mode_t mode;
+};
+
+struct SpawnFileCloseAction : public BaseSpawnFileAction {
+  int fd;
+};
+
+struct SpawnFileDup2Action : public BaseSpawnFileAction {
+  int fd;
+  int newfd;
+};
+
+inline void enque_spawn_action(posix_spawn_file_actions_t *actions,
+                               BaseSpawnFileAction *act) {
+  if (actions->__back != nullptr) {
+    auto *back = reinterpret_cast<BaseSpawnFileAction *>(actions->__back);
+    back->next = act;
+    actions->__back = act;
+  } else {
+    // First action is being added.
+    actions->__front = actions->__back = act;
+  }
+}
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_SPAWN_FILE_ACTIONS_H

diff  --git a/libc/src/spawn/posix_spawn_file_actions_addclose.cpp b/libc/src/spawn/posix_spawn_file_actions_addclose.cpp
new file mode 100644
index 0000000000000..81d3878fe81d1
--- /dev/null
+++ b/libc/src/spawn/posix_spawn_file_actions_addclose.cpp
@@ -0,0 +1,38 @@
+//===-- Implementation of posix_spawn_file_actions_addclose ---------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "posix_spawn_file_actions_addclose.h"
+
+#include "file_actions.h"
+#include "src/__support/common.h"
+
+#include <errno.h>
+#include <spawn.h>
+#include <stdlib.h> // For malloc
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, posix_spawn_file_actions_addclose,
+                   (posix_spawn_file_actions_t *__restrict actions, int fd)) {
+  if (actions == nullptr)
+    return EINVAL;
+  if (fd < 0)
+    return EBADF;
+
+  auto *act = reinterpret_cast<SpawnFileCloseAction *>(
+      malloc(sizeof(SpawnFileCloseAction)));
+  if (act == nullptr)
+    return ENOMEM;
+
+  act->type = BaseSpawnFileAction::CLOSE;
+  act->fd = fd;
+  enque_spawn_action(actions, act);
+  return 0;
+}
+
+} // namespace __llvm_libc

diff  --git a/libc/src/spawn/posix_spawn_file_actions_addclose.h b/libc/src/spawn/posix_spawn_file_actions_addclose.h
new file mode 100644
index 0000000000000..5eda292760daf
--- /dev/null
+++ b/libc/src/spawn/posix_spawn_file_actions_addclose.h
@@ -0,0 +1,21 @@
+//===-- Impl header for posix_spawn_file_actions_addclose -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SPAWN_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE_H
+#define LLVM_LIBC_SRC_SPAWN_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE_H
+
+#include <spawn.h>
+
+namespace __llvm_libc {
+
+int posix_spawn_file_actions_addclose(
+    posix_spawn_file_actions_t *__restrict actions, int fd);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_SPAWN_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE_H

diff  --git a/libc/src/spawn/posix_spawn_file_actions_adddup2.cpp b/libc/src/spawn/posix_spawn_file_actions_adddup2.cpp
new file mode 100644
index 0000000000000..a6a7f07110e92
--- /dev/null
+++ b/libc/src/spawn/posix_spawn_file_actions_adddup2.cpp
@@ -0,0 +1,40 @@
+//===-- Implementation of posix_spawn_file_actions_adddup2 ----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "posix_spawn_file_actions_adddup2.h"
+
+#include "file_actions.h"
+#include "src/__support/common.h"
+
+#include <errno.h>
+#include <spawn.h>
+#include <stdlib.h> // For malloc
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, posix_spawn_file_actions_adddup2,
+                   (posix_spawn_file_actions_t * actions, int fd, int newfd)) {
+  if (actions == nullptr)
+    return EINVAL;
+  if (fd < 0 || newfd < 0)
+    return EBADF;
+
+  auto *act = reinterpret_cast<SpawnFileDup2Action *>(
+      malloc(sizeof(SpawnFileDup2Action)));
+  if (act == nullptr)
+    return ENOMEM;
+
+  act->type = BaseSpawnFileAction::DUP2;
+  act->fd = fd;
+  act->newfd = newfd;
+  act->next = nullptr;
+  enque_spawn_action(actions, act);
+  return 0;
+}
+
+} // namespace __llvm_libc

diff  --git a/libc/src/spawn/posix_spawn_file_actions_adddup2.h b/libc/src/spawn/posix_spawn_file_actions_adddup2.h
new file mode 100644
index 0000000000000..33444184f9736
--- /dev/null
+++ b/libc/src/spawn/posix_spawn_file_actions_adddup2.h
@@ -0,0 +1,21 @@
+//===-- Impl header for posix_spawn_file_actions_adddup2 --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SPAWN_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2_H
+#define LLVM_LIBC_SRC_SPAWN_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2_H
+
+#include <spawn.h>
+
+namespace __llvm_libc {
+
+int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *actions,
+                                     int fd, int newfd);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_SPAWN_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2_H

diff  --git a/libc/src/spawn/posix_spawn_file_actions_addopen.cpp b/libc/src/spawn/posix_spawn_file_actions_addopen.cpp
new file mode 100644
index 0000000000000..ac286631c0565
--- /dev/null
+++ b/libc/src/spawn/posix_spawn_file_actions_addopen.cpp
@@ -0,0 +1,43 @@
+//===-- Implementation of posix_spawn_file_actions_addopen ----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "posix_spawn_file_actions_addopen.h"
+
+#include "file_actions.h"
+#include "src/__support/common.h"
+
+#include <errno.h>
+#include <spawn.h>
+#include <stdlib.h> // For malloc
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, posix_spawn_file_actions_addopen,
+                   (posix_spawn_file_actions_t *__restrict actions, int fd,
+                    const char *__restrict path, int oflag, mode_t mode)) {
+  if (actions == nullptr)
+    return EINVAL;
+  if (fd < 0)
+    return EBADF;
+
+  auto *act = reinterpret_cast<SpawnFileOpenAction *>(
+      malloc(sizeof(SpawnFileOpenAction)));
+  if (act == nullptr)
+    return ENOMEM;
+
+  act->type = BaseSpawnFileAction::OPEN;
+  act->fd = fd;
+  act->path = path;
+  act->oflag = oflag;
+  act->mode = mode;
+  act->next = nullptr;
+  enque_spawn_action(actions, act);
+  return 0;
+}
+
+} // namespace __llvm_libc

diff  --git a/libc/src/spawn/posix_spawn_file_actions_addopen.h b/libc/src/spawn/posix_spawn_file_actions_addopen.h
new file mode 100644
index 0000000000000..ff757d42e5142
--- /dev/null
+++ b/libc/src/spawn/posix_spawn_file_actions_addopen.h
@@ -0,0 +1,22 @@
+//===-- Impl header for posix_spawn_file_actions_addopen --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SPAWN_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN_H
+#define LLVM_LIBC_SRC_SPAWN_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN_H
+
+#include <spawn.h>
+
+namespace __llvm_libc {
+
+int posix_spawn_file_actions_addopen(
+    posix_spawn_file_actions_t *__restrict actions, int fd,
+    const char *__restrict path, int oflag, mode_t mode);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_SPAWN_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN_H

diff  --git a/libc/src/spawn/posix_spawn_file_actions_destroy.cpp b/libc/src/spawn/posix_spawn_file_actions_destroy.cpp
new file mode 100644
index 0000000000000..83346462c95bd
--- /dev/null
+++ b/libc/src/spawn/posix_spawn_file_actions_destroy.cpp
@@ -0,0 +1,40 @@
+//===-- Implementation of posix_spawn_file_actions_destroy ----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "posix_spawn_file_actions_destroy.h"
+
+#include "file_actions.h"
+#include "src/__support/common.h"
+
+#include <errno.h>
+#include <spawn.h>
+#include <stdlib.h> // For free
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, posix_spawn_file_actions_destroy,
+                   (posix_spawn_file_actions_t * actions)) {
+  if (actions == nullptr)
+    return EINVAL;
+  if (actions->__front == nullptr)
+    return 0;
+
+  auto *act = reinterpret_cast<BaseSpawnFileAction *>(actions->__front);
+  actions->__front = nullptr;
+  actions->__back = nullptr;
+
+  while (act != nullptr) {
+    auto *next = act->next;
+    free(act);
+    act = next;
+  }
+
+  return 0;
+}
+
+} // namespace __llvm_libc

diff  --git a/libc/src/spawn/posix_spawn_file_actions_destroy.h b/libc/src/spawn/posix_spawn_file_actions_destroy.h
new file mode 100644
index 0000000000000..89f3c55dd99b5
--- /dev/null
+++ b/libc/src/spawn/posix_spawn_file_actions_destroy.h
@@ -0,0 +1,20 @@
+//===-- Impl header for posix_spawn_file_actions_destroy --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SPAWN_POSIX_SPAWN_FILE_ACTIONS_DESTROY_H
+#define LLVM_LIBC_SRC_SPAWN_POSIX_SPAWN_FILE_ACTIONS_DESTROY_H
+
+#include <spawn.h>
+
+namespace __llvm_libc {
+
+int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *actions);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_SPAWN_POSIX_SPAWN_FILE_ACTIONS_DESTROY_H

diff  --git a/libc/src/spawn/posix_spawn_file_actions_init.cpp b/libc/src/spawn/posix_spawn_file_actions_init.cpp
new file mode 100644
index 0000000000000..99502ff44962b
--- /dev/null
+++ b/libc/src/spawn/posix_spawn_file_actions_init.cpp
@@ -0,0 +1,24 @@
+//===-- Implementation of posix_spawn_file_actions_init -------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "posix_spawn_file_actions_init.h"
+
+#include "src/__support/common.h"
+
+#include <spawn.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, posix_spawn_file_actions_init,
+                   (posix_spawn_file_actions_t * actions)) {
+  actions->__front = nullptr;
+  actions->__back = nullptr;
+  return 0;
+}
+
+} // namespace __llvm_libc

diff  --git a/libc/src/spawn/posix_spawn_file_actions_init.h b/libc/src/spawn/posix_spawn_file_actions_init.h
new file mode 100644
index 0000000000000..da354e1b0ebae
--- /dev/null
+++ b/libc/src/spawn/posix_spawn_file_actions_init.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for posix_spawn_file_actions_init -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SPAWN_POSIX_SPAWN_FILE_ACTIONS_INIT_H
+#define LLVM_LIBC_SRC_SPAWN_POSIX_SPAWN_FILE_ACTIONS_INIT_H
+
+#include <spawn.h>
+
+namespace __llvm_libc {
+
+int posix_spawn_file_actions_init(posix_spawn_file_actions_t *actions);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_SPAWN_POSIX_SPAWN_FILE_ACTIONS_INIT_H

diff  --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt
index b186e7764b7fa..3667f33d169ab 100644
--- a/libc/test/src/CMakeLists.txt
+++ b/libc/test/src/CMakeLists.txt
@@ -52,6 +52,7 @@ add_subdirectory(dirent)
 # since assert uses the signal API, we disable assert also.
 # add_subdirectory(assert)
 add_subdirectory(signal)
+add_subdirectory(spawn)
 add_subdirectory(time)
 
 if(${LIBC_TARGET_OS} STREQUAL "linux")

diff  --git a/libc/test/src/spawn/CMakeLists.txt b/libc/test/src/spawn/CMakeLists.txt
new file mode 100644
index 0000000000000..c7e7bc29ad02b
--- /dev/null
+++ b/libc/test/src/spawn/CMakeLists.txt
@@ -0,0 +1,18 @@
+add_libc_testsuite(libc_spawn_unittests)
+
+add_libc_unittest(
+  posix_spawn_file_actions_test
+  SUITE
+    libc_spawn_unittests
+  SRCS
+    posix_spawn_file_actions_test.cpp
+  DEPENDS
+    libc.include.errno
+    libc.include.spawn
+    libc.src.spawn.file_actions
+    libc.src.spawn.posix_spawn_file_actions_addclose
+    libc.src.spawn.posix_spawn_file_actions_adddup2
+    libc.src.spawn.posix_spawn_file_actions_addopen
+    libc.src.spawn.posix_spawn_file_actions_destroy
+    libc.src.spawn.posix_spawn_file_actions_init
+)

diff  --git a/libc/test/src/spawn/posix_spawn_file_actions_test.cpp b/libc/test/src/spawn/posix_spawn_file_actions_test.cpp
new file mode 100644
index 0000000000000..f486745158f9a
--- /dev/null
+++ b/libc/test/src/spawn/posix_spawn_file_actions_test.cpp
@@ -0,0 +1,75 @@
+//===-- Unittests for posix_spwan_file_actions_t manipulation -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/spawn/file_actions.h"
+#include "src/spawn/posix_spawn_file_actions_addclose.h"
+#include "src/spawn/posix_spawn_file_actions_adddup2.h"
+#include "src/spawn/posix_spawn_file_actions_addopen.h"
+#include "src/spawn/posix_spawn_file_actions_destroy.h"
+#include "src/spawn/posix_spawn_file_actions_init.h"
+#include "utils/UnitTest/Test.h"
+
+#include <errno.h>
+#include <spawn.h>
+#include <stdint.h>
+
+TEST(LlvmLibcPosixSpawnFileActionsTest, AddActions) {
+  posix_spawn_file_actions_t actions;
+  ASSERT_EQ(__llvm_libc::posix_spawn_file_actions_init(&actions), 0);
+
+  ASSERT_EQ(uintptr_t(actions.__front), uintptr_t(nullptr));
+  ASSERT_EQ(uintptr_t(actions.__back), uintptr_t(nullptr));
+
+  ASSERT_EQ(__llvm_libc::posix_spawn_file_actions_addclose(&actions, 10), 0);
+  ASSERT_NE(uintptr_t(actions.__front), uintptr_t(nullptr));
+  ASSERT_NE(uintptr_t(actions.__back), uintptr_t(nullptr));
+
+  ASSERT_EQ(__llvm_libc::posix_spawn_file_actions_adddup2(&actions, 11, 12), 0);
+  ASSERT_EQ(__llvm_libc::posix_spawn_file_actions_addopen(&actions, 13,
+                                                          "path/to/file", 0, 0),
+            0);
+
+  __llvm_libc::BaseSpawnFileAction *act =
+      reinterpret_cast<__llvm_libc::BaseSpawnFileAction *>(actions.__front);
+  int action_count = 0;
+  while (act != nullptr) {
+    ++action_count;
+    if (action_count == 1)
+      ASSERT_EQ(act->type, __llvm_libc::BaseSpawnFileAction::CLOSE);
+    if (action_count == 2)
+      ASSERT_EQ(act->type, __llvm_libc::BaseSpawnFileAction::DUP2);
+    if (action_count == 3)
+      ASSERT_EQ(act->type, __llvm_libc::BaseSpawnFileAction::OPEN);
+    act = act->next;
+  }
+  ASSERT_EQ(action_count, 3);
+  ASSERT_EQ(__llvm_libc::posix_spawn_file_actions_destroy(&actions), 0);
+}
+
+TEST(LlvmLibcPosixSpawnFileActionsTest, InvalidActions) {
+  ASSERT_EQ(__llvm_libc::posix_spawn_file_actions_addclose(nullptr, 1), EINVAL);
+  ASSERT_EQ(__llvm_libc::posix_spawn_file_actions_adddup2(nullptr, 1, 2),
+            EINVAL);
+  ASSERT_EQ(
+      __llvm_libc::posix_spawn_file_actions_addopen(nullptr, 1, nullptr, 0, 0),
+      EINVAL);
+  ASSERT_EQ(__llvm_libc::posix_spawn_file_actions_destroy(nullptr), EINVAL);
+
+  posix_spawn_file_actions_t actions;
+  ASSERT_EQ(__llvm_libc::posix_spawn_file_actions_init(&actions), 0);
+  ASSERT_EQ(__llvm_libc::posix_spawn_file_actions_addclose(&actions, -1),
+            EBADF);
+  ASSERT_EQ(__llvm_libc::posix_spawn_file_actions_adddup2(&actions, -1, 2),
+            EBADF);
+  ASSERT_EQ(__llvm_libc::posix_spawn_file_actions_adddup2(&actions, 1, -2),
+            EBADF);
+  ASSERT_EQ(__llvm_libc::posix_spawn_file_actions_addopen(&actions, -1, nullptr,
+                                                          0, 0),
+            EBADF);
+  ASSERT_EQ(__llvm_libc::posix_spawn_file_actions_destroy(&actions), 0);
+}


        


More information about the libc-commits mailing list