diff --git a/README.md b/README.md index e03e98b..a9ec17b 100644 --- a/README.md +++ b/README.md @@ -179,6 +179,13 @@ pass `NULL` to inherit the parent's current working directory. On Windows, custom environment entries and the current working directory string are interpreted as UTF-8. +Not every platform can honour a custom working directory. Where it cannot, +`SUBPROCESS_HAVE_CWD` is defined to `0` and passing a non-`NULL` working +directory fails with `ENOSYS`; this currently affects glibc older than 2.29, +macOS older than 10.15, and iOS, tvOS and watchOS, where Apple marks the +underlying call unavailable. Define `SUBPROCESS_HAVE_CWD` yourself to override +the detection, for instance on musl older than 1.1.24. + Note though that you **cannot** specify `subprocess_option_inherit_environment` with a custom environment. If you want to merge some custom environment with the parent process environment then it is up to you as the user to query the original diff --git a/subprocess.h b/subprocess.h index 5e80902..a81f45a 100644 --- a/subprocess.h +++ b/subprocess.h @@ -274,6 +274,25 @@ subprocess_weak int subprocess_alive(struct subprocess_s *const process); #include #endif +/* Whether subprocess_create_ex can honour process_cwd. glibc only gained + posix_spawn_file_actions_addchdir_np in 2.29, and macOS in 10.15; the SDKs + mark it unavailable on iOS, tvOS and watchOS, where the undefined version + macro folds to 0 and so answers correctly. Define this yourself to override + the detection, for instance on musl older than 1.1.24. */ +#if !defined(SUBPROCESS_HAVE_CWD) +#if defined(__GLIBC__) +#if __GLIBC_PREREQ(2, 29) +#define SUBPROCESS_HAVE_CWD 1 +#else +#define SUBPROCESS_HAVE_CWD 0 +#endif +#elif defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED < 101500 +#define SUBPROCESS_HAVE_CWD 0 +#else +#define SUBPROCESS_HAVE_CWD 1 +#endif +#endif + #if defined(_WIN32) #include @@ -1207,6 +1226,8 @@ int subprocess_create_ex(const char *const commandLine[], int options, if (process_cwd) { #if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED >= 260000 posix_error = posix_spawn_file_actions_addchdir(&actions, process_cwd); +#elif !SUBPROCESS_HAVE_CWD + posix_error = ENOSYS; #else #if defined(__APPLE__) && defined(__clang__) #pragma clang diagnostic push diff --git a/test/test_shared.h b/test/test_shared.h index a694ed6..b6a9706 100644 --- a/test/test_shared.h +++ b/test/test_shared.h @@ -1116,6 +1116,7 @@ SUBPROCESS_TEST(environment, specify_environment) { ASSERT_EQ(0, subprocess_destroy(&process)); } +#if SUBPROCESS_HAVE_CWD SUBPROCESS_TEST(create_ex, subprocess_cwd) { char current_path[4096]; char target_path[4096]; @@ -1156,6 +1157,7 @@ SUBPROCESS_TEST(create_ex, subprocess_cwd) { ASSERT_EQ(0, subprocess_destroy(&process)); } +#endif #if !defined(_MSC_VER) SUBPROCESS_TEST(executable_resolve, no_slashes_with_environment) {