profile
viewpoint
Ben Noordhuis bnoordhuis Deno Land Inc. The Netherlands

bnoordhuis/bspc 22

Quake 3 BSP-to-AAS compiler

bnoordhuis/amazing-graceful-fs 4

Like graceful-fs, but without eval() hacks and polyfills.

bnoordhuis/chicken-core 4

http://call-cc.org/

bnoordhuis/axis2-c 3

Apache Axis2/C is a Web services engine implemented in the C programming language.

bnoordhuis/chamfilter 3

block China and other South Asian countries at the firewall level

bnoordhuis/entityplus 3

just another quake 3 mod

bnoordhuis/c-ares 2

c-ares is a C library that performs DNS requests and name resolves asynchronously.

issue closedlibuv/libuv

tools/node_modules/eslint/node_modules/table/node_modules/ajv/README.md

<!-- If you want to report a bug, you are in the right place!

If you need help or have a question, go here: https://github.com/libuv/help/issues/new

If you are reporting a libuv test failure, please ensure that you are not running the test as root.

Please include code that demonstrates the bug and keep it short and simple. -->

  • Version: <!-- libuv version -->
  • Platform: <!-- uname -a (UNIX), or Windows version and machine type -->

closed time in 5 hours

chukys1234

issue commentlibuv/libuv

tools/node_modules/eslint/node_modules/table/node_modules/ajv/README.md

Seguimos modificando

chukys1234

comment created time in 7 hours

issue openedlibuv/libuv

tools/node_modules/eslint/node_modules/table/node_modules/ajv/README.md

<!-- If you want to report a bug, you are in the right place!

If you need help or have a question, go here: https://github.com/libuv/help/issues/new

If you are reporting a libuv test failure, please ensure that you are not running the test as root.

Please include code that demonstrates the bug and keep it short and simple. -->

  • Version: <!-- libuv version -->
  • Platform: <!-- uname -a (UNIX), or Windows version and machine type -->

created time in 7 hours

startedjhlagado/forth-iterators

started time in 8 hours

PR opened libuv/libuv

Linux abstract namespace socket for uv_pipe_connect, uv_pipe_bind

In current libuv, uv_pipe_connect and uv_pipe_bind cannot be used for Linux abstract namespace sockets because the leading \0 character in the address is interpreted as the end of the string. Following the convention for how such sockets are reported by netstat, this change would likewise allow uv_pipe_connect/uv_pipe_bind to use abstract sockets by mapping a leading @ character to \0. For consistency, up_pipe_getsockname/uv_pipe_getpeername perform the reverse translation.

+32 -3

0 comment

3 changed files

pr created time in 10 hours

startedbnoordhuis/node-heapdump

started time in 20 hours

PR closed libuv/libuv

unix: support macOS CoW file copy

This is another proposal on supporting CoW on macOS.

One caveat is that on my machine, clonefile() does not seem to set the group ID on the destination file correctly.

+43 -0

0 comment

1 changed file

cjihrig

pr closed time in a day

PR closed libuv/libuv

test: fix 'incompatible pointer types' warnings

Refs: https://github.com/libuv/libuv/pull/2686

+2 -2

2 comments

1 changed file

cjihrig

pr closed time in a day

pull request commentlibuv/libuv

test: fix 'incompatible pointer types' warnings

Landed in https://github.com/libuv/libuv/commit/9c3d692b3941a2a4171629fb52af2e1029c415e8. Thanks for the reviews.

cjihrig

comment created time in a day

push eventlibuv/libuv

cjihrig

commit sha 9c3d692b3941a2a4171629fb52af2e1029c415e8

test: fix 'incompatible pointer types' warnings Refs: https://github.com/libuv/libuv/pull/2686 PR-URL: https://github.com/libuv/libuv/pull/3088 Reviewed-By: Jameson Nash <vtjnash@gmail.com> Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>

view details

push time in a day

startedchmodawk/OSX-Forth

started time in a day

startedDanya0x07/smiling-led-mask

started time in a day

startedg2pmas/bitkanone

started time in a day

startedLongJohnCoder/swapforth

started time in a day

startedkrb18/D3-Conways-life-KRB

started time in a day

push eventcjihrig/uvwasi

cjihrig

commit sha 2d4e6c92b60944f7485515564b97e5dcae1849e4

remove personal funding links

view details

push time in a day

push eventcjihrig/uvwasi

cjihrig

commit sha 4911b557e864c875992a7776eb77a6fa12144521

add documents required by nodejs org Refs: https://github.com/nodejs/admin/issues/578#issuecomment-758215838

view details

push time in a day

pull request commentlibuv/libuv

win,fsevent: optionally ignore change to last access time

I added a test, but it passes even without UV_FS_EVENT_IGNORE_LAST_ACCESS. I still need to figure out why that is. The last access time does change in the test, as expected.

