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')