Skip to content

Commit

Permalink
add HH\Lib\_Private\_OS\dup()
Browse files Browse the repository at this point in the history
Summary:
refs hhvm/hsl#176

This part of enabling a pattern of:
```
list($stderr_parent, $stderr_child) = OS\socketpair(); // yep, stderr is read-write
$stdin_child = OS\dup($stderr_child);
OS\shutdown($stdin_child, OS\SHUT_WR);
$stdout_child = OS\dup($stderr_child);
OS\shutdown($stdout_child, OS\SHUT_RD);
```

`dup2()` is not necessary as we support explicitly remapping FDs when creating subprocesses

`dup2()` is not desirable as:
- Hack programs do not have insights to the real FD numbers. Especially in CLI server mode, STDIN/STDOUT/STDERR may not be on the canonical STDIN_FILENO/STDOUT_FILENO/STDERR_FILENO
- Given that, there's a large risk of accidentally creating cross-request issues with `dup2()`

Reviewed By: shayne-fletcher

Differential Revision: D33166096

fbshipit-source-id: 41339a9a33c854982009086f3efdfc35277715c0
  • Loading branch information
fredemmott authored and facebook-github-bot committed Mar 21, 2022
1 parent 9217447 commit ac00a11
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 1 deletion.
2 changes: 2 additions & 0 deletions hphp/hack/hhi/hsl/ext_hsl_os_fds.hhi
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ function write(FileDescriptor $fd, string $data): int;

function close(FileDescriptor $fd): void;

function dup(FileDescriptor $fd): FileDescriptor;

function pipe(): (FileDescriptor, FileDescriptor);

const int AF_UNSPEC = 0;
Expand Down
11 changes: 10 additions & 1 deletion hphp/runtime/ext/hsl/ext_hsl_os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,11 @@ void throw_errno_exception(int number, const String& message = String()) {
}

template<class T>
void throw_errno_if_minus_one(T var) {
T&& throw_errno_if_minus_one(T&& var) {
if (var == -1) {
throw_errno_exception(errno);
}
return std::forward<T>(var);
}

template<class TRet, class ...Args, class TFn>
Expand Down Expand Up @@ -587,6 +588,13 @@ void HHVM_FUNCTION(HSL_os_close, const Object& obj) {
HSLFileDescriptor::get(obj)->close();
}

Object HHVM_FUNCTION(HSL_os_dup, const Object& fd_wrapper) {
// Not using CLI client/server proxying as `dup()` preserves SO_PEERCRED
auto in = HSLFileDescriptor::fd(fd_wrapper);
auto out = throw_errno_if_minus_one(::dup(in));
return HSLFileDescriptor::newInstance(out);
}

Array HHVM_FUNCTION(HSL_os_pipe) {
int fds[2];
throw_errno_if_minus_one(retry_on_eintr(-1, ::pipe, fds));
Expand Down Expand Up @@ -1214,6 +1222,7 @@ struct OSExtension final : Extension {
HHVM_FALIAS(HH\\Lib\\_Private\\_OS\\read, HSL_os_read);
HHVM_FALIAS(HH\\Lib\\_Private\\_OS\\write, HSL_os_write);
HHVM_FALIAS(HH\\Lib\\_Private\\_OS\\close, HSL_os_close);
HHVM_FALIAS(HH\\Lib\\_Private\\_OS\\dup, HSL_os_dup);

HHVM_FALIAS(HH\\Lib\\_Private\\_OS\\request_stdio_fd, HSL_os_request_stdio_fd);
HHVM_RC_INT(HH\\Lib\\_Private\\_OS\\STDIN_FILENO, STDIN_FILENO);
Expand Down
3 changes: 3 additions & 0 deletions hphp/runtime/ext/hsl/ext_hsl_os.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ function write(FileDescriptor $fd, string $data): int;
<<__Native>>
function close(FileDescriptor $fd): void;

<<__Native>>
function dup(FileDescriptor $fd): FileDescriptor;

<<__Native>>
function pipe(): varray<FileDescriptor>;

Expand Down
18 changes: 18 additions & 0 deletions hphp/test/slow/ext_hsl/os_dup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?hh // strict

use namespace HH\Lib\_Private\_OS;

<<__EntryPoint>>
function main(): void {
list ($r, $w1) = _OS\pipe();
$w2 = _OS\dup($w1);
_OS\write($w2, "Hello, ");
_OS\write($w1, "world.\n");

var_dump(_OS\read($r, 0xff));
_OS\close($w1);
_OS\write($w2, "Hello again.\n");
_OS\close($w2);
var_dump(_OS\read($r, 0xff));
var_dump(_OS\read($r, 0xff));
}
5 changes: 5 additions & 0 deletions hphp/test/slow/ext_hsl/os_dup.php.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
string(14) "Hello, world.
"
string(13) "Hello again.
"
string(0) ""

0 comments on commit ac00a11

Please sign in to comment.