drizzd

comment created time in 2 days

pull request commentlibuv/libuv

win: consider a broken pipe a normal EOF

Resumed builds, errors looked unrelated https://ci.nodejs.org/view/libuv/job/libuv-in-node/173/ and https://ci.nodejs.org/view/libuv/job/libuv-test-commit/2116/

mmomtchev

comment created time in 2 days

pull request commentdenoland/rusty_v8

Disable broken aarch64-unknown-linux-gnu build

Fwiw, I am monitoring a aarch64 rpm that can be pulled from a repo (configured for opensuse tumbleweed, but probably compatible with other rpm linuxes). It's continuously built and rebuilt as the build deps change. Will forward any build regressions.

piscisaureus

comment created time in 2 days

Pull request review commentdenoland/rusty_v8

Support setting OOM callback on `Isolate`.

 fn run_with_rust_allocator() {   let count_loaded = count.load(Ordering::SeqCst);   assert_eq!(count_loaded, 0); }++#[test]+fn oom_callback() {+  extern "C" {+    fn setjmp(env: &mut [usize; 32]) -> i32;+    fn longjmp(env: &[usize; 32], value: i32) -> !;+  }++  static mut JMPBUF: [usize; 32] = [0; 32];++  extern "C" fn oom_callback(_: *const std::os::raw::c_char, _: bool) {+    unsafe {+      longjmp(&JMPBUF, 42);

Yeah it seems that the test is broken on Windows, triggering some undefined behavior here.

Updated.

losfair

comment created time in 2 days

pull request commentlibuv/libuv

darwin: Use posix_spawn to spawn subprocesses in macOS

@santigimeno Thanks, addressed all but one, with had an open question to which I replied; but I'll change if requested.

jpcanepa

comment created time in 2 days

Pull request review commentlibuv/libuv

