-
Notifications
You must be signed in to change notification settings - Fork 10.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[libc] Add a simple implementation of the posix_spawn function.
The implementation currently ignores all spawn attributes. Support for them will be added in future changes. A simple allocator for integration tests has been added so that the integration test for posix_spawn can use the posix_spawn_file_actions_add* functions. Reviewed By: michaelrj Differential Revision: https://reviews.llvm.org/D135752
- Loading branch information
Siva Chandra Reddy
committed
Oct 13, 2022
1 parent
dde9db5
commit 02a543d
Showing
20 changed files
with
396 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
//===-- 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_SPAWNATTR_T_H | ||
#define __LLVM_LIBC_TYPES_POSIX_SPAWNATTR_T_H | ||
|
||
typedef struct { | ||
// This data structure will be populated as required. | ||
} posix_spawnattr_t; | ||
|
||
#endif // __LLVM_LIBC_TYPES_POSIX_SPAWNATTR_T_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
add_entrypoint_object( | ||
posix_spawn | ||
SRCS | ||
posix_spawn.cpp | ||
HDRS | ||
../posix_spawn.h | ||
DEPENDS | ||
libc.include.fcntl | ||
libc.include.spawn | ||
libc.include.sys_syscall | ||
libc.src.__support.CPP.optional | ||
libc.src.__support.OSUtil.osutil | ||
libc.src.spawn.file_actions | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
//===-- Linux implementation of posix_spawn -------------------------------===// | ||
// | ||
// 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/posix_spawn.h" | ||
|
||
#include "src/__support/CPP/optional.h" | ||
#include "src/__support/OSUtil/syscall.h" // For internal syscall function. | ||
#include "src/__support/common.h" | ||
#include "src/spawn/file_actions.h" | ||
|
||
#include <fcntl.h> | ||
#include <spawn.h> | ||
#include <sys/syscall.h> // For syscall numbers. | ||
|
||
namespace __llvm_libc { | ||
|
||
namespace { | ||
|
||
pid_t fork() { | ||
// TODO: Use only the clone syscall and use a sperate small stack in the child | ||
// to avoid duplicating the complete stack from the parent. A new stack will | ||
// be created on exec anyway so duplicating the full stack is unnecessary. | ||
#ifdef SYS_fork | ||
return __llvm_libc::syscall_impl(SYS_fork); | ||
#elif defined(SYS_clone) | ||
return __llvm_libc::syscall_impl(SYS_clone, SIGCHLD, 0); | ||
#else | ||
#error "SYS_fork or SYS_clone not available." | ||
#endif | ||
} | ||
|
||
cpp::optional<int> open(const char *path, int oflags, mode_t mode) { | ||
#ifdef SYS_open | ||
int fd = __llvm_libc::syscall_impl(SYS_open, path, oflags, mode); | ||
#else | ||
int fd = __llvm_libc::syscall_impl(SYS_openat, AT_FDCWD, path, oflags, mode); | ||
#endif | ||
if (fd > 0) | ||
return fd; | ||
// The open function is called as part of the child process' preparatory | ||
// steps. If an open fails, the child process just exits. So, unlike | ||
// the public open function, we do not need to set errno here. | ||
return cpp::nullopt; | ||
} | ||
|
||
void close(int fd) { __llvm_libc::syscall_impl(SYS_close, fd); } | ||
|
||
bool dup2(int fd, int newfd) { | ||
long ret = __llvm_libc::syscall_impl(SYS_dup2, fd, newfd); | ||
return ret < 0 ? false : true; | ||
} | ||
|
||
// All exits from child_process are error exits. So, we use a simple | ||
// exit implementation which exits with code 127. | ||
void exit() { | ||
for (;;) { | ||
__llvm_libc::syscall_impl(SYS_exit_group, 127); | ||
__llvm_libc::syscall_impl(SYS_exit, 127); | ||
} | ||
} | ||
|
||
void child_process(const char *__restrict path, | ||
const posix_spawn_file_actions_t *file_actions, | ||
const posix_spawnattr_t *__restrict, // For now unused | ||
char *const *__restrict argv, char *const *__restrict envp) { | ||
// TODO: In the code below, the child_process just exits on error during | ||
// processing |file_actions| and |attr|. The correct way would be to exit | ||
// after conveying the information about the failure to the parent process | ||
// (via a pipe for example). | ||
// TODO: Handle |attr|. | ||
|
||
if (file_actions != nullptr) { | ||
auto *act = reinterpret_cast<BaseSpawnFileAction *>(file_actions->__front); | ||
while (act != nullptr) { | ||
switch (act->type) { | ||
case BaseSpawnFileAction::OPEN: { | ||
auto *open_act = reinterpret_cast<SpawnFileOpenAction *>(act); | ||
auto fd = open(open_act->path, open_act->oflag, open_act->mode); | ||
if (!fd) | ||
exit(); | ||
int actual_fd = *fd; | ||
if (actual_fd != open_act->fd) { | ||
bool dup2_result = dup2(actual_fd, open_act->fd); | ||
close(actual_fd); // The old fd is not needed anymore. | ||
if (!dup2_result) | ||
exit(); | ||
} | ||
break; | ||
} | ||
case BaseSpawnFileAction::CLOSE: { | ||
auto *close_act = reinterpret_cast<SpawnFileCloseAction *>(act); | ||
close(close_act->fd); | ||
break; | ||
} | ||
case BaseSpawnFileAction::DUP2: { | ||
auto *dup2_act = reinterpret_cast<SpawnFileDup2Action *>(act); | ||
if (!dup2(dup2_act->fd, dup2_act->newfd)) | ||
exit(); | ||
break; | ||
} | ||
} | ||
act = act->next; | ||
} | ||
} | ||
|
||
if (__llvm_libc::syscall_impl(SYS_execve, path, argv, envp) < 0) | ||
exit(); | ||
} | ||
|
||
} // anonymous namespace | ||
|
||
LLVM_LIBC_FUNCTION(int, posix_spawn, | ||
(pid_t *__restrict pid, const char *__restrict path, | ||
const posix_spawn_file_actions_t *file_actions, | ||
const posix_spawnattr_t *__restrict attr, | ||
char *const *__restrict argv, | ||
char *const *__restrict envp)) { | ||
pid_t cpid = fork(); | ||
if (cpid == 0) | ||
child_process(path, file_actions, attr, argv, envp); | ||
else if (cpid < 0) | ||
return -cpid; | ||
|
||
if (pid != nullptr) | ||
*pid = cpid; | ||
|
||
// TODO: Before returning, one should wait for the child_process to startup | ||
// successfully. For now, we will just return. Future changes will add proper | ||
// wait (using pipes for example). | ||
|
||
return 0; | ||
} | ||
|
||
} // namespace __llvm_libc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
//===-- Implementation header for posix_spawn -------------------*- 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_H | ||
#define LLVM_LIBC_SRC_SPAWN_POSIX_SPAWN_H | ||
|
||
#include <spawn.h> | ||
|
||
namespace __llvm_libc { | ||
|
||
int posix_spawn(pid_t *__restrict pid, const char *__restrict path, | ||
const posix_spawn_file_actions_t *file_actions, | ||
const posix_spawnattr_t *__restrict attr, | ||
char *const *__restrict argv, char *const *__restrict envp); | ||
|
||
} // namespace __llvm_libc | ||
|
||
#endif // LLVM_LIBC_SRC_SPAWN_POSIX_SPAWN_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
add_custom_target(spawn-integration-tests) | ||
add_dependencies(libc-integration-tests spawn-integration-tests) | ||
|
||
add_executable( | ||
libc_posix_spawn_test_binary | ||
EXCLUDE_FROM_ALL | ||
posix_spawn_test_binary.cpp | ||
test_binary_properties.h | ||
) | ||
set_target_properties( | ||
libc_posix_spawn_test_binary | ||
PROPERTIES | ||
OUTPUT_NAME libc_posix_spawn_test_binary | ||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} | ||
) | ||
|
||
add_header_library( | ||
test_binary_properties | ||
HDRS | ||
test_binary_properties.h | ||
) | ||
|
||
add_integration_test( | ||
posix_spawn_test | ||
SUITE | ||
spawn-integration-tests | ||
SRCS | ||
posix_spawn_test.cpp | ||
LOADER | ||
libc.loader.linux.crt1 | ||
DEPENDS | ||
libc_posix_spawn_test_binary | ||
libc.test.integration.src.spawn.test_binary_properties | ||
libc.include.fcntl | ||
libc.include.signal | ||
libc.include.spawn | ||
libc.include.sys_wait | ||
libc.src.signal.raise | ||
libc.src.spawn.posix_spawn | ||
libc.src.spawn.posix_spawn_file_actions_addopen | ||
libc.src.spawn.posix_spawn_file_actions_destroy | ||
libc.src.spawn.posix_spawn_file_actions_init | ||
libc.src.sys.wait.waitpid | ||
) | ||
|
||
add_subdirectory(testdata) |
Oops, something went wrong.