diff --git a/doc/manual/rl-next/haunted-gc-macos.md b/doc/manual/rl-next/haunted-gc-macos.md
new file mode 100644
index 000000000..3ce912b2d
--- /dev/null
+++ b/doc/manual/rl-next/haunted-gc-macos.md
@@ -0,0 +1,15 @@
+---
+synopsis: "Fix unexpectedly-successful GC failures on macOS"
+cls: 1723
+issues: fj#446
+credits: jade
+category: Fixes
+---
+
+Has the following happened to you on macOS? This failure has been successfully eliminated, thanks to our successful deployment of advanced successful-failure detection technology (it's just `if (failed && errno == 0)`. Patent pendingnot really):
+
+```
+$ nix-store --gc --print-dead
+finding garbage collector roots...
+error: Listing pid 87261 file descriptors: Undefined error: 0
+```
diff --git a/meson.build b/meson.build
index 8577657d9..4e2f713ce 100644
--- a/meson.build
+++ b/meson.build
@@ -203,23 +203,23 @@ gc_opt = get_option('gc').disable_if(
'address' in get_option('b_sanitize'),
error_message: 'gc does far too many memory crimes for ASan'
)
-boehm = dependency('bdw-gc', required : gc_opt, version : '>=8.2.6')
+boehm = dependency('bdw-gc', required : gc_opt, version : '>=8.2.6', include_type : 'system')
configdata += {
'HAVE_BOEHMGC': boehm.found().to_int(),
}
-boost = dependency('boost', required : true, modules : ['container'])
+boost = dependency('boost', required : true, modules : ['container'], include_type : 'system')
# cpuid only makes sense on x86_64
cpuid_required = is_x64 ? get_option('cpuid') : false
-cpuid = dependency('libcpuid', 'cpuid', required : cpuid_required)
+cpuid = dependency('libcpuid', 'cpuid', required : cpuid_required, include_type : 'system')
configdata += {
'HAVE_LIBCPUID': cpuid.found().to_int(),
}
# seccomp only makes sense on Linux
seccomp_required = is_linux ? get_option('seccomp-sandboxing') : false
-seccomp = dependency('libseccomp', 'seccomp', required : seccomp_required, version : '>=2.5.5')
+seccomp = dependency('libseccomp', 'seccomp', required : seccomp_required, version : '>=2.5.5', include_type : 'system')
if is_linux and not seccomp.found()
warning('Sandbox security is reduced because libseccomp has not been found! Please provide libseccomp if it supports your CPU architecture.')
endif
@@ -227,19 +227,24 @@ configdata += {
'HAVE_SECCOMP': seccomp.found().to_int(),
}
-libarchive = dependency('libarchive', required : true)
+libarchive = dependency('libarchive', required : true, include_type : 'system')
brotli = [
- dependency('libbrotlicommon', required : true),
- dependency('libbrotlidec', required : true),
- dependency('libbrotlienc', required : true),
+ dependency('libbrotlicommon', required : true, include_type : 'system'),
+ dependency('libbrotlidec', required : true, include_type : 'system'),
+ dependency('libbrotlienc', required : true, include_type : 'system'),
]
-openssl = dependency('libcrypto', 'openssl', required : true)
+openssl = dependency('libcrypto', 'openssl', required : true, include_type : 'system')
# FIXME: confirm we actually support such old versions of aws-sdk-cpp
-aws_sdk = dependency('aws-cpp-sdk-core', required : false, version : '>=1.8')
-aws_sdk_transfer = dependency('aws-cpp-sdk-transfer', required : aws_sdk.found(), fallback : ['aws_sdk', 'aws_cpp_sdk_transfer_dep'])
+aws_sdk = dependency('aws-cpp-sdk-core', required : false, version : '>=1.8', include_type : 'system')
+aws_sdk_transfer = dependency(
+ 'aws-cpp-sdk-transfer',
+ required : aws_sdk.found(),
+ fallback : ['aws_sdk', 'aws_cpp_sdk_transfer_dep'],
+ include_type : 'system',
+)
if aws_sdk.found()
# The AWS pkg-config adds -std=c++11.
# https://github.com/aws/aws-sdk-cpp/issues/2673
@@ -259,7 +264,12 @@ if aws_sdk.found()
)
endif
-aws_s3 = dependency('aws-cpp-sdk-s3', required : aws_sdk.found(), fallback : ['aws_sdk', 'aws_cpp_sdk_s3_dep'])
+aws_s3 = dependency(
+ 'aws-cpp-sdk-s3',
+ required : aws_sdk.found(),
+ fallback : ['aws_sdk', 'aws_cpp_sdk_s3_dep'],
+ include_type : 'system',
+)
if aws_s3.found()
# The AWS pkg-config adds -std=c++11.
# https://github.com/aws/aws-sdk-cpp/issues/2673
@@ -276,30 +286,30 @@ configdata += {
'ENABLE_S3': aws_s3.found().to_int(),
}
-sqlite = dependency('sqlite3', 'sqlite', version : '>=3.6.19', required : true)
+sqlite = dependency('sqlite3', 'sqlite', version : '>=3.6.19', required : true, include_type : 'system')
-sodium = dependency('libsodium', 'sodium', required : true)
+sodium = dependency('libsodium', 'sodium', required : true, include_type : 'system')
-curl = dependency('libcurl', 'curl', required : true)
+curl = dependency('libcurl', 'curl', required : true, include_type : 'system')
-editline = dependency('libeditline', 'editline', version : '>=1.14', required : true)
+editline = dependency('libeditline', 'editline', version : '>=1.14', required : true, include_type : 'system')
-lowdown = dependency('lowdown', version : '>=0.9.0', required : true)
+lowdown = dependency('lowdown', version : '>=0.9.0', required : true, include_type : 'system')
# HACK(Qyriad): rapidcheck's pkg-config doesn't include the libs lol
# Note: technically we 'check' for rapidcheck twice, for the internal-api-docs handling above,
# but Meson will cache the result of the first one, and the required : arguments are different.
-rapidcheck_meson = dependency('rapidcheck', required : enable_tests)
+rapidcheck_meson = dependency('rapidcheck', required : enable_tests, include_type : 'system')
rapidcheck = declare_dependency(dependencies : rapidcheck_meson, link_args : ['-lrapidcheck'])
gtest = [
- dependency('gtest', required : enable_tests),
- dependency('gtest_main', required : enable_tests),
- dependency('gmock', required : enable_tests),
- dependency('gmock_main', required : enable_tests),
+ dependency('gtest', required : enable_tests, include_type : 'system'),
+ dependency('gtest_main', required : enable_tests, include_type : 'system'),
+ dependency('gmock', required : enable_tests, include_type : 'system'),
+ dependency('gmock_main', required : enable_tests, include_type : 'system'),
]
-toml11 = dependency('toml11', version : '>=3.7.0', required : true, method : 'cmake')
+toml11 = dependency('toml11', version : '>=3.7.0', required : true, method : 'cmake', include_type : 'system')
pegtl = dependency(
'pegtl',
@@ -307,9 +317,10 @@ pegtl = dependency(
required : true,
method : 'cmake',
modules : [ 'taocpp::pegtl' ],
+ include_type : 'system',
)
-nlohmann_json = dependency('nlohmann_json', required : true)
+nlohmann_json = dependency('nlohmann_json', required : true, include_type : 'system')
# lix-doc is a Rust project provided via buildInputs and unfortunately doesn't have any way to be detected.
# Just declare it manually to resolve this.
diff --git a/perl/configure.ac b/perl/configure.ac
deleted file mode 100644
index 493f0c85c..000000000
--- a/perl/configure.ac
+++ /dev/null
@@ -1,84 +0,0 @@
-AC_INIT(nix-perl, m4_esyscmd([bash -c "echo -n $(cat ../.version)$VERSION_SUFFIX"]))
-AC_CONFIG_SRCDIR(MANIFEST)
-AC_CONFIG_AUX_DIR(../config)
-
-CFLAGS=
-CXXFLAGS=
-AC_PROG_CC
-AC_PROG_CXX
-
-AC_CANONICAL_HOST
-
-# Use 64-bit file system calls so that we can support files > 2 GiB.
-AC_SYS_LARGEFILE
-
-AC_DEFUN([NEED_PROG],
-[
-AC_PATH_PROG($1, $2)
-if test -z "$$1"; then
- AC_MSG_ERROR([$2 is required])
-fi
-])
-
-NEED_PROG(perl, perl)
-NEED_PROG(curl, curl)
-NEED_PROG(bzip2, bzip2)
-NEED_PROG(xz, xz)
-
-# Test that Perl has the open/fork feature (Perl 5.8.0 and beyond).
-AC_MSG_CHECKING([whether Perl is recent enough])
-if ! $perl -e 'open(FOO, "-|", "true"); while () { print; }; close FOO or die;'; then
- AC_MSG_RESULT(no)
- AC_MSG_ERROR([Your Perl version is too old. Lix requires Perl 5.8.0 or newer.])
-fi
-AC_MSG_RESULT(yes)
-
-
-# Figure out where to install Perl modules.
-AC_MSG_CHECKING([for the Perl installation prefix])
-perlversion=$($perl -e 'use Config; print $Config{version};')
-perlarchname=$($perl -e 'use Config; print $Config{archname};')
-AC_SUBST(perllibdir, [${libdir}/perl5/site_perl/$perlversion/$perlarchname])
-AC_MSG_RESULT($perllibdir)
-
-# Look for libsodium.
-PKG_CHECK_MODULES([SODIUM], [libsodium], [CXXFLAGS="$SODIUM_CFLAGS $CXXFLAGS"])
-
-# Check for the required Perl dependencies (DBI and DBD::SQLite).
-perlFlags="-I$perllibdir"
-
-AC_ARG_WITH(dbi, AC_HELP_STRING([--with-dbi=PATH],
- [prefix of the Perl DBI library]),
- perlFlags="$perlFlags -I$withval")
-
-AC_ARG_WITH(dbd-sqlite, AC_HELP_STRING([--with-dbd-sqlite=PATH],
- [prefix of the Perl DBD::SQLite library]),
- perlFlags="$perlFlags -I$withval")
-
-AC_MSG_CHECKING([whether DBD::SQLite works])
-if ! $perl $perlFlags -e 'use DBI; use DBD::SQLite;' 2>&5; then
- AC_MSG_RESULT(no)
- AC_MSG_FAILURE([The Perl modules DBI and/or DBD::SQLite are missing.])
-fi
-AC_MSG_RESULT(yes)
-
-AC_SUBST(perlFlags)
-
-PKG_CHECK_MODULES([NIX], [nix-store])
-
-NEED_PROG([NIX], [nix])
-
-# Expand all variables in config.status.
-test "$prefix" = NONE && prefix=$ac_default_prefix
-test "$exec_prefix" = NONE && exec_prefix='${prefix}'
-for name in $ac_subst_vars; do
- declare $name="$(eval echo "${!name}")"
- declare $name="$(eval echo "${!name}")"
- declare $name="$(eval echo "${!name}")"
-done
-
-rm -f Makefile.config
-ln -sfn ../mk mk
-
-AC_CONFIG_FILES([])
-AC_OUTPUT
diff --git a/src/libstore/platform/darwin.cc b/src/libstore/platform/darwin.cc
index 1b591fde3..1f7e9be23 100644
--- a/src/libstore/platform/darwin.cc
+++ b/src/libstore/platform/darwin.cc
@@ -56,12 +56,27 @@ void DarwinLocalStore::findPlatformRoots(UncheckedRoots & unchecked)
while (fdBufSize > fds.size() * sizeof(struct proc_fdinfo)) {
// Reserve some extra size so we don't fail too much
fds.resize((fdBufSize + fdBufSize / 8) / sizeof(struct proc_fdinfo));
+ errno = 0;
fdBufSize = proc_pidinfo(
pid, PROC_PIDLISTFDS, 0, fds.data(), fds.size() * sizeof(struct proc_fdinfo)
);
+ // errno == 0???! Yes, seriously. This is because macOS has a
+ // broken syscall wrapper for proc_pidinfo that has no way of
+ // dealing with the system call successfully returning 0. It
+ // takes the -1 error result from the errno-setting syscall
+ // wrapper and turns it into a 0 result. But what if the system
+ // call actually returns 0? Then you get an errno of success.
+ //
+ // https://github.com/apple-opensource/xnu/blob/4f43d4276fc6a87f2461a3ab18287e4a2e5a1cc0/libsyscall/wrappers/libproc/libproc.c#L100-L110
+ // https://git.lix.systems/lix-project/lix/issues/446#issuecomment-5483
+ // FB14695751
if (fdBufSize <= 0) {
- throw SysError("Listing pid %1% file descriptors", pid);
+ if (errno == 0) {
+ break;
+ } else {
+ throw SysError("Listing pid %1% file descriptors", pid);
+ }
}
}
fds.resize(fdBufSize / sizeof(struct proc_fdinfo));