darwin: Use posix_spawn to spawn subprocesses in macOS

 static void uv__process_child_init(const uv_process_options_t* options, #endif  +#if defined(__APPLE__)+typedef struct uv__posix_spawn_fncs_tag {+  struct {+    int (*set_uid_np)(const posix_spawnattr_t *, uid_t);+    int (*set_gid_np)(const posix_spawnattr_t *, gid_t);+    int (*set_groups_np)(const posix_spawnattr_t*, int, gid_t*, uid_t);+  } spawnattr;++  struct {+    int (*addchdir_np)(const posix_spawn_file_actions_t *, const char *);+  } file_actions;+} uv__posix_spawn_fncs_t;+++static uv_once_t posix_spawn_init_once = UV_ONCE_INIT;+static uv__posix_spawn_fncs_t posix_spawn_fncs;+static int posix_spawn_can_use_setsid = 0;+++void uv__spawn_init_posix_spawn_fncs(void) {+  /* Try to locate all non-portable functions at runtime */+  posix_spawn_fncs.spawnattr.set_uid_np = +    dlsym(RTLD_DEFAULT, "posix_spawnattr_set_uid_np");+  posix_spawn_fncs.spawnattr.set_gid_np = +    dlsym(RTLD_DEFAULT, "posix_spawnattr_set_gid_np");+  posix_spawn_fncs.spawnattr.set_groups_np = +    dlsym(RTLD_DEFAULT, "posix_spawnattr_set_groups_np");+  posix_spawn_fncs.file_actions.addchdir_np = +    dlsym(RTLD_DEFAULT, "posix_spawn_file_actions_addchdir_np");+}+++void uv__spawn_init_can_use_setsid(void) {+  static const int MACOS_CATALINA_VERSION_MAJOR = 19;+  char version_str[256];+  char* version_major_str;+  size_t version_str_size = 256;+  int r;+  int version_major;++  /* By default, assume failure */+  posix_spawn_can_use_setsid = 0;

Not initializing variable makes me nervous, and (to me at least) having the default case value right there makes it easier to follow the code.

jpcanepa

comment created time in 2 days

issue commentForthHub/discussion

Minimal set of low level words to build forth

@jacereda yes, I'm aware of the OISC, but I'm specifically interested in forth primitives that can be used to define the rest of the system. It is absolutely possible to implement forth in OISC, but in this case OISC single command will be used as an assembler, not as a forth primitive. And we will need to implement stack and everything else.

kt97679

comment created time in 2 days

issue commentForthHub/discussion

Minimal set of low level words to build forth

If it's a theoretical question you might be interested in https://en.wikipedia.org/wiki/One-instruction_set_computer

kt97679

comment created time in 2 days

Pull request review commentlibuv/libuv

darwin: Use posix_spawn to spawn subprocesses in macOS

 static void uv__process_child_init(const uv_process_options_t* options, #endif  +#if defined(__APPLE__)+typedef struct uv__posix_spawn_fncs_tag {+  struct {+    int (*set_uid_np)(const posix_spawnattr_t *, uid_t);+    int (*set_gid_np)(const posix_spawnattr_t *, gid_t);+    int (*set_groups_np)(const posix_spawnattr_t*, int, gid_t*, uid_t);+  } spawnattr;++  struct {+    int (*addchdir_np)(const posix_spawn_file_actions_t *, const char *);+  } file_actions;+} uv__posix_spawn_fncs_t;+++static uv_once_t posix_spawn_init_once = UV_ONCE_INIT;+static uv__posix_spawn_fncs_t posix_spawn_fncs;+static int posix_spawn_can_use_setsid = 0;+++void uv__spawn_init_posix_spawn_fncs(void) {+  /* Try to locate all non-portable functions at runtime */+  posix_spawn_fncs.spawnattr.set_uid_np = +    dlsym(RTLD_DEFAULT, "posix_spawnattr_set_uid_np");+  posix_spawn_fncs.spawnattr.set_gid_np = +    dlsym(RTLD_DEFAULT, "posix_spawnattr_set_gid_np");+  posix_spawn_fncs.spawnattr.set_groups_np = +    dlsym(RTLD_DEFAULT, "posix_spawnattr_set_groups_np");+  posix_spawn_fncs.file_actions.addchdir_np = +    dlsym(RTLD_DEFAULT, "posix_spawn_file_actions_addchdir_np");+}+++void uv__spawn_init_can_use_setsid(void) {+  static const int MACOS_CATALINA_VERSION_MAJOR = 19;+  char version_str[256];+  char* version_major_str;+  size_t version_str_size = 256;+  int r;+  int version_major;++  /* By default, assume failure */+  posix_spawn_can_use_setsid = 0;

Is this needed? Shouldn't it be always 0 ?

jpcanepa

comment created time in 2 days

Pull request review commentlibuv/libuv

darwin: Use posix_spawn to spawn subprocesses in macOS

 static void uv__process_child_init(const uv_process_options_t* options, #endif  +#if defined(__APPLE__)+typedef struct uv__posix_spawn_fncs_tag {+  struct {+    int (*set_uid_np)(const posix_spawnattr_t *, uid_t);+    int (*set_gid_np)(const posix_spawnattr_t *, gid_t);+    int (*set_groups_np)(const posix_spawnattr_t*, int, gid_t*, uid_t);+  } spawnattr;++  struct {+    int (*addchdir_np)(const posix_spawn_file_actions_t *, const char *);+  } file_actions;+} uv__posix_spawn_fncs_t;+++static uv_once_t posix_spawn_init_once = UV_ONCE_INIT;+static uv__posix_spawn_fncs_t posix_spawn_fncs;+static int posix_spawn_can_use_setsid = 0;+++void uv__spawn_init_posix_spawn_fncs(void) {+  /* Try to locate all non-portable functions at runtime */+  posix_spawn_fncs.spawnattr.set_uid_np = +    dlsym(RTLD_DEFAULT, "posix_spawnattr_set_uid_np");+  posix_spawn_fncs.spawnattr.set_gid_np = +    dlsym(RTLD_DEFAULT, "posix_spawnattr_set_gid_np");+  posix_spawn_fncs.spawnattr.set_groups_np = +    dlsym(RTLD_DEFAULT, "posix_spawnattr_set_groups_np");+  posix_spawn_fncs.file_actions.addchdir_np = +    dlsym(RTLD_DEFAULT, "posix_spawn_file_actions_addchdir_np");+}+++void uv__spawn_init_can_use_setsid(void) {+  static const int MACOS_CATALINA_VERSION_MAJOR = 19;+  char version_str[256];+  char* version_major_str;+  size_t version_str_size = 256;+  int r;+  int version_major;++  /* By default, assume failure */+  posix_spawn_can_use_setsid = 0;++  /* Get a version string */+  r = sysctlbyname("kern.osrelease", version_str, &version_str_size, NULL, 0);+  if (r != 0)+    return;++  /* Try to get the major version number. If not found+   * fall back to the fork/exec flow */+  version_major_str = strtok(version_str, ".");+  if (version_major_str == NULL)+    return;++  /* Parse the version major as a number. If it is greater than+   * the major version for macOS Catalina (aka macOS 10.15), then+   * the POSIX_SPAWN_SETSID flag is available */+  version_major = atoi(version_major_str);+  if (version_major >= MACOS_CATALINA_VERSION_MAJOR)+    posix_spawn_can_use_setsid = 1;+}+++void uv__spawn_init_posix_spawn(void) {+  /* Init handles to all potentially non-defined functions */+  uv__spawn_init_posix_spawn_fncs();++  /* Init feature detection for POSIX_SPAWN_SETSID flag */+  uv__spawn_init_can_use_setsid();+}+++int uv__spawn_set_posix_spawn_attrs(posix_spawnattr_t* attrs,+                                    const uv__posix_spawn_fncs_t* posix_spawn_fncs,+                                    const uv_process_options_t* options) {+  int err;+  unsigned int flags;+  sigset_t signal_set;++  err = posix_spawnattr_init(attrs);+  if (err != 0) {+    /* If initialization fails, no need to de-init, just return */+    return err;+  }++  if (options->flags & UV_PROCESS_SETUID) {+    if (posix_spawn_fncs->spawnattr.set_uid_np == NULL) {+      err = ENOSYS;+      goto error;+    }++    err = posix_spawn_fncs->spawnattr.set_uid_np(attrs, options->uid);+    if (err != 0)+      goto error;+  }++  if (options->flags & UV_PROCESS_SETGID) {+    if (posix_spawn_fncs->spawnattr.set_gid_np == NULL) {+      err = ENOSYS;+      goto error;+    }++    err = posix_spawn_fncs->spawnattr.set_gid_np(attrs, options->gid);+    if (err != 0) +      goto error;+  }++  if (options->flags & (UV_PROCESS_SETUID | UV_PROCESS_SETGID)) {+    /* Using ngroups = 0 implied the group_array is empty, and so +     * its contents are never traversed. Still the +     * posix_spawn_set_groups_np function seems to require that the +     * group_array pointer be non-null */+    const int ngroups = 0;+    gid_t group_array = KAUTH_GID_NONE;++    if (posix_spawn_fncs->spawnattr.set_groups_np == NULL) {+      err = ENOSYS;+      goto error;+    }+    +    /* See the comment on the call to setgroups in uv__process_child_init above+     * for why this is not a fatal error */+    SAVE_ERRNO(posix_spawn_fncs->spawnattr.set_groups_np(+      attrs, +      ngroups, +      &group_array, +      KAUTH_UID_NONE));+  }++  /* Set flags for spawn behavior +    * 1) POSIX_SPAWN_CLOEXEC_DEFAULT: (Apple Extension) All descriptors in+    * the parent will be treated as if they had been created with O_CLOEXEC.+    * The only fds that will be passed on to the child are those manipulated+    * by the file actions+    * 2) POSIX_SPAWN_SETSIGDEF: Signals mentioned in spawn-sigdefault in+    * the spawn attributes will be reset to behave as their default+    * 3) POSIX_SPAWN_SETSIGMASK: Signal mask will be set to the value of+    * spawn-sigmask in attributes+    * 4) POSIX_SPAWN_SETSID: Make the process a new session leader if a+    * detached session was requested. */+  flags = POSIX_SPAWN_CLOEXEC_DEFAULT |+          POSIX_SPAWN_SETSIGDEF |+          POSIX_SPAWN_SETSIGMASK;+  if (options->flags & UV_PROCESS_DETACHED) {+    /* If running on a version of macOS where this flag is not supported,+     * revert back to the fork/exec flow. Otherwise posix_spawn will+     * silently ignore the flag. */+    if (!posix_spawn_can_use_setsid) {+      err = ENOSYS;+      goto error;+    }++    flags |= POSIX_SPAWN_SETSID;+  }+  err = posix_spawnattr_setflags(attrs, flags);+  if (err != 0)+    goto error;++  /*  Reset all signal the child to their default behavior */+  sigfillset(&signal_set);+  err = posix_spawnattr_setsigdefault(attrs, &signal_set);+  if (err != 0) +    goto error;++  /*  Reset the signal mask for all signals */+  sigemptyset(&signal_set);+  err = posix_spawnattr_setsigmask(attrs, &signal_set);+  if (err != 0)+    goto error;++  return err;++error:+  (void) posix_spawnattr_destroy(attrs);+  return err;+}+++int uv__spawn_set_posix_spawn_file_actions(posix_spawn_file_actions_t* actions,+                                           const uv__posix_spawn_fncs_t* posix_spawn_fncs,+                                           const uv_process_options_t* options,+                                           int stdio_count,+                                           int (*pipes)[2]) {+  int fd;+  int err;++  err = posix_spawn_file_actions_init(actions);+  if (err != 0) {+    /* If initialization fails, no need to de-init, just return */+    return err;+  }++  /* Set the current working directory if requested */+  if (options->cwd != NULL) {+    if (posix_spawn_fncs->file_actions.addchdir_np == NULL) {+      err = ENOSYS;+      goto error;+    }++    err = posix_spawn_fncs->file_actions.addchdir_np(actions, options->cwd);+    if (err != 0)+      goto error;+  }++  /* First, duplicate any required fd into orbit, out of the range of +   * the descriptors that should be mapped in. */+  for (fd = 0; fd < stdio_count; fd++) {+    if (pipes[fd][1] < 0)+      continue;+    +    err = posix_spawn_file_actions_adddup2(+      actions, +      pipes[fd][1], +      stdio_count + fd);+    if (err != 0)+      goto error;+  }++  /*  Second, move the descriptors into their respective places */+  for (fd = 0; fd < stdio_count; fd++) {+    if (pipes[fd][1] < 0)+      continue;++    err = posix_spawn_file_actions_adddup2(actions, stdio_count + fd, fd);+    if (err != 0)+      goto error;+  }++  /*  Finally, close all the superfluous descriptors */+  for (fd = 0; fd < stdio_count; fd++) {+    if (pipes[fd][1] < 0)+      continue;+    +    err = posix_spawn_file_actions_addclose(actions, stdio_count + fd);+    if (err != 0)+      goto error;+  }++  /*  Finally process the standard streams as per documentation */+  for (fd = 0; fd < 3; fd++) {+    int oflags;+    const int mode = 0;++    oflags = fd == 0 ? O_RDONLY : O_RDWR;++    if (pipes[fd][1] != -1) {+      /* If not ignored, make sure the fd is marked as non-blocking */+      uv__nonblock_fcntl(pipes[fd][1], 0);+    } else {+      /* If ignored, redirect to (or from) /dev/null, */+      err = posix_spawn_file_actions_addopen(+        actions, +        fd, +        "/dev/null", +        oflags, +        mode);+      if (err != 0)+        goto error;+    }+  }  ++  return 0;++error:+  (void) posix_spawn_file_actions_destroy(actions);+  return err;+}++char* uv__spawn_find_path_in_env(char** env) {+  char** env_iterator;++  /* Look for an environment variable called PATH in the +   * provided env array, and return its value if found */+  for (env_iterator = env; *env_iterator != NULL; env_iterator++) {+    const char path_var[] = "PATH=";+    if (strncmp(*env_iterator, path_var, sizeof(path_var) - 1) == 0) {+      /* Found "PATH=" at the beginning of the string */+      return *env_iterator + sizeof(path_var) - 1;+    }+  }++  return NULL;+}+++int uv__spawn_resolve_and_spawn(const uv_process_options_t* options, +                                posix_spawnattr_t* attrs,+                                posix_spawn_file_actions_t* actions,+                                pid_t* pid) {+  const char *p;+  const char *z;+  const char *path = NULL;+  size_t l;+  size_t k;+  int err = -1;++  /* Short circuit for erroneous case */+  if (options->file == NULL) +    return ENOENT;++  /* The environment for the child process is that of the parent unless overriden +   * by options->env */+  char** env = environ;+  if (options->env != NULL)+    env = options->env;++  /* If options->file contains a slash, posix_spawn/posix_spawnp behave+   * the same, and don't involve PATH resolution at all. Otherwise, if+   * options->file does not include a slash, but no custom environment is +   * to be used, the environment used for path resolution as well for the +   * child process is that of the parent process, so posix_spawnp is the+   * way to go. */+  if (strchr(options->file, '/') != NULL || options->env == NULL)+    return posix_spawnp(pid, options->file, actions, attrs, options->args, env);++  /* Look for the definition of PATH in the provided env */+  path = uv__spawn_find_path_in_env(options->env);++  /* The following resolution logic (execvpe emulation) is taken from +   * https://github.com/JuliaLang/libuv/commit/9af3af617138d6a6de7d72819ed362996ff255d9+   * and adapted to work around our own situations */++  /* If no path was provided in options->env, use the default value +   * to look for the executable */+  if (!path) 
  if (path == NULL) 
jpcanepa

comment created time in 2 days

Pull request review commentlibuv/libuv

darwin: Use posix_spawn to spawn subprocesses in macOS

 static void uv__process_child_init(const uv_process_options_t* options, #endif  +#if defined(__APPLE__)+typedef struct uv__posix_spawn_fncs_tag {+  struct {+    int (*set_uid_np)(const posix_spawnattr_t *, uid_t);+    int (*set_gid_np)(const posix_spawnattr_t *, gid_t);+    int (*set_groups_np)(const posix_spawnattr_t*, int, gid_t*, uid_t);+  } spawnattr;++  struct {+    int (*addchdir_np)(const posix_spawn_file_actions_t *, const char *);+  } file_actions;+} uv__posix_spawn_fncs_t;+++static uv_once_t posix_spawn_init_once = UV_ONCE_INIT;+static uv__posix_spawn_fncs_t posix_spawn_fncs;+static int posix_spawn_can_use_setsid = 0;

No need to initialize an static variable to 0:

static int posix_spawn_can_use_setsid;
jpcanepa

comment created time in 2 days

Pull request review commentlibuv/libuv

darwin: Use posix_spawn to spawn subprocesses in macOS

 static void uv__process_child_init(const uv_process_options_t* options, #endif  +#if defined(__APPLE__)+typedef struct uv__posix_spawn_fncs_tag {+  struct {+    int (*set_uid_np)(const posix_spawnattr_t *, uid_t);+    int (*set_gid_np)(const posix_spawnattr_t *, gid_t);+    int (*set_groups_np)(const posix_spawnattr_t*, int, gid_t*, uid_t);+  } spawnattr;++  struct {+    int (*addchdir_np)(const posix_spawn_file_actions_t *, const char *);+  } file_actions;+} uv__posix_spawn_fncs_t;+++static uv_once_t posix_spawn_init_once = UV_ONCE_INIT;+static uv__posix_spawn_fncs_t posix_spawn_fncs;+static int posix_spawn_can_use_setsid = 0;+++void uv__spawn_init_posix_spawn_fncs(void) {+  /* Try to locate all non-portable functions at runtime */+  posix_spawn_fncs.spawnattr.set_uid_np = +    dlsym(RTLD_DEFAULT, "posix_spawnattr_set_uid_np");+  posix_spawn_fncs.spawnattr.set_gid_np = +    dlsym(RTLD_DEFAULT, "posix_spawnattr_set_gid_np");+  posix_spawn_fncs.spawnattr.set_groups_np = +    dlsym(RTLD_DEFAULT, "posix_spawnattr_set_groups_np");+  posix_spawn_fncs.file_actions.addchdir_np = +    dlsym(RTLD_DEFAULT, "posix_spawn_file_actions_addchdir_np");+}+++void uv__spawn_init_can_use_setsid(void) {+  static const int MACOS_CATALINA_VERSION_MAJOR = 19;+  char version_str[256];+  char* version_major_str;+  size_t version_str_size = 256;+  int r;+  int version_major;++  /* By default, assume failure */+  posix_spawn_can_use_setsid = 0;++  /* Get a version string */+  r = sysctlbyname("kern.osrelease", version_str, &version_str_size, NULL, 0);+  if (r != 0)+    return;++  /* Try to get the major version number. If not found+   * fall back to the fork/exec flow */+  version_major_str = strtok(version_str, ".");+  if (version_major_str == NULL)+    return;++  /* Parse the version major as a number. If it is greater than+   * the major version for macOS Catalina (aka macOS 10.15), then+   * the POSIX_SPAWN_SETSID flag is available */+  version_major = atoi(version_major_str);+  if (version_major >= MACOS_CATALINA_VERSION_MAJOR)+    posix_spawn_can_use_setsid = 1;+}+++void uv__spawn_init_posix_spawn(void) {+  /* Init handles to all potentially non-defined functions */+  uv__spawn_init_posix_spawn_fncs();++  /* Init feature detection for POSIX_SPAWN_SETSID flag */+  uv__spawn_init_can_use_setsid();+}+++int uv__spawn_set_posix_spawn_attrs(posix_spawnattr_t* attrs,+                                    const uv__posix_spawn_fncs_t* posix_spawn_fncs,+                                    const uv_process_options_t* options) {+  int err;+  unsigned int flags;+  sigset_t signal_set;++  err = posix_spawnattr_init(attrs);+  if (err != 0) {+    /* If initialization fails, no need to de-init, just return */+    return err;+  }++  if (options->flags & UV_PROCESS_SETUID) {+    if (posix_spawn_fncs->spawnattr.set_uid_np == NULL) {+      err = ENOSYS;+      goto error;+    }++    err = posix_spawn_fncs->spawnattr.set_uid_np(attrs, options->uid);+    if (err != 0)+      goto error;+  }++  if (options->flags & UV_PROCESS_SETGID) {+    if (posix_spawn_fncs->spawnattr.set_gid_np == NULL) {+      err = ENOSYS;+      goto error;+    }++    err = posix_spawn_fncs->spawnattr.set_gid_np(attrs, options->gid);+    if (err != 0) +      goto error;+  }++  if (options->flags & (UV_PROCESS_SETUID | UV_PROCESS_SETGID)) {+    /* Using ngroups = 0 implied the group_array is empty, and so +     * its contents are never traversed. Still the +     * posix_spawn_set_groups_np function seems to require that the +     * group_array pointer be non-null */+    const int ngroups = 0;+    gid_t group_array = KAUTH_GID_NONE;++    if (posix_spawn_fncs->spawnattr.set_groups_np == NULL) {+      err = ENOSYS;+      goto error;+    }+    +    /* See the comment on the call to setgroups in uv__process_child_init above+     * for why this is not a fatal error */+    SAVE_ERRNO(posix_spawn_fncs->spawnattr.set_groups_np(+      attrs, +      ngroups, +      &group_array, +      KAUTH_UID_NONE));+  }++  /* Set flags for spawn behavior +    * 1) POSIX_SPAWN_CLOEXEC_DEFAULT: (Apple Extension) All descriptors in+    * the parent will be treated as if they had been created with O_CLOEXEC.+    * The only fds that will be passed on to the child are those manipulated+    * by the file actions+    * 2) POSIX_SPAWN_SETSIGDEF: Signals mentioned in spawn-sigdefault in+    * the spawn attributes will be reset to behave as their default+    * 3) POSIX_SPAWN_SETSIGMASK: Signal mask will be set to the value of+    * spawn-sigmask in attributes+    * 4) POSIX_SPAWN_SETSID: Make the process a new session leader if a+    * detached session was requested. */+  flags = POSIX_SPAWN_CLOEXEC_DEFAULT |+          POSIX_SPAWN_SETSIGDEF |+          POSIX_SPAWN_SETSIGMASK;+  if (options->flags & UV_PROCESS_DETACHED) {+    /* If running on a version of macOS where this flag is not supported,+     * revert back to the fork/exec flow. Otherwise posix_spawn will+     * silently ignore the flag. */+    if (!posix_spawn_can_use_setsid) {+      err = ENOSYS;+      goto error;+    }++    flags |= POSIX_SPAWN_SETSID;+  }+  err = posix_spawnattr_setflags(attrs, flags);+  if (err != 0)+    goto error;++  /*  Reset all signal the child to their default behavior */+  sigfillset(&signal_set);+  err = posix_spawnattr_setsigdefault(attrs, &signal_set);+  if (err != 0) +    goto error;++  /*  Reset the signal mask for all signals */+  sigemptyset(&signal_set);+  err = posix_spawnattr_setsigmask(attrs, &signal_set);+  if (err != 0)+    goto error;++  return err;++error:+  (void) posix_spawnattr_destroy(attrs);+  return err;+}+++int uv__spawn_set_posix_spawn_file_actions(posix_spawn_file_actions_t* actions,+                                           const uv__posix_spawn_fncs_t* posix_spawn_fncs,+                                           const uv_process_options_t* options,+                                           int stdio_count,+                                           int (*pipes)[2]) {+  int fd;+  int err;++  err = posix_spawn_file_actions_init(actions);+  if (err != 0) {+    /* If initialization fails, no need to de-init, just return */+    return err;+  }++  /* Set the current working directory if requested */+  if (options->cwd != NULL) {+    if (posix_spawn_fncs->file_actions.addchdir_np == NULL) {+      err = ENOSYS;+      goto error;+    }++    err = posix_spawn_fncs->file_actions.addchdir_np(actions, options->cwd);+    if (err != 0)+      goto error;+  }++  /* First, duplicate any required fd into orbit, out of the range of +   * the descriptors that should be mapped in. */+  for (fd = 0; fd < stdio_count; fd++) {+    if (pipes[fd][1] < 0)+      continue;+    +    err = posix_spawn_file_actions_adddup2(+      actions, +      pipes[fd][1], +      stdio_count + fd);+    if (err != 0)+      goto error;+  }++  /*  Second, move the descriptors into their respective places */+  for (fd = 0; fd < stdio_count; fd++) {+    if (pipes[fd][1] < 0)+      continue;++    err = posix_spawn_file_actions_adddup2(actions, stdio_count + fd, fd);+    if (err != 0)+      goto error;+  }++  /*  Finally, close all the superfluous descriptors */+  for (fd = 0; fd < stdio_count; fd++) {+    if (pipes[fd][1] < 0)+      continue;+    +    err = posix_spawn_file_actions_addclose(actions, stdio_count + fd);+    if (err != 0)+      goto error;+  }++  /*  Finally process the standard streams as per documentation */+  for (fd = 0; fd < 3; fd++) {+    int oflags;+    const int mode = 0;++    oflags = fd == 0 ? O_RDONLY : O_RDWR;++    if (pipes[fd][1] != -1) {+      /* If not ignored, make sure the fd is marked as non-blocking */+      uv__nonblock_fcntl(pipes[fd][1], 0);+    } else {+      /* If ignored, redirect to (or from) /dev/null, */+      err = posix_spawn_file_actions_addopen(+        actions, +        fd, +        "/dev/null", +        oflags, +        mode);+      if (err != 0)+        goto error;+    }+  }  ++  return 0;++error:+  (void) posix_spawn_file_actions_destroy(actions);+  return err;+}++char* uv__spawn_find_path_in_env(char** env) {+  char** env_iterator;++  /* Look for an environment variable called PATH in the +   * provided env array, and return its value if found */+  for (env_iterator = env; *env_iterator != NULL; env_iterator++) {+    const char path_var[] = "PATH=";+    if (strncmp(*env_iterator, path_var, sizeof(path_var) - 1) == 0) {+      /* Found "PATH=" at the beginning of the string */+      return *env_iterator + sizeof(path_var) - 1;+    }+  }++  return NULL;+}+++int uv__spawn_resolve_and_spawn(const uv_process_options_t* options, +                                posix_spawnattr_t* attrs,+                                posix_spawn_file_actions_t* actions,+                                pid_t* pid) {+  const char *p;+  const char *z;+  const char *path = NULL;+  size_t l;+  size_t k;+  int err = -1;++  /* Short circuit for erroneous case */+  if (options->file == NULL) +    return ENOENT;++  /* The environment for the child process is that of the parent unless overriden +   * by options->env */+  char** env = environ;+  if (options->env != NULL)+    env = options->env;++  /* If options->file contains a slash, posix_spawn/posix_spawnp behave+   * the same, and don't involve PATH resolution at all. Otherwise, if+   * options->file does not include a slash, but no custom environment is +   * to be used, the environment used for path resolution as well for the +   * child process is that of the parent process, so posix_spawnp is the+   * way to go. */+  if (strchr(options->file, '/') != NULL || options->env == NULL)+    return posix_spawnp(pid, options->file, actions, attrs, options->args, env);++  /* Look for the definition of PATH in the provided env */+  path = uv__spawn_find_path_in_env(options->env);++  /* The following resolution logic (execvpe emulation) is taken from +   * https://github.com/JuliaLang/libuv/commit/9af3af617138d6a6de7d72819ed362996ff255d9+   * and adapted to work around our own situations */++  /* If no path was provided in options->env, use the default value +   * to look for the executable */+  if (!path) +    path = _PATH_DEFPATH;++  k = strnlen(options->file, NAME_MAX+1);+  if (k > NAME_MAX) {+    return ENAMETOOLONG;+  }++  l = strnlen(path, PATH_MAX-1)+1;++  for (p = path;; p = z) {+    /* Compose the new process file from the entry in the PATH+     * environment variable and the actual file name */+    char b[PATH_MAX + NAME_MAX];+    z = strchr(p, ':');+    if (!z) +      z = p+strlen(p);+    if ((size_t)(z-p) >= l) {+      if (!*z++) +        break;+      +      continue;+    }+    memcpy(b, p, z-p);+    b[z-p] = '/';+    memcpy(b+(z-p)+(z>p), options->file, k+1);++    /* Try to spawn the new process file. If it fails with ENOENT, the+     * new process file is not in this PATH entry, continue with the next+     * PATH entry. */+    err = posix_spawn(pid, b, actions, attrs, options->args, env);+    if (err != ENOENT) +      return err;++    if (!*z++) +      break;+  }++  return err;+}+++int uv__spawn_and_init_child_posix_spawn(const uv_process_options_t* options,+                                         int stdio_count,+                                         int (*pipes)[2], +                                         pid_t* pid,+                                         const uv__posix_spawn_fncs_t* posix_spawn_fncs) {+  int err;+  posix_spawnattr_t attrs;+  posix_spawn_file_actions_t actions;++  err = uv__spawn_set_posix_spawn_attrs(&attrs, posix_spawn_fncs, options);+  if (err != 0) +    goto error;++  err = uv__spawn_set_posix_spawn_file_actions(+    &actions,+    posix_spawn_fncs,+    options,+    stdio_count,+    pipes);+  if (err != 0) {+    (void) posix_spawnattr_destroy(&attrs);+    goto error;+  }++  /* Try to spawn options->file resolving in the provided environment +   * if any */+  err = uv__spawn_resolve_and_spawn(options, &attrs, &actions, pid);++  /* Destroy the actions/attributes */+  (void) posix_spawn_file_actions_destroy(&actions);+  (void) posix_spawnattr_destroy(&attrs);++error:+  /* In an error situation, the attributes and file actions are +   * already destroyed, only the happy path requires cleanup */+  return UV__ERR(err);+}+#endif++int uv__spawn_and_init_child_fork(const uv_process_options_t* options,+                                  int stdio_count,+                                  int (*pipes)[2],+                                  int error_fd,+                                  pid_t* pid) {+  *pid = fork();++  if (*pid == -1) {+    /* Failed to fork */+    return UV__ERR(errno);+  }++  if (*pid == 0) {+    /* Fork succeeded, in the child process */+    uv__process_child_init(options, stdio_count, pipes, error_fd);+    abort();+  }++  /* Fork succeeded, in the parent process */+  return 0;+}++int uv__spawn_and_init_child(const uv_process_options_t* options,+                             int stdio_count,+                             int (*pipes)[2],+                             int error_fd,+                             pid_t* pid) {+  int err = 0;
  int err;
jpcanepa

comment created time in 2 days

more