Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package uwsgi for openSUSE:Factory checked 
in at 2023-01-08 21:25:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/uwsgi (Old)
 and      /work/SRC/openSUSE:Factory/.uwsgi.new.1563 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "uwsgi"

Sun Jan  8 21:25:12 2023 rev:48 rq:1056813 version:2.0.21

Changes:
--------
--- /work/SRC/openSUSE:Factory/uwsgi/uwsgi.changes      2022-12-19 
14:07:55.262557671 +0100
+++ /work/SRC/openSUSE:Factory/.uwsgi.new.1563/uwsgi.changes    2023-01-08 
21:25:14.523141076 +0100
@@ -1,0 +2,18 @@
+Fri Jan  6 20:36:08 UTC 2023 - Dirk Müller <dmuel...@suse.com>
+
+- update to 2.0.21:
+  * Python 3.10 support
+  * Python 3.11 support
+  * add tests for worker deadlocks
+  * fix memory corruption in uwsgi_cache
+  * Fix segfault from GEVENT_SWITCH
+  * Support php 8.1
+  * Use parenthesis in print() statement 
+
+-------------------------------------------------------------------
+Tue Dec 13 19:44:00 UTC 2022 - s...@uebelacker.net
+
+- fixing uwsgi-php[78] package description
+- rpmlint: removing obsolete specfile condition for python which is included 
in python-rpm-macros
+
+-------------------------------------------------------------------

Old:
----
  uwsgi-2.0.20.tar.gz

New:
----
  2.0.21.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ uwsgi.spec ++++++
--- /var/tmp/diff_new_pack.NOkjsw/_old  2023-01-08 21:25:16.019149963 +0100
+++ /var/tmp/diff_new_pack.NOkjsw/_new  2023-01-08 21:25:16.023149987 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package uwsgi
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -27,15 +27,14 @@
 %define with_php 0
 %endif
 
-%{?!python_module:%define python_module() python3-%{**}}
 Name:           uwsgi
-Version:        2.0.20
+Version:        2.0.21
 Release:        0
 Summary:        Application Container Server for Networked/Clustered Web 
Applications
 License:        Apache-2.0 AND GPL-2.0-only WITH GCC-exception-2.0
 Group:          Productivity/Networking/Web/Servers
 URL:            https://uwsgi-docs.readthedocs.io/en/latest/
-Source:         https://projects.unbit.it/downloads/uwsgi-%{version}.tar.gz
+Source:         
https://github.com/unbit/uwsgi/archive/refs/tags/%{version}.tar.gz
 Source1:        opensuse.ini.in
 Source2:        uwsgi.service
 Source3:        django.ini.example
@@ -420,7 +419,11 @@
 
 %if %{with_php}
 %package %{php}
+%if 0%{?suse_version} >= 1550
+Summary:        PHP8 Plugin for uWSGI
+%else
 Summary:        PHP7 Plugin for uWSGI
+%endif
 Group:          Productivity/Networking/Web/Servers
 Requires:       %{name} = %{version}
 Requires:       %{php}-embed
@@ -428,8 +431,12 @@
 %description %{php}
 uWSGI is a self-healing application container server coded in pure C.
 
+%if 0%{?suse_version} >= 1550
+This package contains support for PHP version 8.
+%else
 This package contains support for PHP version 7.
 %endif
+%endif
 
 %prep
 %setup -q -n uwsgi-%{version}

++++++ uwsgi-2.0.20.tar.gz -> 2.0.21.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/.github/workflows/test.yml 
new/uwsgi-2.0.21/.github/workflows/test.yml
--- old/uwsgi-2.0.20/.github/workflows/test.yml 2021-10-06 07:22:45.000000000 
+0200
+++ new/uwsgi-2.0.21/.github/workflows/test.yml 2022-10-24 12:21:58.000000000 
+0200
@@ -7,10 +7,13 @@
     branches: [ master, uwsgi-2.0 ]
 
 jobs:
-  build:
+  python:
 
     runs-on: ubuntu-18.04
-
+    strategy:
+      matrix:
+        python-version: ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11"]
+        test-suite: [unittest, python, deadlocks]
     steps:
     - name: Add deadnakes ppa
       run: |
@@ -19,39 +22,60 @@
     - name: Install dependencies
       run: |
         sudo apt update -qq
-        sudo apt install --no-install-recommends -qqyf 
python{2.7,3.5,3.6,3.7,3.8}-dev \
-          python3.8-distutils \
+        sudo apt install --no-install-recommends -qqyf python${{ 
matrix.python-version }}-dev \
           libpcre3-dev libjansson-dev libcap2-dev \
           curl check
+    - name: Install distutils
+      if: contains(fromJson('["3.8","3.9","3.10","3.11"]'), 
matrix.python-version)
+      run: |
+        sudo apt install --no-install-recommends -qqyf python${{ 
matrix.python-version }}-distutils \
     - uses: actions/checkout@v2
     - name: Run unit tests
+      if: matrix.test-suite == 'unittest'
       run: make tests
     - name: Build uWSGI binary
+      if: matrix.test-suite != 'unittest'
       run: make
-    - name: Build python2.7 plugin
+    - name: Build python${{ matrix.python-version }} plugin
+      if: matrix.test-suite != 'unittest'
       run: |
-        /usr/bin/python2.7 -V
-        /usr/bin/python2.7 uwsgiconfig.py --plugin plugins/python base python27
-    - name: Build python3.5 plugin
-      run: |
-        /usr/bin/python3.5 -V
-        /usr/bin/python3.5 uwsgiconfig.py --plugin plugins/python base python35
-    - name: Build python3.6 plugin
-      run: |
-        /usr/bin/python3.6 -V
-        /usr/bin/python3.6 uwsgiconfig.py --plugin plugins/python base python36
-    - name: Build python3.7 plugin
-      run: |
-        /usr/bin/python3.7 -V
-        /usr/bin/python3.7 uwsgiconfig.py --plugin plugins/python base python37
-    - name: Build python3.8 plugin
+        PYTHON_VERSION=${{ matrix.python-version }}
+        PYTHON_VERSION=python${PYTHON_VERSION//.}
+        /usr/bin/python${{ matrix.python-version }} -V
+        /usr/bin/python${{ matrix.python-version }} uwsgiconfig.py --plugin 
plugins/python base $PYTHON_VERSION
+    - name: run smoke tests
+      if: matrix.test-suite != 'unittest'
+      run: |
+        PYTHON_VERSION=${{ matrix.python-version }}
+        PYTHON_VERSION=python${PYTHON_VERSION//.}
+        ./tests/gh-${{ matrix.test-suite }}.sh ${PYTHON_VERSION}
+
+  rack:
+
+    runs-on: ubuntu-18.04
+    strategy:
+      matrix:
+        rack-version: ["251"]
+    steps:
+    - name: Add deadnakes ppa
       run: |
-        /usr/bin/python3.8 -V
-        /usr/bin/python3.8 uwsgiconfig.py --plugin plugins/python base python38
+        sudo apt install -qqyf software-properties-common
+        sudo add-apt-repository ppa:deadsnakes/ppa -y
+    - name: Install dependencies
+      run: |
+        sudo apt update -qq
+        sudo apt install --no-install-recommends -qqyf python3-dev \
+          libpcre3-dev libjansson-dev libcap2-dev \
+          curl check
+    - uses: actions/checkout@v2
+    - name: Run unit tests
+      run: make tests
+    - name: Build uWSGI binary
+      run: make
     - name: Build rack plugin
       run: |
         ruby -v
-        UWSGICONFIG_RUBYPATH=ruby /usr/bin/python uwsgiconfig.py --plugin 
plugins/rack base rack251
-    - name: Run smoke tests
+        UWSGICONFIG_RUBYPATH=ruby /usr/bin/python uwsgiconfig.py --plugin 
plugins/rack base rack${{ matrix.rack-version }}
+    - name: run smoke tests
       run: |
-        ./tests/travis.sh .github/workflows/test.yml
+        ./tests/gh-rack.sh rack${{ matrix.rack-version}}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/PKG-INFO new/uwsgi-2.0.21/PKG-INFO
--- old/uwsgi-2.0.20/PKG-INFO   2021-10-06 07:22:45.000000000 +0200
+++ new/uwsgi-2.0.21/PKG-INFO   2022-10-24 12:21:58.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: uWSGI
-Version: 2.0.20
+Version: 2.0.21
 Summary: The uWSGI server
 Home-page: https://uwsgi-docs.readthedocs.io/en/latest/
 Author: Unbit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/README new/uwsgi-2.0.21/README
--- old/uwsgi-2.0.20/README     2021-10-06 07:22:45.000000000 +0200
+++ new/uwsgi-2.0.21/README     2022-10-24 12:21:58.000000000 +0200
@@ -1,5 +1,13 @@
 The uWSGI project
 
-For official documentation check: https://uwsgi-docs.readthedocs.org/en/latest/
+For official documentation check: https://uwsgi-docs.readthedocs.io/en/latest/
 
-For commercial support check: http://unbit.com/
+Note: The project is in maintenance mode (only bugfixes and updates for new 
languages apis)
+
+uWSGI development has been sponsored by:
+
+http://unbit.com
+https://www.pythonanywhere.com/
+https://lincolnloop.com/
+https://yourlabs.io/oss
+https://fili.com
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/core/master_utils.c 
new/uwsgi-2.0.21/core/master_utils.c
--- old/uwsgi-2.0.20/core/master_utils.c        2021-10-06 07:22:45.000000000 
+0200
+++ new/uwsgi-2.0.21/core/master_utils.c        2022-10-24 12:21:58.000000000 
+0200
@@ -692,9 +692,22 @@
                pthread_mutex_lock(&uwsgi.threaded_logger_lock);
        }
 
+
+       for (i = 0; i < 256; i++) {
+               if (uwsgi.p[i]->pre_uwsgi_fork) {
+                       uwsgi.p[i]->pre_uwsgi_fork();
+               }
+       }
+
        pid_t pid = uwsgi_fork(uwsgi.workers[wid].name);
 
        if (pid == 0) {
+               for (i = 0; i < 256; i++) {
+                       if (uwsgi.p[i]->post_uwsgi_fork) {
+                               uwsgi.p[i]->post_uwsgi_fork(1);
+                       }
+               }
+
                signal(SIGWINCH, worker_wakeup);
                signal(SIGTSTP, worker_wakeup);
                uwsgi.mywid = wid;
@@ -753,6 +766,12 @@
                uwsgi_error("fork()");
        }
        else {
+               for (i = 0; i < 256; i++) {
+                       if (uwsgi.p[i]->post_uwsgi_fork) {
+                               uwsgi.p[i]->post_uwsgi_fork(0);
+                       }
+               }
+
                // the pid is set only in the master, as the worker should 
never use it
                uwsgi.workers[wid].pid = pid;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/core/metrics.c 
new/uwsgi-2.0.21/core/metrics.c
--- old/uwsgi-2.0.20/core/metrics.c     2021-10-06 07:22:45.000000000 +0200
+++ new/uwsgi-2.0.21/core/metrics.c     2022-10-24 12:21:58.000000000 +0200
@@ -703,16 +703,16 @@
 
 int uwsgi_metric_set_max(char *name, char *oid, int64_t value) {
        um_op;
-    if (value > *um->value)
-        *um->value = value;
+       if (value > *um->value)
+               *um->value = value;
        uwsgi_rwunlock(uwsgi.metrics_lock);
        return 0;
 }
 
 int uwsgi_metric_set_min(char *name, char *oid, int64_t value) {
        um_op;
-    if ((value > um->initial_value || 0) && value < *um->value)
-        *um->value = value;
+       if ((value > um->initial_value || 0) && value < *um->value)
+               *um->value = value;
        uwsgi_rwunlock(uwsgi.metrics_lock);
        return 0;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/core/mount.c 
new/uwsgi-2.0.21/core/mount.c
--- old/uwsgi-2.0.20/core/mount.c       2021-10-06 07:22:45.000000000 +0200
+++ new/uwsgi-2.0.21/core/mount.c       2022-10-24 12:21:58.000000000 +0200
@@ -106,6 +106,7 @@
 }
 
 int uwsgi_mount(char *fs, char *what, char *where, char *flags, char *data) {
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__GNU_kFreeBSD__)
 #if defined(__FreeBSD__) || defined(__GNU_kFreeBSD__)
        struct iovec iov[6];
 #endif
@@ -143,10 +144,12 @@
 
        return nmount(iov, 6, (int) mountflags);
 #endif
+#endif
        return -1;
 }
 
 int uwsgi_umount(char *where, char *flags) {
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__GNU_kFreeBSD__)
        unsigned long mountflags = 0;
         if (!flags) goto parsed;
         char *mflags = uwsgi_str(flags);
@@ -196,6 +199,7 @@
 #elif defined(__FreeBSD__) || defined(__GNU_kFreeBSD__)
        return unmount(where, mountflags);
 #endif
+#endif
         return -1;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/core/utils.c 
new/uwsgi-2.0.21/core/utils.c
--- old/uwsgi-2.0.20/core/utils.c       2021-10-06 07:22:45.000000000 +0200
+++ new/uwsgi-2.0.21/core/utils.c       2022-10-24 12:21:58.000000000 +0200
@@ -3671,6 +3671,7 @@
 
 
 void uwsgi_set_cpu_affinity() {
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__GNU_kFreeBSD__)
        char buf[4096];
        int ret;
        int pos = 0;
@@ -3690,7 +3691,6 @@
 #elif defined(__FreeBSD__)
                cpuset_t cpuset;
 #endif
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__GNU_kFreeBSD__)
                CPU_ZERO(&cpuset);
                int i;
                for (i = 0; i < uwsgi.cpu_affinity; i++) {
@@ -3705,7 +3705,6 @@
                        pos += ret;
                        base_cpu++;
                }
-#endif
 #if defined(__linux__) || defined(__GNU_kFreeBSD__)
                if (sched_setaffinity(0, sizeof(cpu_set_t), &cpuset)) {
                        uwsgi_error("sched_setaffinity()");
@@ -3717,7 +3716,7 @@
 #endif
                uwsgi_log("%s\n", buf);
        }
-
+#endif
 }
 
 #ifdef UWSGI_ELF
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/plugins/coroae/uwsgiplugin.py 
new/uwsgi-2.0.21/plugins/coroae/uwsgiplugin.py
--- old/uwsgi-2.0.20/plugins/coroae/uwsgiplugin.py      2021-10-06 
07:22:45.000000000 +0200
+++ new/uwsgi-2.0.21/plugins/coroae/uwsgiplugin.py      2022-10-24 
12:21:58.000000000 +0200
@@ -9,7 +9,7 @@
         coroapi = p
 
 if not coroapi:
-    print "unable to find the Coro perl module !!!"
+    print("unable to find the Coro perl module !!!")
     sys.exit(1)
 
 NAME='coroae'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/plugins/gccgo/uwsgiplugin.py 
new/uwsgi-2.0.21/plugins/gccgo/uwsgiplugin.py
--- old/uwsgi-2.0.20/plugins/gccgo/uwsgiplugin.py       2021-10-06 
07:22:45.000000000 +0200
+++ new/uwsgi-2.0.21/plugins/gccgo/uwsgiplugin.py       2022-10-24 
12:21:58.000000000 +0200
@@ -1,5 +1,7 @@
 import os
-NAME='gccgo'
+import subprocess
+
+NAME = 'gccgo'
 
 CFLAGS = ['-g']
 LDFLAGS = []
@@ -8,6 +10,6 @@
 
 def post_build(config):
     if os.path.exists('plugins/gccgo/uwsgi.go.o'):
-        if os.system("objcopy -j .go_export plugins/gccgo/uwsgi.go.o 
plugins/gccgo/uwsgi.gox") != 0:
+        if subprocess.call("objcopy -j .go_export plugins/gccgo/uwsgi.go.o 
plugins/gccgo/uwsgi.gox", shell=True) != 0:
             os._exit(1)
         print("*** uwsgi.gox available in %s/plugins/gccgo ***" % os.getcwd())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/plugins/gevent/gevent.h 
new/uwsgi-2.0.21/plugins/gevent/gevent.h
--- old/uwsgi-2.0.20/plugins/gevent/gevent.h    2021-10-06 07:22:45.000000000 
+0200
+++ new/uwsgi-2.0.21/plugins/gevent/gevent.h    2022-10-24 12:21:58.000000000 
+0200
@@ -4,7 +4,7 @@
 int uwsgi_gevent_wait_read_hook(int, int);
 int uwsgi_gevent_wait_milliseconds_hook(int);
 
-#define GEVENT_SWITCH PyObject *gswitch = python_call(ugevent.greenlet_switch, 
ugevent.greenlet_switch_args, 0, NULL); Py_DECREF(gswitch)
+#define GEVENT_SWITCH PyObject *gswitch = python_call(ugevent.greenlet_switch, 
ugevent.greenlet_switch_args, 0, NULL); if (gswitch) { Py_DECREF(gswitch); }
 #define GET_CURRENT_GREENLET python_call(ugevent.get_current, 
ugevent.get_current_args, 0, NULL)
 #define free_req_queue uwsgi.async_queue_unused_ptr++; 
uwsgi.async_queue_unused[uwsgi.async_queue_unused_ptr] = wsgi_req
 #define stop_the_watchers if (timer) { ret = PyObject_CallMethod(timer, 
"stop", NULL);\
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/plugins/jvm/uwsgiplugin.py 
new/uwsgi-2.0.21/plugins/jvm/uwsgiplugin.py
--- old/uwsgi-2.0.20/plugins/jvm/uwsgiplugin.py 2021-10-06 07:22:45.000000000 
+0200
+++ new/uwsgi-2.0.21/plugins/jvm/uwsgiplugin.py 2022-10-24 12:21:58.000000000 
+0200
@@ -1,5 +1,6 @@
 import os
 import shutil
+import subprocess
 
 NAME='jvm'
 
@@ -71,9 +72,9 @@
     os.environ['LD_RUN_PATH'] = JVM_LIBPATH[0][2:]
 
 def post_build(config):
-    if os.system("javac %s/plugins/jvm/uwsgi.java" % os.getcwd()) != 0:
+    if subprocess.call("javac %s/plugins/jvm/uwsgi.java" % os.getcwd(), 
shell=True) != 0:
         os._exit(1)
-    if os.system("cd %s/plugins/jvm ; jar cvf uwsgi.jar *.class" % 
os.getcwd()) != 0:
+    if subprocess.call("cd %s/plugins/jvm ; jar cvf uwsgi.jar *.class" % 
os.getcwd(), shell=True) != 0:
         os._exit(1)
     print("*** uwsgi.jar available in %s/plugins/jvm/uwsgi.jar ***" % 
os.getcwd())
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/plugins/mono/uwsgiplugin.py 
new/uwsgi-2.0.21/plugins/mono/uwsgiplugin.py
--- old/uwsgi-2.0.20/plugins/mono/uwsgiplugin.py        2021-10-06 
07:22:45.000000000 +0200
+++ new/uwsgi-2.0.21/plugins/mono/uwsgiplugin.py        2022-10-24 
12:21:58.000000000 +0200
@@ -1,5 +1,7 @@
 import os
-NAME='mono'
+import subprocess
+
+NAME = 'mono'
 
 CFLAGS = os.popen('pkg-config --cflags mono-2').read().rstrip().split()
 LDFLAGS = []
@@ -7,11 +9,11 @@
 GCC_LIST = ['mono_plugin']
 
 if os.uname()[0] == 'Darwin':
-       LIBS.append('-framework Foundation')
+    LIBS.append('-framework Foundation')
 
 def post_build(config):
-    if os.system("sn -k plugins/mono/uwsgi.key") != 0:
+    if subprocess.call("sn -k plugins/mono/uwsgi.key", shell=True) != 0:
         os._exit(1)
-    if os.system("mcs /target:library /r:System.Web.dll 
/keyfile:plugins/mono/uwsgi.key plugins/mono/uwsgi.cs") != 0:
+    if subprocess.call("mcs /target:library /r:System.Web.dll 
/keyfile:plugins/mono/uwsgi.key plugins/mono/uwsgi.cs", shell=True) != 0:
         os._exit(1)
     print("*** uwsgi.dll available in %s/plugins/mono/uwsgi.dll ***" % 
os.getcwd())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/plugins/php/php_plugin.c 
new/uwsgi-2.0.21/plugins/php/php_plugin.c
--- old/uwsgi-2.0.20/plugins/php/php_plugin.c   2021-10-06 07:22:45.000000000 
+0200
+++ new/uwsgi-2.0.21/plugins/php/php_plugin.c   2022-10-24 12:21:58.000000000 
+0200
@@ -275,9 +275,9 @@
 PHP_FUNCTION(uwsgi_cache_exists) {
 
         char *key = NULL;
-        int keylen = 0;
+        php_strlen_size keylen = 0;
         char *cache = NULL;
-        int cachelen = 0;
+        php_strlen_size cachelen = 0;
 
         if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|s", &key, &keylen, 
&cache, &cachelen) == FAILURE) {
                 RETURN_NULL();
@@ -293,7 +293,7 @@
 PHP_FUNCTION(uwsgi_cache_clear) {
 
         char *cache = NULL;
-        int cachelen = 0;
+        php_strlen_size cachelen = 0;
 
         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s", &cache, &cachelen) == 
FAILURE) {
                 RETURN_NULL();
@@ -308,11 +308,11 @@
 
 
 PHP_FUNCTION(uwsgi_cache_del) {
-       
+
        char *key = NULL;
-        int keylen = 0;
+       php_strlen_size keylen = 0;
        char *cache = NULL;
-       int cachelen = 0;
+       php_strlen_size cachelen = 0;
 
         if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|s", &key, &keylen, 
&cache, &cachelen) == FAILURE) {
                 RETURN_NULL();
@@ -328,9 +328,9 @@
 PHP_FUNCTION(uwsgi_cache_get) {
 
        char *key = NULL;
-       int keylen = 0;
+       php_strlen_size keylen = 0;
        char *cache = NULL;
-       int cachelen = 0;
+       php_strlen_size cachelen = 0;
        uint64_t valsize;
 
        if (!uwsgi.caches)
@@ -351,12 +351,12 @@
 
 PHP_FUNCTION(uwsgi_cache_set) {
        char *key = NULL;       
-       int keylen;
+       php_strlen_size keylen = 0;
        char *value = NULL;
-       int vallen;
-       uint64_t expires = 0;
+       php_strlen_size vallen = 0;
+       php_long_size expires = 0;
        char *cache = NULL;
-       int cachelen = 0;
+       php_strlen_size cachelen = 0;
 
        if (!uwsgi.caches)
                RETURN_NULL();
@@ -374,12 +374,12 @@
 
 PHP_FUNCTION(uwsgi_cache_update) {
         char *key = NULL;
-        int keylen;
+        php_strlen_size keylen = 0;
         char *value = NULL;
-        int vallen;
-        uint64_t expires = 0;
+        php_strlen_size vallen = 0;
+        php_long_size expires = 0;
         char *cache = NULL;
-        int cachelen = 0;
+        php_strlen_size cachelen = 0;
 
         if (!uwsgi.caches)
                 RETURN_NULL();
@@ -487,21 +487,24 @@
         RETURN_NULL();
 }
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_void, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
 zend_function_entry uwsgi_php_functions[] = {
-       PHP_FE(uwsgi_version,   NULL)
-       PHP_FE(uwsgi_setprocname,   NULL)
-       PHP_FE(uwsgi_worker_id,   NULL)
-       PHP_FE(uwsgi_masterpid,   NULL)
-       PHP_FE(uwsgi_signal,   NULL)
-
-       PHP_FE(uwsgi_rpc,   NULL)
-
-       PHP_FE(uwsgi_cache_get,   NULL)
-       PHP_FE(uwsgi_cache_set,   NULL)
-       PHP_FE(uwsgi_cache_update,   NULL)
-       PHP_FE(uwsgi_cache_del,   NULL)
-       PHP_FE(uwsgi_cache_clear,   NULL)
-       PHP_FE(uwsgi_cache_exists,   NULL)
+       PHP_FE(uwsgi_version, arginfo_void)
+       PHP_FE(uwsgi_setprocname, arginfo_void)
+       PHP_FE(uwsgi_worker_id, arginfo_void)
+       PHP_FE(uwsgi_masterpid, arginfo_void)
+       PHP_FE(uwsgi_signal, arginfo_void)
+
+       PHP_FE(uwsgi_rpc, arginfo_void)
+
+       PHP_FE(uwsgi_cache_get, arginfo_void)
+       PHP_FE(uwsgi_cache_set, arginfo_void)
+       PHP_FE(uwsgi_cache_update, arginfo_void)
+       PHP_FE(uwsgi_cache_del, arginfo_void)
+       PHP_FE(uwsgi_cache_clear, arginfo_void)
+       PHP_FE(uwsgi_cache_exists, arginfo_void)
        { NULL, NULL, NULL},
 };
 
@@ -814,6 +817,7 @@
 #endif
 
                strcpy(real_filename, uphp.app);        
+               real_filename_len = strlen(real_filename);
                if (wsgi_req->path_info_len == 1 && wsgi_req->path_info[0] == 
'/') {
                        goto appready;
                }
@@ -1041,14 +1045,19 @@
 
        SG(request_info).path_translated = wsgi_req->file;
 
-        memset(&file_handle, 0, sizeof(zend_file_handle));
-        file_handle.type = ZEND_HANDLE_FILENAME;
-        file_handle.filename = real_filename;
+#if PHP_VERSION_ID >= 80100
+       zend_string *handle_filename = zend_string_init(real_filename, 
real_filename_len, 0);
+#else
+       const char *handle_filename = real_filename;
+#endif
+       memset(&file_handle, 0, sizeof(zend_file_handle));
+       file_handle.type = ZEND_HANDLE_FILENAME;
+       file_handle.filename = handle_filename;
 
-        if (php_request_startup() == FAILURE) {
+       if (php_request_startup() == FAILURE) {
                uwsgi_500(wsgi_req);
-                return -1;
-        }
+               return -1;
+       }
 
        struct uwsgi_string_list *usl=NULL;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/plugins/python/profiler.c 
new/uwsgi-2.0.21/plugins/python/profiler.c
--- old/uwsgi-2.0.20/plugins/python/profiler.c  2021-10-06 07:22:45.000000000 
+0200
+++ new/uwsgi-2.0.21/plugins/python/profiler.c  2022-10-24 12:21:58.000000000 
+0200
@@ -13,6 +13,14 @@
 }
 #endif
 
+#if PY_VERSION_HEX < 0x030900B1
+PyCodeObject* PyFrame_GetCode(PyFrameObject *frame)
+{
+       Py_INCREF(frame->f_code);
+       return frame->f_code;
+}
+#endif
+
 #ifdef PYTHREE
 #undef PyString_AsString
 static char *PyString_AsString(PyObject *o) {
@@ -27,27 +35,32 @@
        static uint64_t last_ts = 0;
         uint64_t now = uwsgi_micros();
         uint64_t delta = 0;
+       PyCodeObject *code;
 
        switch(what) {
                case PyTrace_CALL:
                        if (last_ts == 0) delta = 0;
                        else delta = now - last_ts;
                        last_ts = now;
+                       code = PyFrame_GetCode(frame);
                        uwsgi_log("[uWSGI Python profiler %llu] CALL: %s (line 
%d) -> %s %d args, stacksize %d\n",
                                (unsigned long long) delta,
-                               PyString_AsString(frame->f_code->co_filename),
+                               PyString_AsString(code->co_filename),
                                PyFrame_GetLineNumber(frame),
-                               PyString_AsString(frame->f_code->co_name), 
frame->f_code->co_argcount, frame->f_code->co_stacksize);
+                               PyString_AsString(code->co_name), 
code->co_argcount, code->co_stacksize);
+                       Py_DECREF(code);
                        break;
                case PyTrace_C_CALL:
                        if (last_ts == 0) delta = 0;
                        else delta = now - last_ts;
                        last_ts = now;
+                       code = PyFrame_GetCode(frame);
                        uwsgi_log("[uWSGI Python profiler %llu] C CALL: %s 
(line %d) -> %s %d args, stacksize %d\n",
                                (unsigned long long) delta,
-                               PyString_AsString(frame->f_code->co_filename),
+                               PyString_AsString(code->co_filename),
                                PyFrame_GetLineNumber(frame),
-                               PyEval_GetFuncName(arg), 
frame->f_code->co_argcount, frame->f_code->co_stacksize);
+                               PyEval_GetFuncName(arg), code->co_argcount, 
code->co_stacksize);
+                       Py_DECREF(code);
                        break;
        }
 
@@ -68,7 +81,9 @@
                        delta = now - last_ts;
                }
                last_ts = now;
-               uwsgi_log("[uWSGI Python profiler %llu] file %s line %d: %s 
argc:%d\n", (unsigned long long)delta,  
PyString_AsString(frame->f_code->co_filename), PyFrame_GetLineNumber(frame), 
PyString_AsString(frame->f_code->co_name), frame->f_code->co_argcount);
+               PyCodeObject *code = PyFrame_GetCode(frame);
+               uwsgi_log("[uWSGI Python profiler %llu] file %s line %d: %s 
argc:%d\n", (unsigned long long)delta,  PyString_AsString(code->co_filename), 
PyFrame_GetLineNumber(frame), PyString_AsString(code->co_name), 
code->co_argcount);
+               Py_DECREF(code);
        }
 
         return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/plugins/python/python_plugin.c 
new/uwsgi-2.0.21/plugins/python/python_plugin.c
--- old/uwsgi-2.0.20/plugins/python/python_plugin.c     2021-10-06 
07:22:45.000000000 +0200
+++ new/uwsgi-2.0.21/plugins/python/python_plugin.c     2022-10-24 
12:21:58.000000000 +0200
@@ -171,6 +171,7 @@
 #endif
 
        {"py-call-osafterfork", no_argument, 0, "enable child processes running 
cpython to trap OS signals", uwsgi_opt_true, &up.call_osafterfork, 0},
+       {"py-call-uwsgi-fork-hooks", no_argument, 0, "call pre and post hooks 
when uswgi forks to update the internal interpreter state of CPython", 
uwsgi_opt_true, &up.call_uwsgi_fork_hooks, 0},
 
        {"python-worker-override", required_argument, 0, "override worker with 
the specified python script", uwsgi_opt_set_str, &up.worker_override, 0},
 
@@ -391,12 +392,20 @@
 
 void uwsgi_python_post_fork() {
 
+       // Need to acquire the gil when no master process is used as first 
worker
+       // will not have been forked like others
+       // Necessary if uwsgi fork hooks called to update interpreter state
+       if (up.call_uwsgi_fork_hooks && !uwsgi.master_process && uwsgi.mywid == 
1) {
+               UWSGI_GET_GIL
+       }
+
        if (uwsgi.i_am_a_spooler) {
                UWSGI_GET_GIL
        }       
 
        // reset python signal flags so child processes can trap signals
-       if (up.call_osafterfork) {
+       // Necessary if uwsgi fork hooks not called to update interpreter state
+       if (!up.call_uwsgi_fork_hooks && up.call_osafterfork) {
 #ifdef HAS_NOT_PyOS_AfterFork_Child
                PyOS_AfterFork();
 #else
@@ -1077,6 +1086,13 @@
 // this hook will be executed by master (or worker1 when master is not 
requested, so COW is in place)
 void uwsgi_python_preinit_apps() {
 
+       // GIL was released in previous initialization steps but init_pyargv 
expects
+       // the GIL to be acquired
+       // Necessary if uwsgi fork hooks called to update interpreter state
+       if (up.call_uwsgi_fork_hooks) {
+               UWSGI_GET_GIL
+       }
+
        init_pyargv();
 
         init_uwsgi_embedded_module();
@@ -1127,19 +1143,30 @@
                upli = upli->next;
        }
 
+       // Release the GIL before moving on forward with initialization
+       // Necessary if uwsgi fork hooks called to update interpreter state
+       if (up.call_uwsgi_fork_hooks) {
+               UWSGI_RELEASE_GIL
+       }
+
 }
 
 void uwsgi_python_init_apps() {
 
        // lazy ?
-       if (uwsgi.mywid > 0) {
+       // Also necessary if uwsgi fork hooks called to update interpreter state
+       if (uwsgi.mywid > 0 || up.call_uwsgi_fork_hooks) {
                UWSGI_GET_GIL;
        }
 
        // prepare for stack suspend/resume
        if (uwsgi.async > 1) {
+#ifdef UWSGI_PY311
+               up.current_recursion_remaining = 
uwsgi_malloc(sizeof(int)*uwsgi.async);
+#else
                up.current_recursion_depth = 
uwsgi_malloc(sizeof(int)*uwsgi.async);
-               up.current_frame = uwsgi_malloc(sizeof(struct 
_frame)*uwsgi.async);
+#endif
+               up.current_frame = 
uwsgi_malloc(sizeof(up.current_frame[0])*uwsgi.async);
        }
 
         // setup app loaders
@@ -1255,7 +1282,8 @@
                }
        }
        // lazy ?
-       if (uwsgi.mywid > 0) {
+       // Also necessary if uwsgi fork hooks called to update interpreter state
+       if (uwsgi.mywid > 0 || up.call_uwsgi_fork_hooks) {
                UWSGI_RELEASE_GIL;
        }
 
@@ -1268,6 +1296,10 @@
 
        if (!uwsgi.master_process) return;
 
+       // Skip master fixup if uwsgi fork hooks called to update interpreter 
state
+       if (up.call_uwsgi_fork_hooks)
+               return;
+
        if (uwsgi.has_threads) {
                if (step == 0) {
                        if (!master_fixed) {
@@ -1284,6 +1316,40 @@
        }
 }
 
+void uwsgi_python_pre_uwsgi_fork() {
+       if (!up.call_uwsgi_fork_hooks)
+               return;
+
+       if (uwsgi.has_threads) {
+               // Acquire the gil and import lock before forking in order to 
avoid
+               // deadlocks in workers
+               UWSGI_GET_GIL
+               _PyImport_AcquireLock();
+       }
+}
+
+
+void uwsgi_python_post_uwsgi_fork(int step) {
+       if (!up.call_uwsgi_fork_hooks)
+               return;
+
+       if (uwsgi.has_threads) {
+               if (step == 0) {
+                       // Release locks within master process
+                       _PyImport_ReleaseLock();
+                       UWSGI_RELEASE_GIL
+               }
+               else {
+                       // Ensure thread state and locks are cleaned up in 
child process
+#ifdef HAS_NOT_PyOS_AfterFork_Child
+                       PyOS_AfterFork();
+#else
+                       PyOS_AfterFork_Child();
+#endif
+               }
+       }
+}
+
 void uwsgi_python_enable_threads() {
 
 #ifdef UWSGI_SHOULD_CALL_PYEVAL_INITTHREADS
@@ -1313,7 +1379,11 @@
                up.reset_ts = threaded_reset_ts;
        }
 
-       
+       // Release the newly created gil from call to PyEval_InitThreads above
+       // Necessary if uwsgi fork hooks called to update interpreter state
+       if (up.call_uwsgi_fork_hooks) {
+               UWSGI_RELEASE_GIL
+       }
 
        uwsgi_log("python threads support enabled\n");
        
@@ -1321,16 +1391,12 @@
 }
 
 void uwsgi_python_set_thread_name(int core_id) {
-       // call threading.currentThread (taken from mod_wsgi, but removes 
DECREFs as thread in uWSGI are fixed)
+       // call threading.current_thread (taken from mod_wsgi, but removes 
DECREFs as thread in uWSGI are fixed)
        PyObject *threading_module = PyImport_ImportModule("threading");
         if (threading_module) {
                 PyObject *threading_module_dict = 
PyModule_GetDict(threading_module);
                 if (threading_module_dict) {
-#ifdef PYTHREE
                         PyObject *threading_current = 
PyDict_GetItemString(threading_module_dict, "current_thread");
-#else
-                        PyObject *threading_current = 
PyDict_GetItemString(threading_module_dict, "currentThread");
-#endif
                         if (threading_current) {
                                 PyObject *current_thread = 
PyObject_CallObject(threading_current, (PyObject *)NULL);
                                 if (!current_thread) {
@@ -1414,11 +1480,7 @@
         if (threading_module) {
                 PyObject *threading_module_dict = 
PyModule_GetDict(threading_module);
                 if (threading_module_dict) {
-#ifdef PYTHREE
                         PyObject *threading_current = 
PyDict_GetItemString(threading_module_dict, "current_thread");
-#else
-                        PyObject *threading_current = 
PyDict_GetItemString(threading_module_dict, "currentThread");
-#endif
                         if (threading_current) {
                                 PyObject *current_thread = 
PyObject_CallObject(threading_current, (PyObject *)NULL);
                                 if (!current_thread) {
@@ -1530,12 +1592,22 @@
        PyGILState_Release(pgst);
 
        if (wsgi_req) {
+#ifdef UWSGI_PY311
+               up.current_recursion_remaining[wsgi_req->async_id] = 
tstate->recursion_remaining;
+               up.current_frame[wsgi_req->async_id] = tstate->cframe;
+#else
                up.current_recursion_depth[wsgi_req->async_id] = 
tstate->recursion_depth;
                up.current_frame[wsgi_req->async_id] = tstate->frame;
+#endif
        }
        else {
+#ifdef UWSGI_PY311
+               up.current_main_recursion_remaining = 
tstate->recursion_remaining;
+               up.current_main_frame = tstate->cframe;
+#else
                up.current_main_recursion_depth = tstate->recursion_depth;
                up.current_main_frame = tstate->frame;
+#endif
        }
 
 }
@@ -1763,12 +1835,22 @@
        PyGILState_Release(pgst);
 
        if (wsgi_req) {
+#ifdef UWSGI_PY311
+               tstate->recursion_remaining = 
up.current_recursion_remaining[wsgi_req->async_id];
+               tstate->cframe = up.current_frame[wsgi_req->async_id];
+#else
                tstate->recursion_depth = 
up.current_recursion_depth[wsgi_req->async_id];
                tstate->frame = up.current_frame[wsgi_req->async_id];
+#endif
        }
        else {
+#ifdef UWSGI_PY311
+               tstate->recursion_remaining = 
up.current_main_recursion_remaining;
+               tstate->cframe = up.current_main_frame;
+#else
                tstate->recursion_depth = up.current_main_recursion_depth;
                tstate->frame = up.current_main_frame;
+#endif
        }
 
 }
@@ -1970,7 +2052,8 @@
                return 0;
        UWSGI_GET_GIL;
        // ensure signals can be used again from python
-       if (!up.call_osafterfork)
+       // Necessary if fork hooks have been not used to update interpreter 
state
+       if (!up.call_osafterfork && !up.call_uwsgi_fork_hooks)
 #ifdef HAS_NOT_PyOS_AfterFork_Child
                PyOS_AfterFork();
 #else
@@ -2038,4 +2121,6 @@
 
        .worker = uwsgi_python_worker,
 
+       .pre_uwsgi_fork = uwsgi_python_pre_uwsgi_fork,
+       .post_uwsgi_fork = uwsgi_python_post_uwsgi_fork,
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/plugins/python/uwsgi_python.h 
new/uwsgi-2.0.21/plugins/python/uwsgi_python.h
--- old/uwsgi-2.0.20/plugins/python/uwsgi_python.h      2021-10-06 
07:22:45.000000000 +0200
+++ new/uwsgi-2.0.21/plugins/python/uwsgi_python.h      2022-10-24 
12:21:58.000000000 +0200
@@ -1,5 +1,8 @@
 #include <uwsgi.h>
+/* See https://docs.python.org/3.10/whatsnew/3.10.html#id2 */
+#define PY_SSIZE_T_CLEAN
 #include <Python.h>
+#include <pythread.h>
 
 #include <frameobject.h>
 
@@ -14,6 +17,10 @@
 #define UWSGI_PYTHON_OLD
 #endif
 
+#if (PY_VERSION_HEX >= 0x030b0000)
+#  define UWSGI_PY311
+#endif
+
 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 7
 #define HAS_NOT_PyMemoryView_FromBuffer
 #endif
@@ -161,11 +168,19 @@
 
        char *callable;
 
+#ifdef UWSGI_PY311
+       int *current_recursion_remaining;
+       _PyCFrame **current_frame;
+
+       int current_main_recursion_remaining;
+       _PyCFrame *current_main_frame;
+#else
        int *current_recursion_depth;
        struct _frame **current_frame;
 
        int current_main_recursion_depth;
        struct _frame *current_main_frame;
+#endif
 
        void (*swap_ts)(struct wsgi_request *, struct uwsgi_app *);
        void (*reset_ts)(struct wsgi_request *, struct uwsgi_app *);
@@ -216,6 +231,8 @@
        char *worker_override;
 
        char *executable;
+
+       int call_uwsgi_fork_hooks;
 };
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/plugins/python/uwsgiplugin.py 
new/uwsgi-2.0.21/plugins/python/uwsgiplugin.py
--- old/uwsgi-2.0.20/plugins/python/uwsgiplugin.py      2021-10-06 
07:22:45.000000000 +0200
+++ new/uwsgi-2.0.21/plugins/python/uwsgiplugin.py      2022-10-24 
12:21:58.000000000 +0200
@@ -53,6 +53,8 @@
         # hack for messy linkers/compilers
         if '-lutil' in LIBS:
             LIBS.append('-lutil')
+        if '-lrt' in LIBS:
+            LIBS.append('-lrt')
     else:
         try:
             libdir = sysconfig.get_config_var('LIBDIR')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/plugins/python/wsgi_subhandler.c 
new/uwsgi-2.0.21/plugins/python/wsgi_subhandler.c
--- old/uwsgi-2.0.20/plugins/python/wsgi_subhandler.c   2021-10-06 
07:22:45.000000000 +0200
+++ new/uwsgi-2.0.21/plugins/python/wsgi_subhandler.c   2022-10-24 
12:21:58.000000000 +0200
@@ -356,23 +356,24 @@
                Py_DECREF((PyObject *) wsgi_req->async_sendfile);
        }
 
-       if (wsgi_req->async_placeholder) {
-               // CALL close() ALWAYS if we are working with an iterator !!!
-               if (PyObject_HasAttrString((PyObject *)wsgi_req->async_result, 
"close")) {
-                        PyObject *close_method = 
PyObject_GetAttrString((PyObject *)wsgi_req->async_result, "close");
-                        PyObject *close_method_args = PyTuple_New(0);
+       if (wsgi_req->async_placeholder != NULL) {
+               Py_DECREF((PyObject *)wsgi_req->async_placeholder);
+       }
+
+       // Call close() on the response, this is required by the WSGI spec
+       if (PyObject_HasAttrString((PyObject *)wsgi_req->async_result, 
"close")) {
+               PyObject *close_method = PyObject_GetAttrString((PyObject 
*)wsgi_req->async_result, "close");
+               PyObject *close_method_args = PyTuple_New(0);
 #ifdef UWSGI_DEBUG
-                        uwsgi_log("calling close() for %.*s %p %p\n", 
wsgi_req->uri_len, wsgi_req->uri, close_method, close_method_args);
+               uwsgi_log("calling close() for %.*s %p %p\n", 
wsgi_req->uri_len, wsgi_req->uri, close_method, close_method_args);
 #endif
-                        PyObject *close_method_output = 
PyObject_CallObject(close_method, close_method_args);
-                        if (PyErr_Occurred()) {
-                                uwsgi_manage_exception(wsgi_req, 0);
-                        }
-                        Py_DECREF(close_method_args);
-                        Py_XDECREF(close_method_output);
-                        Py_DECREF(close_method);
-                }
-               Py_DECREF((PyObject *)wsgi_req->async_placeholder);
+               PyObject *close_method_output = 
PyObject_CallObject(close_method, close_method_args);
+               if (PyErr_Occurred()) {
+                               uwsgi_manage_exception(wsgi_req, 0);
+               }
+               Py_DECREF(close_method_args);
+               Py_XDECREF(close_method_output);
+               Py_DECREF(close_method);
        }
 
        Py_DECREF((PyObject *)wsgi_req->async_result);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/setup.py new/uwsgi-2.0.21/setup.py
--- old/uwsgi-2.0.20/setup.py   2021-10-06 07:22:45.000000000 +0200
+++ new/uwsgi-2.0.21/setup.py   2022-10-24 12:21:58.000000000 +0200
@@ -139,5 +139,7 @@
         'Programming Language :: Python :: 3.7',
         'Programming Language :: Python :: 3.8',
         'Programming Language :: Python :: 3.9',
+        'Programming Language :: Python :: 3.10',
+        'Programming Language :: Python :: 3.11',
     ],
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/tests/deadlocks/main.py 
new/uwsgi-2.0.21/tests/deadlocks/main.py
--- old/uwsgi-2.0.20/tests/deadlocks/main.py    1970-01-01 01:00:00.000000000 
+0100
+++ new/uwsgi-2.0.21/tests/deadlocks/main.py    2022-10-24 12:21:58.000000000 
+0200
@@ -0,0 +1,4 @@
+def application(env, start_response):
+    start_response("200 OK", [("Content-Type", "text/plain")])
+    message = "Hello World"
+    return [message.encode("utf-8")]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/tests/deadlocks/master-nothreads.ini 
new/uwsgi-2.0.21/tests/deadlocks/master-nothreads.ini
--- old/uwsgi-2.0.20/tests/deadlocks/master-nothreads.ini       1970-01-01 
01:00:00.000000000 +0100
+++ new/uwsgi-2.0.21/tests/deadlocks/master-nothreads.ini       2022-10-24 
12:21:58.000000000 +0200
@@ -0,0 +1,6 @@
+[uwsgi]
+show-config = true
+master = true
+enable-threads = false
+workers = 1
+py-call-uwsgi-fork-hooks = true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/uwsgi-2.0.20/tests/deadlocks/master-singleinterpreter-threads-10workers.ini 
new/uwsgi-2.0.21/tests/deadlocks/master-singleinterpreter-threads-10workers.ini
--- 
old/uwsgi-2.0.20/tests/deadlocks/master-singleinterpreter-threads-10workers.ini 
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/uwsgi-2.0.21/tests/deadlocks/master-singleinterpreter-threads-10workers.ini 
    2022-10-24 12:21:58.000000000 +0200
@@ -0,0 +1,7 @@
+[uwsgi]
+show-config = true
+master = true
+enable-threads = true
+workers = 10
+single-interpreter = true
+py-call-uwsgi-fork-hooks = true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/uwsgi-2.0.20/tests/deadlocks/master-singleinterpreter-threads-1worker.ini 
new/uwsgi-2.0.21/tests/deadlocks/master-singleinterpreter-threads-1worker.ini
--- 
old/uwsgi-2.0.20/tests/deadlocks/master-singleinterpreter-threads-1worker.ini   
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/uwsgi-2.0.21/tests/deadlocks/master-singleinterpreter-threads-1worker.ini   
    2022-10-24 12:21:58.000000000 +0200
@@ -0,0 +1,7 @@
+[uwsgi]
+show-config = true
+master = true
+enable-threads = true
+workers = 1
+single-interpreter = true
+py-call-uwsgi-fork-hooks = true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/uwsgi-2.0.20/tests/deadlocks/master-threads-10workers.ini 
new/uwsgi-2.0.21/tests/deadlocks/master-threads-10workers.ini
--- old/uwsgi-2.0.20/tests/deadlocks/master-threads-10workers.ini       
1970-01-01 01:00:00.000000000 +0100
+++ new/uwsgi-2.0.21/tests/deadlocks/master-threads-10workers.ini       
2022-10-24 12:21:58.000000000 +0200
@@ -0,0 +1,6 @@
+[uwsgi]
+show-config = true
+master = true
+enable-threads = true
+workers = 10
+py-call-uwsgi-fork-hooks = true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/uwsgi-2.0.20/tests/deadlocks/master-threads-1worker.ini 
new/uwsgi-2.0.21/tests/deadlocks/master-threads-1worker.ini
--- old/uwsgi-2.0.20/tests/deadlocks/master-threads-1worker.ini 1970-01-01 
01:00:00.000000000 +0100
+++ new/uwsgi-2.0.21/tests/deadlocks/master-threads-1worker.ini 2022-10-24 
12:21:58.000000000 +0200
@@ -0,0 +1,6 @@
+[uwsgi]
+show-config = true
+master = true
+enable-threads = true
+workers = 1
+py-call-uwsgi-fork-hooks = true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/uwsgi-2.0.20/tests/deadlocks/nomaster-threads-10workers.ini 
new/uwsgi-2.0.21/tests/deadlocks/nomaster-threads-10workers.ini
--- old/uwsgi-2.0.20/tests/deadlocks/nomaster-threads-10workers.ini     
1970-01-01 01:00:00.000000000 +0100
+++ new/uwsgi-2.0.21/tests/deadlocks/nomaster-threads-10workers.ini     
2022-10-24 12:21:58.000000000 +0200
@@ -0,0 +1,6 @@
+[uwsgi]
+show-config = true
+master = false
+enable-threads = true
+workers = 10
+py-call-uwsgi-fork-hooks = true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/uwsgi-2.0.20/tests/deadlocks/nomaster-threads-1worker.ini 
new/uwsgi-2.0.21/tests/deadlocks/nomaster-threads-1worker.ini
--- old/uwsgi-2.0.20/tests/deadlocks/nomaster-threads-1worker.ini       
1970-01-01 01:00:00.000000000 +0100
+++ new/uwsgi-2.0.21/tests/deadlocks/nomaster-threads-1worker.ini       
2022-10-24 12:21:58.000000000 +0200
@@ -0,0 +1,6 @@
+[uwsgi]
+show-config = true
+master = false
+enable-threads = true
+workers = 1
+py-call-uwsgi-fork-hooks = true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/tests/deadlocks/sitecustomize.py 
new/uwsgi-2.0.21/tests/deadlocks/sitecustomize.py
--- old/uwsgi-2.0.20/tests/deadlocks/sitecustomize.py   1970-01-01 
01:00:00.000000000 +0100
+++ new/uwsgi-2.0.21/tests/deadlocks/sitecustomize.py   2022-10-24 
12:21:58.000000000 +0200
@@ -0,0 +1,14 @@
+import threading
+import time
+
+
+def run():
+    print("[DEADLOCKS] started run")
+    st = time.time()
+    while time.time() < st + 5:
+        pass
+    print("[DEADLOCKS] finished run")
+
+t = threading.Thread(target=run)
+t.daemon = True
+t.start()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/tests/gh-deadlocks.sh 
new/uwsgi-2.0.21/tests/gh-deadlocks.sh
--- old/uwsgi-2.0.20/tests/gh-deadlocks.sh      1970-01-01 01:00:00.000000000 
+0100
+++ new/uwsgi-2.0.21/tests/gh-deadlocks.sh      2022-10-24 12:21:58.000000000 
+0200
@@ -0,0 +1,12 @@
+#!/bin/bash
+set -u
+
+PYTHON_VERSION="$1"
+. "./tests/gh-shared.sh"
+
+
+for INI_FILE in tests/deadlocks/*.ini ; do
+  test_python_deadlocks "${PYTHON_VERSION}" "$INI_FILE"
+done
+
+results
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/tests/gh-python.sh 
new/uwsgi-2.0.21/tests/gh-python.sh
--- old/uwsgi-2.0.20/tests/gh-python.sh 1970-01-01 01:00:00.000000000 +0100
+++ new/uwsgi-2.0.21/tests/gh-python.sh 2022-10-24 12:21:58.000000000 +0200
@@ -0,0 +1,12 @@
+#!/bin/bash
+set -u
+
+PYTHON_VERSION="$1"
+. "./tests/gh-shared.sh"
+
+
+for WSGI_FILE in tests/staticfile.py tests/testworkers.py tests/testrpc.py ; do
+  test_python "${PYTHON_VERSION}" "${WSGI_FILE}"
+done
+
+results
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/tests/gh-rack.sh 
new/uwsgi-2.0.21/tests/gh-rack.sh
--- old/uwsgi-2.0.20/tests/gh-rack.sh   1970-01-01 01:00:00.000000000 +0100
+++ new/uwsgi-2.0.21/tests/gh-rack.sh   2022-10-24 12:21:58.000000000 +0200
@@ -0,0 +1,12 @@
+#!/bin/bash
+set -u
+
+RACK_VERSION="$1"
+. "./tests/gh-shared.sh"
+
+
+for RACK in examples/config2.ru ; do
+  test_rack "${RACK_VERSION}" "${RACK}"
+done
+
+results
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/tests/gh-shared.sh 
new/uwsgi-2.0.21/tests/gh-shared.sh
--- old/uwsgi-2.0.20/tests/gh-shared.sh 1970-01-01 01:00:00.000000000 +0100
+++ new/uwsgi-2.0.21/tests/gh-shared.sh 2022-10-24 12:21:58.000000000 +0200
@@ -0,0 +1,108 @@
+#!/bin/bash
+
+txtund=$(tput sgr 0 1)          # underline
+txtbld=$(tput bold)             # bold
+bldred=${txtbld}$(tput setaf 1) # red
+bldgre=${txtbld}$(tput setaf 2) # green
+bldyel=${txtbld}$(tput setaf 3) # yellow
+bldblu=${txtbld}$(tput setaf 4) # blue
+txtcya=$(tput setaf 6)          # cyan
+bldwht=${txtbld}$(tput setaf 7) # white
+txtrst=$(tput sgr0)             # reset
+
+
+ERROR=0
+SUCCESS=0
+
+
+die() {
+    date > reload.txt
+    sleep 3
+    pidof uwsgi && killall uwsgi
+    sleep 1
+    pidof uwsgi && killall -9 uwsgi
+    echo -e "$@"
+    if [ -e uwsgi.log ]; then
+        echo -e "${bldyel}>>> uwsgi.log:${txtrst}"
+        echo -e "${txtcya}"
+        cat uwsgi.log
+        echo -e "${txtrst}"
+    fi
+}
+
+
+http_test() {
+    URL=$1
+    UPID=`pidof uwsgi`
+    if [ "$UPID" != "" ]; then
+        echo -e "${bldgre}>>> Spawned PID $UPID, running tests${txtrst}"
+        sleep 5
+        curl -fI $URL
+        RET=$?
+        if [ $RET != 0 ]; then
+            die "${bldred}>>> Error during curl run${txtrst}"
+            ERROR=$((ERROR+1))
+        else
+            SUCCESS=$((SUCCESS+1))
+        fi
+        die "${bldyel}>>> SUCCESS: Done${txtrst}"
+    else
+        die "${bldred}>>> ERROR: uWSGI did not start${txtrst}"
+        ERROR=$((ERROR+1))
+    fi
+}
+
+
+test_python() {
+    date > reload.txt
+    rm -f uwsgi.log
+    echo -e "${bldyel}================== TESTING $1 $2 
=====================${txtrst}"
+    echo -e "${bldyel}>>> Spawning uWSGI python app${txtrst}"
+    echo -en "${bldred}"
+    ./uwsgi --master --plugin 0:$1 --http :8080 --exit-on-reload 
--touch-reload reload.txt --wsgi-file $2 --daemonize uwsgi.log
+    sleep 1
+    echo -en "${txtrst}"
+    http_test "http://localhost:8080/";
+    echo -e "${bldyel}===================== DONE $1 $2 
=====================${txtrst}\n\n"
+}
+
+
+test_python_deadlocks() {
+    date > reload.txt
+    rm -f uwsgi.log
+    echo -e "${bldyel}================== TESTING DEADLOCKS $1 $2 
=====================${txtrst}"
+    echo -e "${bldyel}>>> Starting python app${txtrst}"
+    echo -en "${bldred}"
+    # initialize with tests/deadlocks/sitecustomize.py
+    PYTHONPATH=tests/deadlocks ./uwsgi --plugin 0:$1 --http :8080 
--exit-on-reload --touch-reload reload.txt --wsgi-file tests/deadlocks/main.py 
--ini $2 --daemonize uwsgi.log
+    sleep 1
+    echo -en "${txtrst}"
+    http_test "http://localhost:8080/";
+    echo -e "${bldyel}===================== DONE $1 $2 
=====================${txtrst}\n\n"
+}
+
+
+test_rack() {
+    date > reload.txt
+    rm -f uwsgi.log
+    # the code assumes that ruby environment is activated by `rvm use`
+    echo -e "${bldyel}================== TESTING $1 $2 
=====================${txtrst}"
+    echo -e "${bldyel}>>> Installing sinatra gem using gem${txtrst}"
+    sudo gem install sinatra -v 2.2.2 || die
+    echo -e "${bldyel}>>> Spawning uWSGI rack app${txtrst}"
+    echo -en "${bldred}"
+    ./uwsgi --master --plugin 0:$1 --http :8080 --exit-on-reload 
--touch-reload reload.txt --rack $2 --daemonize uwsgi.log
+    echo -en "${txtrst}"
+    http_test "http://localhost:8080/hi";
+    echo -e "${bldyel}===================== DONE $1 $2 
=====================${txtrst}\n\n"
+}
+
+results() {
+  echo "${bldgre}>>> $SUCCESS SUCCESSFUL TEST(S)${txtrst}"
+  if [ $ERROR -ge 1 ]; then
+      echo "${bldred}>>> $ERROR FAILED TEST(S)${txtrst}"
+      exit 1
+  fi
+
+  exit 0
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/tests/travis.sh 
new/uwsgi-2.0.21/tests/travis.sh
--- old/uwsgi-2.0.20/tests/travis.sh    2021-10-06 07:22:45.000000000 +0200
+++ new/uwsgi-2.0.21/tests/travis.sh    2022-10-24 12:21:58.000000000 +0200
@@ -70,6 +70,22 @@
     echo -e "${bldyel}>>> Spawning uWSGI python app${txtrst}"
     echo -en "${bldred}"
     ./uwsgi --master --plugin 0:$1 --http :8080 --exit-on-reload 
--touch-reload reload.txt --wsgi-file $2 --daemonize uwsgi.log
+    sleep 1
+    echo -en "${txtrst}"
+    http_test "http://localhost:8080/";
+    echo -e "${bldyel}===================== DONE $1 $2 
=====================${txtrst}\n\n"
+}
+
+
+test_python_deadlocks() {
+    date > reload.txt
+    rm -f uwsgi.log
+    echo -e "${bldyel}================== TESTING DEADLOCKS $1 $2 
=====================${txtrst}"
+    echo -e "${bldyel}>>> Starting python app${txtrst}"
+    echo -en "${bldred}"
+    # initialize with tests/deadlocks/sitecustomize.py
+    PYTHONPATH=tests/deadlocks ./uwsgi --plugin 0:$1 --http :8080 
--exit-on-reload --touch-reload reload.txt --wsgi-file tests/deadlocks/main.py 
--ini $2 --daemonize uwsgi.log
+    sleep 1
     echo -en "${txtrst}"
     http_test "http://localhost:8080/";
     echo -e "${bldyel}===================== DONE $1 $2 
=====================${txtrst}\n\n"
@@ -82,7 +98,7 @@
     # the code assumes that ruby environment is activated by `rvm use`
     echo -e "${bldyel}================== TESTING $1 $2 
=====================${txtrst}"
     echo -e "${bldyel}>>> Installing sinatra gem using gem${txtrst}"
-    sudo gem install sinatra || die
+    sudo gem install sinatra -v 2.2.2 || die
     echo -e "${bldyel}>>> Spawning uWSGI rack app${txtrst}"
     echo -en "${bldred}"
     ./uwsgi --master --plugin 0:$1 --http :8080 --exit-on-reload 
--touch-reload reload.txt --rack $2 --daemonize uwsgi.log
@@ -97,8 +113,11 @@
         test_python $PV $WSGI_FILE
     done
 done < <(cat "$CI_CONFIG" | grep "plugins/python base" | sed 
s_".*plugins/python base "_""_g)
-
-
+while read PV ; do
+    for INI_FILE in tests/deadlocks/*.ini ; do
+        test_python_deadlocks $PV $INI_FILE
+    done
+done < <(cat "$CI_CONFIG" | grep "plugins/python base" | sed 
s_".*plugins/python base "_""_g)
 while read RV ; do
     for RACK in examples/config2.ru ; do
         test_rack $RV $RACK
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/uwsgi.gemspec 
new/uwsgi-2.0.21/uwsgi.gemspec
--- old/uwsgi-2.0.20/uwsgi.gemspec      2021-10-06 07:22:45.000000000 +0200
+++ new/uwsgi-2.0.21/uwsgi.gemspec      2022-10-24 12:21:58.000000000 +0200
@@ -2,7 +2,7 @@
   s.name        = 'uwsgi'
   s.license     = 'GPL-2'
   s.version     = `python -c "import uwsgiconfig as uc; print 
uc.uwsgi_version"`.sub(/-dev-.*/,'')
-  s.date        = '2021-10-06'
+  s.date        = '2022-10-24'
   s.summary     = "uWSGI"
   s.description = "The uWSGI server for Ruby/Rack"
   s.authors     = ["Unbit"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/uwsgi.h new/uwsgi-2.0.21/uwsgi.h
--- old/uwsgi-2.0.20/uwsgi.h    2021-10-06 07:22:45.000000000 +0200
+++ new/uwsgi-2.0.21/uwsgi.h    2022-10-24 12:21:58.000000000 +0200
@@ -1084,6 +1084,9 @@
        int (*worker)(void);
 
        void (*early_post_jail) (void);
+
+       void (*pre_uwsgi_fork) (void);
+       void (*post_uwsgi_fork) (int);
 };
 
 #ifdef UWSGI_PCRE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.20/uwsgiconfig.py 
new/uwsgi-2.0.21/uwsgiconfig.py
--- old/uwsgi-2.0.20/uwsgiconfig.py     2021-10-06 07:22:45.000000000 +0200
+++ new/uwsgi-2.0.21/uwsgiconfig.py     2022-10-24 12:21:58.000000000 +0200
@@ -1,6 +1,6 @@
 # uWSGI build system
 
-uwsgi_version = '2.0.20'
+uwsgi_version = '2.0.21'
 
 import os
 import re
@@ -116,8 +116,8 @@
         if objfile:
             print_lock.acquire()
             print_compilation_output("[thread %d][%s] %s" % (num, GCC, 
objfile), "[thread %d] %s" % (num, cmdline))
-            print_lock.release()    
-            ret = os.system(cmdline)
+            print_lock.release()
+            ret = subprocess.call(cmdline, shell=True)
             if ret != 0:
                 os._exit(1)
         elif cmdline:
@@ -157,7 +157,7 @@
 
 if uwsgi_version.endswith('-dev') and os.path.exists('%s/.git' % 
os.path.dirname(os.path.abspath( __file__ ))):
     try:
-        uwsgi_version += '-%s' % spcall('git rev-parse --short HEAD')
+        uwsgi_version += '+%s' % spcall('git rev-parse --short HEAD')
     except:
         pass
 
@@ -237,14 +237,14 @@
 def push_command(objfile, cmdline):
     if not compile_queue:
         print_compilation_output("[%s] %s" % (GCC, objfile), cmdline)
-        ret = os.system(cmdline)
+        ret = subprocess.call(cmdline, shell=True)
         if ret != 0:
             sys.exit(1)
     else:
         compile_queue.put((objfile, cmdline))
         
 
-def compile(cflags, last_cflags_ts, objfile, srcfile):
+def uwsgi_compile(cflags, last_cflags_ts, objfile, srcfile):
     source_stat = os.stat(srcfile)
     header_stat = os.stat('uwsgi.h')
     try:
@@ -411,14 +411,14 @@
         if not objfile.endswith('.a') and not objfile.endswith('.o'):
             if objfile.endswith('.c') or objfile.endswith('.cc') or 
objfile.endswith('.m') or objfile.endswith('.go'):
                 if objfile.endswith('.go'):
-                    cflags.append('-Wno-error') 
-                compile(' '.join(cflags), last_cflags_ts, objfile + '.o', file)
+                    cflags.append('-Wno-error')
+                uwsgi_compile(' '.join(cflags), last_cflags_ts, objfile + 
'.o', file)
                 if objfile.endswith('.go'):
                     cflags.pop()
             else:
                 if objfile == 'core/dot_h':
                     cflags.append('-g')
-                compile(' '.join(cflags), last_cflags_ts, objfile + '.o', file 
+ '.c')
+                uwsgi_compile(' '.join(cflags), last_cflags_ts, objfile + 
'.o', file + '.c')
                 if objfile == 'core/dot_h':
                     cflags.pop()
 
@@ -528,25 +528,25 @@
                     elif cfile.endswith('.o'):
                         gcc_list.append('%s/%s' % (path, cfile))
                     elif not cfile.endswith('.c') and not 
cfile.endswith('.cc') and not cfile.endswith('.go') and not 
cfile.endswith('.m'):
-                        compile(' '.join(uniq_warnings(p_cflags)), 
last_cflags_ts,
+                        uwsgi_compile(' '.join(uniq_warnings(p_cflags)), 
last_cflags_ts,
                             path + '/' + cfile + '.o', path + '/' + cfile + 
'.c')
                         gcc_list.append('%s/%s' % (path, cfile))
                     else:
                         if cfile.endswith('.go'):
                             p_cflags.append('-Wno-error')
-                        compile(' '.join(uniq_warnings(p_cflags)), 
last_cflags_ts,
+                        uwsgi_compile(' '.join(uniq_warnings(p_cflags)), 
last_cflags_ts,
                             path + '/' + cfile + '.o', path + '/' + cfile)
                         gcc_list.append('%s/%s' % (path, cfile))
                 for bfile in up.get('BINARY_LIST', []):
                     try:
                         binary_link_cmd = "ld -r -b binary -o %s/%s.o %s/%s" % 
(path, bfile[1], path, bfile[1])
                         print(binary_link_cmd)
-                        if os.system(binary_link_cmd) != 0:
+                        if subprocess.call(binary_link_cmd, shell=True) != 0:
                             raise Exception('unable to link binary file')
-                        for kind in ('start','end'):
+                        for kind in ('start', 'end'):
                             objcopy_cmd = "objcopy --redefine-sym 
_binary_%s_%s=%s_%s %s/%s.o" % (binarize('%s/%s' % (path, bfile[1])), kind, 
bfile[0], kind, path, bfile[1])
                             print(objcopy_cmd)
-                            if os.system(objcopy_cmd) != 0:
+                            if subprocess.call(objcopy_cmd, shell=True) != 0:
                                 raise Exception('unable to link binary file')
                         gcc_list.append('%s/%s.o' % (path, bfile[1]))
                     except:
@@ -603,7 +603,7 @@
     ldline = "%s -o %s %s %s %s" % (GCC, quote(bin_name), ' 
'.join(uniq_warnings(ldflags)),
         ' '.join(map(add_o, gcc_list)), ' '.join(uniq_warnings(libs)))
     print(ldline)
-    ret = os.system(ldline)
+    ret = subprocess.call(ldline, shell=True)
     if ret != 0:
         print("*** error linking uWSGI ***")
         sys.exit(1)
@@ -1148,7 +1148,7 @@
             if self.embed_config:
                 binary_link_cmd = "ld -r -b binary -o %s.o %s" % 
(binarize(self.embed_config), self.embed_config)
                 print(binary_link_cmd)
-                os.system(binary_link_cmd)
+                subprocess.call(binary_link_cmd, shell=True)
                 self.cflags.append("-DUWSGI_EMBED_CONFIG=_binary_%s_start" % 
binarize(self.embed_config))
                 self.cflags.append("-DUWSGI_EMBED_CONFIG_END=_binary_%s_end" % 
binarize(self.embed_config))
             embed_files = os.environ.get('UWSGI_EMBED_FILES')
@@ -1167,25 +1167,23 @@
                                 fname = "%s/%s" % (directory, f)
                                 binary_link_cmd = "ld -r -b binary -o %s.o %s" 
% (binarize(fname), fname)
                                 print(binary_link_cmd)
-                                os.system(binary_link_cmd)
+                                subprocess.call(binary_link_cmd, shell=True)
                                 if symbase:
                                     for kind in ('start','end'):
                                         objcopy_cmd = "objcopy --redefine-sym 
_binary_%s_%s=_binary_%s%s_%s build/%s.o" % (binarize(fname), kind, 
binarize(symbase), binarize(fname[len(ef):]), kind, binarize(fname))
                                         print(objcopy_cmd)
-                                        os.system(objcopy_cmd)
+                                        subprocess.call(objcopy_cmd, 
shell=True)
                                 binary_list.append(binarize(fname))
                     else:
                         binary_link_cmd = "ld -r -b binary -o %s.o %s" % 
(binarize(ef), ef)
                         print(binary_link_cmd)
-                        os.system(binary_link_cmd)
+                        subprocess.call(binary_link_cmd, shell=True)
                         binary_list.append(binarize(ef))
                         if symbase:
                             for kind in ('start','end'):
                                 objcopy_cmd = "objcopy --redefine-sym 
_binary_%s_%s=_binary_%s_%s build/%s.o" % (binarize(ef), kind, 
binarize(symbase), kind, binarize(ef))
                                 print(objcopy_cmd)
-                                os.system(objcopy_cmd)
-                
-                 
+                                subprocess.call(objcopy_cmd, shell=True)
 
         self.cflags.append('-DUWSGI_VERSION="\\"' + uwsgi_version + '\\""')
 
@@ -1467,12 +1465,12 @@
         try:
             binary_link_cmd = "ld -r -b binary -o %s/%s.o %s/%s" % (path, 
bfile[1], path, bfile[1])
             print(binary_link_cmd)
-            if os.system(binary_link_cmd) != 0:
+            if subprocess.call(binary_link_cmd, shell=True) != 0:
                 raise Exception('unable to link binary file')
             for kind in ('start','end'):
                 objcopy_cmd = "objcopy --redefine-sym _binary_%s_%s=%s_%s 
%s/%s.o" % (binarize('%s/%s' % (path, bfile[1])), kind, bfile[0], kind, path, 
bfile[1])
                 print(objcopy_cmd)
-                if os.system(objcopy_cmd) != 0:
+                if subprocess.call(objcopy_cmd, shell=True) != 0:
                     raise Exception('unable to link binary file')
             gcc_list.append('%s/%s.o' % (path, bfile[1]))
         except:
@@ -1535,7 +1533,7 @@
     gccline = "%s%s %s -o %s.so %s %s %s %s" % (GCC, need_pic, shared_flag, 
plugin_dest, ' '.join(uniq_warnings(p_cflags)), ' '.join(gcc_list), ' 
'.join(uniq_warnings(p_ldflags)), ' '.join(uniq_warnings(p_libs)) )
     print_compilation_output("[%s] %s.so" % (GCC, plugin_dest), gccline)
 
-    ret = os.system(gccline)
+    ret = subprocess.call(gccline, shell=True)
     if ret != 0:
         print("*** unable to build %s plugin ***" % name)
         sys.exit(1)
@@ -1548,7 +1546,7 @@
             f.close()
             objline = "objcopy %s.so --add-section uwsgi=.uwsgi_plugin_section 
%s.so" % (plugin_dest, plugin_dest)
             print_compilation_output(None, objline)
-            os.system(objline)
+            subprocess.call(objline, shell=True)
             os.unlink('.uwsgi_plugin_section')
     except:
         pass
@@ -1659,15 +1657,15 @@
             pass
         build_plugin(options.extra_plugin[0], None, cflags, ldflags, None, 
name)
     elif options.clean:
-        os.system("rm -f core/*.o")
-        os.system("rm -f proto/*.o")
-        os.system("rm -f lib/*.o")
-        os.system("rm -f plugins/*/*.o")
-        os.system("rm -f build/*.o")
-        os.system("rm -f core/dot_h.c")
-        os.system("rm -f core/config_py.c")
+        subprocess.call("rm -f core/*.o", shell=True)
+        subprocess.call("rm -f proto/*.o", shell=True)
+        subprocess.call("rm -f lib/*.o", shell=True)
+        subprocess.call("rm -f plugins/*/*.o", shell=True)
+        subprocess.call("rm -f build/*.o", shell=True)
+        subprocess.call("rm -f core/dot_h.c", shell=True)
+        subprocess.call("rm -f core/config_py.c", shell=True)
     elif options.check:
-        os.system("cppcheck --max-configs=1000 --enable=all -q core/ plugins/ 
proto/ lib/ apache2/")
+        subprocess.call("cppcheck --max-configs=1000 --enable=all -q core/ 
plugins/ proto/ lib/ apache2/", shell=True)
     else:
         parser.print_help()
         sys.exit(1)

++++++ uwsgi-2.0.12-no-LD_RUN_PATH.patch ++++++
--- /var/tmp/diff_new_pack.NOkjsw/_old  2023-01-08 21:25:16.283151532 +0100
+++ /var/tmp/diff_new_pack.NOkjsw/_new  2023-01-08 21:25:16.287151555 +0100
@@ -1,8 +1,8 @@
-Index: uwsgi-2.0.13/plugins/jvm/uwsgiplugin.py
+Index: uwsgi-2.0.21/plugins/jvm/uwsgiplugin.py
 ===================================================================
---- uwsgi-2.0.13.orig/plugins/jvm/uwsgiplugin.py
-+++ uwsgi-2.0.13/plugins/jvm/uwsgiplugin.py
-@@ -65,11 +65,6 @@ if "-framework JavaVM" in JVM_LIBPATH:
+--- uwsgi-2.0.21.orig/plugins/jvm/uwsgiplugin.py
++++ uwsgi-2.0.21/plugins/jvm/uwsgiplugin.py
+@@ -66,11 +66,6 @@ if "-framework JavaVM" in JVM_LIBPATH:
  
  GCC_LIST = ['jvm_plugin']
  
@@ -12,12 +12,12 @@
 -    os.environ['LD_RUN_PATH'] = JVM_LIBPATH[0][2:]
 -
  def post_build(config):
-     if os.system("javac %s/plugins/jvm/uwsgi.java" % os.getcwd()) != 0:
+     if subprocess.call("javac %s/plugins/jvm/uwsgi.java" % os.getcwd(), 
shell=True) != 0:
          os._exit(1)
-Index: uwsgi-2.0.13/plugins/php/uwsgiplugin.py
+Index: uwsgi-2.0.21/plugins/php/uwsgiplugin.py
 ===================================================================
---- uwsgi-2.0.13.orig/plugins/php/uwsgiplugin.py
-+++ uwsgi-2.0.13/plugins/php/uwsgiplugin.py
+--- uwsgi-2.0.21.orig/plugins/php/uwsgiplugin.py
++++ uwsgi-2.0.21/plugins/php/uwsgiplugin.py
 @@ -19,7 +19,6 @@ LDFLAGS = os.popen(PHPPATH + ' --ldflags
  
  if ld_run_path:
@@ -26,11 +26,11 @@
  
  LIBS = [os.popen(PHPPATH + ' --libs').read().rstrip(), '-lphp' + php_version]
  
-Index: uwsgi-2.0.13/plugins/python/uwsgiplugin.py
+Index: uwsgi-2.0.21/plugins/python/uwsgiplugin.py
 ===================================================================
---- uwsgi-2.0.13.orig/plugins/python/uwsgiplugin.py
-+++ uwsgi-2.0.13/plugins/python/uwsgiplugin.py
-@@ -58,8 +58,6 @@ if not 'UWSGI_PYTHON_NOLIB' in os.enviro
+--- uwsgi-2.0.21.orig/plugins/python/uwsgiplugin.py
++++ uwsgi-2.0.21/plugins/python/uwsgiplugin.py
+@@ -64,8 +64,6 @@ if not 'UWSGI_PYTHON_NOLIB' in os.enviro
          LDFLAGS.append("-L%s" % libdir)
          LDFLAGS.append("-Wl,-rpath,%s" % libdir)
  
@@ -39,10 +39,10 @@
          LIBS.append('-lpython%s' % get_python_version())
  else:
      LIBS = []
-Index: uwsgi-2.0.13/plugins/rack/uwsgiplugin.py
+Index: uwsgi-2.0.21/plugins/rack/uwsgiplugin.py
 ===================================================================
---- uwsgi-2.0.13.orig/plugins/rack/uwsgiplugin.py
-+++ uwsgi-2.0.13/plugins/rack/uwsgiplugin.py
+--- uwsgi-2.0.21.orig/plugins/rack/uwsgiplugin.py
++++ uwsgi-2.0.21/plugins/rack/uwsgiplugin.py
 @@ -46,7 +46,6 @@ LIBS = os.popen(RUBYPATH + " -e \"requir
  
  if has_shared == 'yes':
@@ -51,10 +51,10 @@
      LIBS.append(os.popen(RUBYPATH + " -e \"require 'rbconfig';print '-l' + 
%s::CONFIG['RUBY_SO_NAME']\"" % rbconfig).read().rstrip())
  else:
      rubylibdir = os.popen(RUBYPATH + " -e \"require 'rbconfig';print 
RbConfig::CONFIG['rubylibdir']\"").read().rstrip()
-Index: uwsgi-2.0.13/plugins/ruby19/uwsgiplugin.py
+Index: uwsgi-2.0.21/plugins/ruby19/uwsgiplugin.py
 ===================================================================
---- uwsgi-2.0.13.orig/plugins/ruby19/uwsgiplugin.py
-+++ uwsgi-2.0.13/plugins/ruby19/uwsgiplugin.py
+--- uwsgi-2.0.21.orig/plugins/ruby19/uwsgiplugin.py
++++ uwsgi-2.0.21/plugins/ruby19/uwsgiplugin.py
 @@ -40,6 +40,5 @@ LDFLAGS = os.popen(RUBYPATH + " -e \"req
  
  libpath = os.popen(RUBYPATH + " -e \"require 'rbconfig';print 
%s::CONFIG['libdir']\"" % rbconfig).read().rstrip()

++++++ uwsgi-ld-noexecstack.patch ++++++
--- /var/tmp/diff_new_pack.NOkjsw/_old  2023-01-08 21:25:16.299151626 +0100
+++ /var/tmp/diff_new_pack.NOkjsw/_new  2023-01-08 21:25:16.303151650 +0100
@@ -1,15 +1,15 @@
-diff --git a/uwsgiconfig.py b/uwsgiconfig.py
-index 9998bc5..abb44e4 100644
---- a/uwsgiconfig.py
-+++ b/uwsgiconfig.py
-@@ -539,7 +539,7 @@ def build_uwsgi(uc, print_only=False, gcll=None):
+Index: uwsgi-2.0.21/uwsgiconfig.py
+===================================================================
+--- uwsgi-2.0.21.orig/uwsgiconfig.py
++++ uwsgi-2.0.21/uwsgiconfig.py
+@@ -539,7 +539,7 @@ def build_uwsgi(uc, print_only=False, gc
                          gcc_list.append('%s/%s' % (path, cfile))
                  for bfile in up.get('BINARY_LIST', []):
                      try:
 -                        binary_link_cmd = "ld -r -b binary -o %s/%s.o %s/%s" 
% (path, bfile[1], path, bfile[1])
 +                        binary_link_cmd = "ld -z noexecstack -r -b binary -o 
%s/%s.o %s/%s" % (path, bfile[1], path, bfile[1])
                          print(binary_link_cmd)
-                         if os.system(binary_link_cmd) != 0:
+                         if subprocess.call(binary_link_cmd, shell=True) != 0:
                              raise Exception('unable to link binary file')
 @@ -1146,7 +1146,7 @@ class uConf(object):
              if not self.embed_config:
@@ -18,7 +18,7 @@
 -                binary_link_cmd = "ld -r -b binary -o %s.o %s" % 
(binarize(self.embed_config), self.embed_config)
 +                binary_link_cmd = "ld -z noexecstack -r -b binary -o %s.o %s" 
% (binarize(self.embed_config), self.embed_config)
                  print(binary_link_cmd)
-                 os.system(binary_link_cmd)
+                 subprocess.call(binary_link_cmd, shell=True)
                  self.cflags.append("-DUWSGI_EMBED_CONFIG=_binary_%s_start" % 
binarize(self.embed_config))
 @@ -1165,7 +1165,7 @@ class uConf(object):
                          for directory, directories, files in os.walk(ef):
@@ -27,24 +27,24 @@
 -                                binary_link_cmd = "ld -r -b binary -o %s.o 
%s" % (binarize(fname), fname)
 +                                binary_link_cmd = "ld -z noexecstack -r -b 
binary -o %s.o %s" % (binarize(fname), fname)
                                  print(binary_link_cmd)
-                                 os.system(binary_link_cmd)
+                                 subprocess.call(binary_link_cmd, shell=True)
                                  if symbase:
 @@ -1175,7 +1175,7 @@ class uConf(object):
-                                         os.system(objcopy_cmd)
+                                         subprocess.call(objcopy_cmd, 
shell=True)
                                  binary_list.append(binarize(fname))
                      else:
 -                        binary_link_cmd = "ld -r -b binary -o %s.o %s" % 
(binarize(ef), ef)
 +                        binary_link_cmd = "ld -z noexecstack -r -b binary -o 
%s.o %s" % (binarize(ef), ef)
                          print(binary_link_cmd)
-                         os.system(binary_link_cmd)
+                         subprocess.call(binary_link_cmd, shell=True)
                          binary_list.append(binarize(ef))
-@@ -1465,7 +1465,7 @@ def build_plugin(path, uc, cflags, ldflags, libs, name = 
None):
+@@ -1460,7 +1460,7 @@ def build_plugin(path, uc, cflags, ldfla
              gcc_list.append(path + '/' + cfile)
      for bfile in up.get('BINARY_LIST', []):
          try:
 -            binary_link_cmd = "ld -r -b binary -o %s/%s.o %s/%s" % (path, 
bfile[1], path, bfile[1])
 +            binary_link_cmd = "ld -z noexecstack -r -b binary -o %s/%s.o 
%s/%s" % (path, bfile[1], path, bfile[1])
              print(binary_link_cmd)
-             if os.system(binary_link_cmd) != 0:
+             if subprocess.call(binary_link_cmd, shell=True) != 0:
                  raise Exception('unable to link binary file')
 

Reply via email to