pkgsrc-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[pkgsrc/trunk]: pkgsrc/pkgtools/pkg_install/files/lib pkg_install: Switch to ...



details:   https://anonhg.NetBSD.org/pkgsrc/rev/34a6b22fcd8f
branches:  trunk
changeset: 769436:34a6b22fcd8f
user:      jperkin <jperkin%pkgsrc.org@localhost>
date:      Mon Nov 15 12:48:23 2021 +0000

description:
pkg_install: Switch to posix_spawn() on newer macOS.

vfork() no longer works on Monterey and causes serious intermittent issues
when upgrading pkg_install.  Forking the INSTALL and DEINSTALL scripts can
sometimes fail, due to the underlying pkg_add/pkg_delete binaries having
been changed or removed, leaving the system broken with no package tools.

The manual page suggests using posix_spawn() instead and that appears to
work correctly.  The code has been laid out so that it's easy enough to
switch other platforms to posix_spawn() too if required, or for improved
performance, and has been verified to work successfully on SmartOS.

Bump pkg_install version to 20211115.

diffstat:

 pkgtools/pkg_install/files/lib/fexec.c   |  67 +++++++++++++++++++++++++++++++-
 pkgtools/pkg_install/files/lib/version.h |   4 +-
 2 files changed, 67 insertions(+), 4 deletions(-)

diffs (133 lines):

diff -r 668ab5e44722 -r 34a6b22fcd8f pkgtools/pkg_install/files/lib/fexec.c
--- a/pkgtools/pkg_install/files/lib/fexec.c    Mon Nov 15 12:27:47 2021 +0000
+++ b/pkgtools/pkg_install/files/lib/fexec.c    Mon Nov 15 12:48:23 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fexec.c,v 1.12 2009/08/02 17:56:45 joerg Exp $ */
+/*     $NetBSD: fexec.c,v 1.13 2021/11/15 12:48:23 jperkin Exp $       */
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -37,6 +37,12 @@
 #if HAVE_SYS_CDEFS_H
 #include <sys/cdefs.h>
 #endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
 #if HAVE_SYS_WAIT_H
 #include <sys/wait.h>
 #endif
@@ -47,6 +53,9 @@
 #if HAVE_ERRNO_H
 #include <errno.h>
 #endif
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
 #if HAVE_STDARG_H
 #include <stdarg.h>
 #endif
@@ -59,7 +68,33 @@
 
 #include "lib.h"
 
-__RCSID("$NetBSD: fexec.c,v 1.12 2009/08/02 17:56:45 joerg Exp $");
+/*
+ * Newer macOS releases are not able to correctly handle vfork() when the
+ * underlying file is changed or removed, as is the case when upgrading
+ * pkg_install itself.  The manual pages suggest using posix_spawn()
+ * instead, which seems to work ok.
+ */
+#if defined(__APPLE__) && \
+       ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) >= 1050)
+#define FEXEC_USE_POSIX_SPAWN  1
+#else
+#define FEXEC_USE_POSIX_SPAWN  0
+#endif
+
+#if FEXEC_USE_POSIX_SPAWN
+#include <spawn.h>
+extern char **environ;
+
+#ifndef O_CLOEXEC
+#define O_CLOEXEC      0
+#endif
+
+#ifndef O_DIRECTORY
+#define O_DIRECTORY    0
+#endif
+#endif
+
+__RCSID("$NetBSD: fexec.c,v 1.13 2021/11/15 12:48:23 jperkin Exp $");
 
 static int     vfcexec(const char *, int, const char *, va_list);
 
@@ -67,6 +102,8 @@
  * fork, then change current working directory to path and
  * execute the command and arguments in the argv array.
  * wait for the command to finish, then return the exit status.
+ *
+ * macOS uses posix_spawn() instead due to reasons explained above.
  */
 int
 pfcexec(const char *path, const char *file, const char **argv)
@@ -74,6 +111,31 @@
        pid_t                   child;
        int                     status;
 
+#if FEXEC_USE_POSIX_SPAWN
+       int prevcwd;
+
+       if ((prevcwd = open(".", O_RDONLY|O_CLOEXEC|O_DIRECTORY)) < 0) {
+               warn("open prevcwd failed");
+               return -1;
+       }
+
+       if ((path != NULL) && (chdir(path) < 0)) {
+               warn("chdir %s failed", path);
+               return -1;
+       }
+
+       if (posix_spawn(&child, file, NULL, NULL, (char **)argv, environ) < 0) {
+               warn("posix_spawn failed");
+               return -1;
+       }
+
+       if (fchdir(prevcwd) < 0) {
+               warn("fchdir prevcwd failed");
+               return -1;
+       }
+
+       (void)close(prevcwd);
+#else
        child = vfork();
        switch (child) {
        case 0:
@@ -86,6 +148,7 @@
        case -1:
                return -1;
        }
+#endif
 
        while (waitpid(child, &status, 0) < 0) {
                if (errno != EINTR)
diff -r 668ab5e44722 -r 34a6b22fcd8f pkgtools/pkg_install/files/lib/version.h
--- a/pkgtools/pkg_install/files/lib/version.h  Mon Nov 15 12:27:47 2021 +0000
+++ b/pkgtools/pkg_install/files/lib/version.h  Mon Nov 15 12:48:23 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: version.h,v 1.188 2021/10/21 13:05:25 jperkin Exp $    */
+/*     $NetBSD: version.h,v 1.189 2021/11/15 12:48:23 jperkin Exp $    */
 
 /*
  * Copyright (c) 2001 Thomas Klausner.  All rights reserved.
@@ -27,6 +27,6 @@
 #ifndef _INST_LIB_VERSION_H_
 #define _INST_LIB_VERSION_H_
 
-#define PKGTOOLS_VERSION 20211021
+#define PKGTOOLS_VERSION 20211115
 
 #endif /* _INST_LIB_VERSION_H_ */



Home | Main Index | Thread Index | Old Index