Skip to content

Instantly share code, notes, and snippets.

@k-takata
Created December 27, 2022 09:24
Show Gist options
  • Save k-takata/7d8fe31ad8eaef3e933f3fbd83d78a00 to your computer and use it in GitHub Desktop.
Save k-takata/7d8fe31ad8eaef3e933f3fbd83d78a00 to your computer and use it in GitHub Desktop.
Similar patch to 8.2.4317 for Linux
diff --git a/src/errors.h b/src/errors.h
index e33f2e66b..c23aac526 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -3213,7 +3213,7 @@ EXTERN char e_autoload_import_cannot_use_absolute_or_relative_path[]
EXTERN char e_cannot_use_partial_here[]
INIT(= N_("E1265: Cannot use a partial here"));
#endif
-#if defined(FEAT_PYTHON3) && defined(MSWIN)
+#if defined(FEAT_PYTHON3) && (defined(MSWIN) || defined(__linux__))
EXTERN char e_critical_error_in_python3_initialization_check_your_installation[]
INIT(= N_("E1266: Critical error in python3 initialization, check your python3 installation"));
#endif
diff --git a/src/if_python3.c b/src/if_python3.c
index 30332e166..03e65b987 100644
--- a/src/if_python3.c
+++ b/src/if_python3.c
@@ -29,6 +29,9 @@
// allocator
// #define Py_DEBUG_NO_PYMALLOC
+#ifdef __linux__
+# define _GNU_SOURCE
+#endif
#include "vim.h"
#include <limits.h>
@@ -122,6 +125,9 @@ typedef PySliceObject PySliceObject_T;
#ifndef MSWIN
# define HINSTANCE void *
+# if defined(DYNAMIC_PYTHON3) || defined(__linux__)
+# include <dlfcn.h>
+# endif
#endif
#if defined(DYNAMIC_PYTHON3) || defined(MSWIN)
static HINSTANCE hinstPy3 = 0; // Instance of python.dll
@@ -130,7 +136,6 @@ static HINSTANCE hinstPy3 = 0; // Instance of python.dll
#if defined(DYNAMIC_PYTHON3) || defined(PROTO)
# ifndef MSWIN
-# include <dlfcn.h>
# define FARPROC void*
# if defined(PY_NO_RTLD_GLOBAL) && defined(PY3_NO_RTLD_GLOBAL)
# define load_dll(n) dlopen((n), RTLD_LAZY)
@@ -1078,9 +1083,10 @@ reset_stdin(void)
// Python 3.2 or later will abort inside Py_Initialize() when mandatory
// modules cannot be loaded (e.g. 'pythonthreehome' is wrongly set.).
// Install a hook to python dll's exit() and recover from it.
-#if defined(MSWIN) && (PY_VERSION_HEX >= 0x030200f0)
-# define HOOK_EXIT
-# include <setjmp.h>
+#if PY_VERSION_HEX >= 0x030200f0
+# ifdef MSWIN
+# define HOOK_EXIT
+# include <setjmp.h>
static jmp_buf exit_hook_jump_buf;
static void *orig_exit = NULL;
@@ -1124,6 +1130,52 @@ restore_py_exit(void)
hook_dll_import_func(hinst, "exit", orig_exit);
orig_exit = NULL;
}
+# elif defined(__linux__)
+# define HOOK_EXIT
+# include <setjmp.h>
+
+static jmp_buf exit_hook_jump_buf;
+static int hooked = FALSE;
+static void (*orig_exit)(int) __attribute__((noreturn)) = NULL;
+
+/*
+ * Function that replaces exit() while calling Py_Initialize().
+ */
+ void
+exit(int ret)
+{
+ if (orig_exit == NULL)
+ orig_exit = dlsym(RTLD_NEXT, "exit");
+
+ if (hooked)
+ {
+ // Recover from exit.
+ longjmp(exit_hook_jump_buf, 1);
+ }
+ else
+ {
+ orig_exit(ret);
+ }
+}
+
+/*
+ * Start hooking exit().
+ */
+ static void
+hook_py_exit(void)
+{
+ hooked = TRUE;
+}
+
+/*
+ * End hooking exit().
+ */
+ static void
+restore_py_exit(void)
+{
+ hooked = FALSE;
+}
+# endif
#endif
static int
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment