update lua-resty-openssl deps and replace nginx -s calls with signals
This commit is contained in:
parent
5adec84d5a
commit
10a4cefd00
|
@ -1,8 +1,11 @@
|
|||
local class = require "middleclass"
|
||||
local datastore = require "bunkerweb.datastore"
|
||||
local utils = require "bunkerweb.utils"
|
||||
local logger = require "bunkerweb.logger"
|
||||
local cjson = require "cjson"
|
||||
local upload = require "resty.upload"
|
||||
local rsignal = require "resty.signal"
|
||||
local process = require "ngx.process"
|
||||
|
||||
local api = class("api")
|
||||
|
||||
|
@ -10,6 +13,32 @@ api.global = { GET = {}, POST = {}, PUT = {}, DELETE = {} }
|
|||
|
||||
function api:initialize()
|
||||
self.datastore = datastore:new()
|
||||
self.logger = logger:new("API")
|
||||
end
|
||||
|
||||
function api:log_cmd(cmd, status, stdout, stderr)
|
||||
local level = ngx.NOTICE
|
||||
local prefix = "success"
|
||||
if status ~= 0 then
|
||||
level = ngx.ERR
|
||||
prefix = "error"
|
||||
end
|
||||
self.logger:log(level, prefix .. " while running command " .. command)
|
||||
self.logger:log(level, "stdout = " .. stdout)
|
||||
self.logger:log(level, "stdout = " .. stderr)
|
||||
end
|
||||
|
||||
-- TODO : use this if we switch to OpenResty
|
||||
function api:cmd(cmd)
|
||||
-- Non-blocking command
|
||||
local ok, stdout, stderr, reason, status = shell.run(cmd, nil, 10000)
|
||||
self.logger:log_cmd(cmd, status, stdout, stderr)
|
||||
-- Timeout
|
||||
if ok == nil then
|
||||
return nil, reason
|
||||
end
|
||||
-- Other cases : exit 0, exit !0 and killed by signal
|
||||
return status == 0, reason, status
|
||||
end
|
||||
|
||||
function api:response(http_status, api_status, msg)
|
||||
|
@ -24,19 +53,21 @@ api.global.GET["^/ping$"] = function(self)
|
|||
end
|
||||
|
||||
api.global.POST["^/reload$"] = function(self)
|
||||
local status = os.execute("nginx -s reload")
|
||||
if status == 0 then
|
||||
return self:response(ngx.HTTP_OK, "success", "reload successful")
|
||||
-- Send HUP signal to master process
|
||||
local ok, err = rsignal.kill(process.get_master_pid(), "HUP")
|
||||
if not ok then
|
||||
return self:response(ngx.HTTP_INTERNAL_SERVER_ERROR, "error", "err = " .. err)
|
||||
end
|
||||
return self:response(ngx.HTTP_INTERNAL_SERVER_ERROR, "error", "exit status = " .. tostring(status))
|
||||
return self:response(ngx.HTTP_OK, "success", "reload successful")
|
||||
end
|
||||
|
||||
api.global.POST["^/stop$"] = function(self)
|
||||
local status = os.execute("nginx -s quit")
|
||||
if status == 0 then
|
||||
return self:response(ngx.HTTP_OK, "success", "stop successful")
|
||||
-- Send QUIT signal to master process
|
||||
local ok, err = rsignal.kill(process.get_master_pid(), "QUIT")
|
||||
if not ok then
|
||||
return self:response(ngx.HTTP_INTERNAL_SERVER_ERROR, "error", "err = " .. err)
|
||||
end
|
||||
return self:response(ngx.HTTP_INTERNAL_SERVER_ERROR, "error", "exit status = " .. tostring(status))
|
||||
return self:response(ngx.HTTP_OK, "success", "stop successful")
|
||||
end
|
||||
|
||||
api.global.POST["^/confs$"] = function(self)
|
||||
|
@ -74,13 +105,15 @@ api.global.POST["^/confs$"] = function(self)
|
|||
end
|
||||
file:flush()
|
||||
file:close()
|
||||
local status = os.execute("rm -rf " .. destination .. "/*")
|
||||
if status ~= 0 then
|
||||
return self:response(ngx.HTTP_BAD_REQUEST, "error", "can't remove old files")
|
||||
end
|
||||
status = os.execute("tar xzf " .. tmp .. " -C " .. destination)
|
||||
if status ~= 0 then
|
||||
return self:response(ngx.HTTP_BAD_REQUEST, "error", "can't extract archive")
|
||||
local cmds = {
|
||||
"rm -rf " .. destination .. "/*",
|
||||
"tar xzf " .. tmp .. " -C " .. destination
|
||||
}
|
||||
for i, cmd in ipairs(cmds) do
|
||||
local status = os.execute(cmd)
|
||||
if status ~= 0 then
|
||||
return self:response(ngx.HTTP_INTERNAL_SERVER_ERROR, "error", "exit status = " .. tostring(status))
|
||||
end
|
||||
end
|
||||
return self:response(ngx.HTTP_OK, "success", "saved data at " .. destination)
|
||||
end
|
||||
|
|
|
@ -265,13 +265,13 @@ if [ "$dopatch" = "yes" ] ; then
|
|||
do_and_check_cmd cp deps/misc/lua-pack.Makefile deps/src/lua-pack/Makefile
|
||||
fi
|
||||
|
||||
# lua-resty-openssl v0.8.21
|
||||
# lua-resty-openssl v0.8.22
|
||||
echo "ℹ️ Downloading lua-resty-openssl"
|
||||
dopatch="no"
|
||||
if [ ! -d "deps/src/lua-resty-openssl" ] ; then
|
||||
dopatch="yes"
|
||||
fi
|
||||
git_secure_clone "https://github.com/fffonion/lua-resty-openssl.git" "15bc59b97feb5acf25fbdd9426cf73870cf7c838"
|
||||
git_secure_clone "https://github.com/fffonion/lua-resty-openssl.git" "484907935e60273d31626ac849b23a2d218173de"
|
||||
if [ "$dopatch" == "yes" ] ; then
|
||||
do_and_check_cmd rm -r deps/src/lua-resty-openssl/t
|
||||
fi
|
||||
|
@ -287,6 +287,10 @@ if [ "$dopatch" = "yes" ] ; then
|
|||
do_and_check_cmd patch deps/src/lua-ffi-zlib/lib/ffi-zlib.lua deps/misc/lua-ffi-zlib.patch
|
||||
fi
|
||||
|
||||
# lua-resty-signal v0.03
|
||||
echo "ℹ️ Downloading lua-resty-signal"
|
||||
git_secure_clone "https://github.com/openresty/lua-resty-signal.git" "d07163e8cfa673900e66048cd2a1f18523aecf16"
|
||||
|
||||
# ModSecurity v3.0.9
|
||||
echo "ℹ️ Downloading ModSecurity"
|
||||
dopatch="no"
|
||||
|
|
|
@ -154,6 +154,11 @@ do_and_check_cmd cp /tmp/bunkerweb/deps/src/lua-resty-openssl/lib/resty/openssl.
|
|||
echo "ℹ️ Installing lua-ffi-zlib"
|
||||
do_and_check_cmd cp /tmp/bunkerweb/deps/src/lua-ffi-zlib/lib/ffi-zlib.lua /usr/share/bunkerweb/deps/lib/lua
|
||||
|
||||
# Installing lua-resty-signal
|
||||
echo "ℹ️ Installing lua-resty-signal"
|
||||
CHANGE_DIR="/tmp/bunkerweb/deps/src/lua-resty-signal" do_and_check_cmd make PREFIX=/usr/share/bunkerweb/deps -j $NTASK
|
||||
CHANGE_DIR="/tmp/bunkerweb/deps/src/lua-resty-signal" do_and_check_cmd make PREFIX=/usr/share/bunkerweb/deps LUA_LIB_DIR=/usr/share/bunkerweb/deps/lib/lua install
|
||||
|
||||
# Compile dynamic modules
|
||||
echo "ℹ️ Compiling and installing dynamic modules"
|
||||
CONFARGS="$(nginx -V 2>&1 | sed -n -e 's/^.*arguments: //p')"
|
||||
|
|
|
@ -2,6 +2,12 @@
|
|||
## [Unreleased]
|
||||
|
||||
|
||||
<a name="0.8.22"></a>
|
||||
## [0.8.22] - 2023-04-26
|
||||
### bug fixes
|
||||
- **crypto:** use OPENSSL_free in BoringSSL ([#107](https://github.com/fffonion/lua-resty-openssl/issues/107)) [7830212](https://github.com/fffonion/lua-resty-openssl/commit/78302123ac744f2d0b6de1156e459e9ea72b7edb)
|
||||
|
||||
|
||||
<a name="0.8.21"></a>
|
||||
## [0.8.21] - 2023-03-24
|
||||
### features
|
||||
|
@ -491,7 +497,8 @@
|
|||
- **x509:** export pubkey [ede4f81](https://github.com/fffonion/lua-resty-openssl/commit/ede4f817cb0fe092ad6f9ab5d6ecdcde864a9fd8)
|
||||
|
||||
|
||||
[Unreleased]: https://github.com/fffonion/lua-resty-openssl/compare/0.8.21...HEAD
|
||||
[Unreleased]: https://github.com/fffonion/lua-resty-openssl/compare/0.8.22...HEAD
|
||||
[0.8.22]: https://github.com/fffonion/lua-resty-openssl/compare/0.8.21...0.8.22
|
||||
[0.8.21]: https://github.com/fffonion/lua-resty-openssl/compare/0.8.20...0.8.21
|
||||
[0.8.20]: https://github.com/fffonion/lua-resty-openssl/compare/0.8.19...0.8.20
|
||||
[0.8.19]: https://github.com/fffonion/lua-resty-openssl/compare/0.8.18...0.8.19
|
||||
|
|
|
@ -11,6 +11,7 @@ all: ;
|
|||
|
||||
install: all
|
||||
cp -rpv lib/resty/openssl/. $(DESTDIR)$(LUA_LIB_DIR)/resty/openssl
|
||||
cp -pv lib/resty/openssl.lua $(DESTDIR)$(LUA_LIB_DIR)/resty/
|
||||
|
||||
test: all
|
||||
PATH=$(OPENRESTY_PREFIX)/nginx/sbin:$$PATH prove -I../test-nginx/lib -r t
|
||||
|
|
|
@ -25,7 +25,7 @@ try_require_modules()
|
|||
|
||||
|
||||
local _M = {
|
||||
_VERSION = '0.8.21',
|
||||
_VERSION = '0.8.22',
|
||||
}
|
||||
|
||||
local libcrypto_name
|
||||
|
|
|
@ -3,6 +3,7 @@ local C = ffi.C
|
|||
|
||||
local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10
|
||||
local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER
|
||||
local BORINGSSL = require("resty.openssl.version").BORINGSSL
|
||||
|
||||
local OPENSSL_free
|
||||
if OPENSSL_10 then
|
||||
|
@ -10,6 +11,11 @@ if OPENSSL_10 then
|
|||
void CRYPTO_free(void *ptr);
|
||||
]]
|
||||
OPENSSL_free = C.CRYPTO_free
|
||||
elseif BORINGSSL then
|
||||
ffi.cdef [[
|
||||
void OPENSSL_free(void *ptr);
|
||||
]]
|
||||
OPENSSL_free = C.OPENSSL_free
|
||||
elseif OPENSSL_11_OR_LATER then
|
||||
ffi.cdef [[
|
||||
void CRYPTO_free(void *ptr, const char *file, int line);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package = "lua-resty-openssl"
|
||||
version = "0.8.21-1"
|
||||
version = "0.8.22-1"
|
||||
source = {
|
||||
url = "git+https://github.com/fffonion/lua-resty-openssl.git",
|
||||
tag = "0.8.21"
|
||||
tag = "0.8.22"
|
||||
}
|
||||
description = {
|
||||
detailed = "FFI-based OpenSSL binding for LuaJIT.",
|
|
@ -0,0 +1,9 @@
|
|||
*~
|
||||
*.swp
|
||||
*.swo
|
||||
t/servroot*
|
||||
/go
|
||||
/reindex
|
||||
/a.lua
|
||||
*.o
|
||||
*.so
|
|
@ -0,0 +1,46 @@
|
|||
sudo: required
|
||||
dist: xenial
|
||||
|
||||
os: linux
|
||||
|
||||
language: c
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
env:
|
||||
global:
|
||||
- JOBS=3
|
||||
- NGX_BUILD_JOBS=$JOBS
|
||||
- LUAJIT_PREFIX=/opt/luajit21
|
||||
- LUAJIT_LIB=$LUAJIT_PREFIX/lib
|
||||
- LUAJIT_INC=$LUAJIT_PREFIX/include/luajit-2.1
|
||||
- LD_LIBRARY_PATH=$LUAJIT_LIB:$LD_LIBRARY_PATH
|
||||
matrix:
|
||||
- NGINX_VERSION=1.19.3
|
||||
|
||||
install:
|
||||
- sudo apt-get install -qq -y cpanminus axel
|
||||
- sudo cpanm --notest Test::Nginx > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- git clone https://github.com/openresty/openresty.git ../openresty
|
||||
- git clone https://github.com/openresty/nginx-devel-utils.git
|
||||
- git clone https://github.com/simpl/ngx_devel_kit.git ../ndk-nginx-module
|
||||
- git clone https://github.com/openresty/lua-nginx-module.git ../lua-nginx-module
|
||||
- git clone https://github.com/openresty/lua-resty-core.git ../lua-resty-core
|
||||
- git clone https://github.com/openresty/lua-resty-lrucache.git ../lua-resty-lrucache
|
||||
- git clone https://github.com/openresty/no-pool-nginx.git ../no-pool-nginx
|
||||
- git clone -b v2.1-agentzh https://github.com/openresty/luajit2.git
|
||||
|
||||
script:
|
||||
- make
|
||||
- cd luajit2/
|
||||
- make -j$JOBS CCDEBUG=-g Q= PREFIX=$LUAJIT_PREFIX CC=$CC XCFLAGS='-DLUA_USE_APICHECK -DLUA_USE_ASSERT' > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- sudo make install PREFIX=$LUAJIT_PREFIX > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- cd ..
|
||||
- export PATH=$PWD/work/nginx/sbin:$PWD/nginx-devel-utils:$PATH
|
||||
- export NGX_BUILD_CC=$CC
|
||||
- ngx-build $NGINX_VERSION --with-http_realip_module --add-module=../ndk-nginx-module --add-module=../lua-nginx-module --with-debug > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- nginx -V
|
||||
- ldd `which nginx`|grep -E 'luajit|ssl|pcre'
|
||||
- prove -r t
|
|
@ -0,0 +1,46 @@
|
|||
OPENRESTY_PREFIX=/usr/local/openresty
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
LUA_INCLUDE_DIR ?= $(PREFIX)/include
|
||||
LUA_LIB_DIR ?= $(PREFIX)/lib/lua/$(LUA_VERSION)
|
||||
INSTALL ?= install
|
||||
|
||||
.PHONY: all test install
|
||||
|
||||
SRC := resty_signal.c
|
||||
OBJ := $(SRC:.c=.o)
|
||||
|
||||
C_SO_NAME := librestysignal.so
|
||||
|
||||
CFLAGS := -O3 -g -Wall -fpic
|
||||
|
||||
LDFLAGS := -shared
|
||||
# on Mac OS X, one should set instead:
|
||||
# LDFLAGS := -bundle -undefined dynamic_lookup
|
||||
|
||||
MY_CFLAGS := $(CFLAGS)
|
||||
MY_LDFLAGS := $(LDFLAGS) -fvisibility=hidden
|
||||
|
||||
test := t
|
||||
|
||||
.PHONY = all test clean install
|
||||
|
||||
all : $(C_SO_NAME)
|
||||
|
||||
${OBJ} : %.o : %.c
|
||||
$(CC) $(MY_CFLAGS) -c $<
|
||||
|
||||
${C_SO_NAME} : ${OBJ}
|
||||
$(CC) $(MY_LDFLAGS) $^ -o $@
|
||||
|
||||
#export TEST_NGINX_NO_CLEAN=1
|
||||
|
||||
clean:; rm -f *.o *.so a.out *.d
|
||||
|
||||
install:
|
||||
$(INSTALL) -d $(DESTDIR)$(LUA_LIB_DIR)/resty
|
||||
$(INSTALL) lib/resty/*.lua $(DESTDIR)$(LUA_LIB_DIR)/resty
|
||||
$(INSTALL) $(C_SO_NAME) $(DESTDIR)$(LUA_LIB_DIR)/
|
||||
|
||||
test : all
|
||||
PATH=$(OPENRESTY_PREFIX)/nginx/sbin:$$PATH prove -I../test-nginx/lib -r $(test)
|
|
@ -0,0 +1,132 @@
|
|||
Name
|
||||
====
|
||||
|
||||
lua-resty-signal - Lua library for killing or sending signals to Linux processes
|
||||
|
||||
Table of Contents
|
||||
=================
|
||||
|
||||
* [Name](#name)
|
||||
* [Synopsis](#synopsis)
|
||||
* [Functions](#functions)
|
||||
* [kill](#kill)
|
||||
* [signum](#signum)
|
||||
* [Author](#author)
|
||||
* [Copyright & Licenses](#copyright--licenses)
|
||||
|
||||
Synopsis
|
||||
========
|
||||
|
||||
```lua
|
||||
local resty_signal = require "resty.signal"
|
||||
local pid = 12345
|
||||
|
||||
local ok, err = resty_signal.kill(pid, "TERM")
|
||||
if not ok then
|
||||
ngx.log(ngx.ERR, "failed to kill process of pid ", pid, ": ", err)
|
||||
return
|
||||
end
|
||||
|
||||
-- send the signal 0 to check the existence of a process
|
||||
local ok, err = resty_signal.kill(pid, "NONE")
|
||||
|
||||
local ok, err = resty_signal.kill(pid, "HUP")
|
||||
|
||||
local ok, err = resty_signal.kill(pid, "KILL")
|
||||
```
|
||||
|
||||
Functions
|
||||
=========
|
||||
|
||||
kill
|
||||
----
|
||||
|
||||
**syntax:** `ok, err = resty_signal.kill(pid, signal_name_or_num)`
|
||||
|
||||
Sends a signal with its name string or number value to the process of the
|
||||
specified pid.
|
||||
|
||||
All signal names accepted by [signum](#signum) are supported, like `HUP`,
|
||||
`KILL`, and `TERM`.
|
||||
|
||||
Signal numbers are also supported when specifying nonportable system-specific
|
||||
signals is desired.
|
||||
|
||||
[Back to TOC](#table-of-contents)
|
||||
|
||||
signum
|
||||
------
|
||||
|
||||
**syntax:** `num = resty_signal.signum(sig_name)`
|
||||
|
||||
Maps the signal name specified to the system-specific signal number. Returns
|
||||
`nil` if the signal name is not known.
|
||||
|
||||
All the POSIX and BSD signal names are supported:
|
||||
|
||||
```
|
||||
HUP
|
||||
INT
|
||||
QUIT
|
||||
ILL
|
||||
TRAP
|
||||
ABRT
|
||||
BUS
|
||||
FPE
|
||||
KILL
|
||||
USR1
|
||||
SEGV
|
||||
USR2
|
||||
PIPE
|
||||
ALRM
|
||||
TERM
|
||||
CHLD
|
||||
CONT
|
||||
STOP
|
||||
TSTP
|
||||
TTIN
|
||||
TTOU
|
||||
URG
|
||||
XCPU
|
||||
XFSZ
|
||||
VTALRM
|
||||
PROF
|
||||
WINCH
|
||||
IO
|
||||
PWR
|
||||
EMT
|
||||
SYS
|
||||
INFO
|
||||
```
|
||||
|
||||
The special signal name `NONE` is also supported, which is mapped to zero (0).
|
||||
|
||||
[Back to TOC](#table-of-contents)
|
||||
|
||||
Author
|
||||
======
|
||||
|
||||
Yichun Zhang (agentzh) <yichun@openresty.com>
|
||||
|
||||
[Back to TOC](#table-of-contents)
|
||||
|
||||
Copyright & Licenses
|
||||
====================
|
||||
|
||||
This module is licensed under the BSD license.
|
||||
|
||||
Copyright (C) 2018-2019, [OpenResty Inc.](https://openresty.com)
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
[Back to TOC](#table-of-contents)
|
|
@ -0,0 +1,156 @@
|
|||
local _M = {
|
||||
version = 0.03
|
||||
}
|
||||
|
||||
|
||||
local ffi = require "ffi"
|
||||
local base = require "resty.core.base"
|
||||
|
||||
|
||||
local C = ffi.C
|
||||
local ffi_str = ffi.string
|
||||
local tonumber = tonumber
|
||||
local assert = assert
|
||||
local errno = ffi.errno
|
||||
local type = type
|
||||
local new_tab = base.new_tab
|
||||
local error = error
|
||||
local string_format = string.format
|
||||
|
||||
|
||||
local load_shared_lib
|
||||
do
|
||||
local string_gmatch = string.gmatch
|
||||
local string_match = string.match
|
||||
local io_open = io.open
|
||||
local io_close = io.close
|
||||
|
||||
local cpath = package.cpath
|
||||
|
||||
function load_shared_lib(so_name)
|
||||
local tried_paths = new_tab(32, 0)
|
||||
local i = 1
|
||||
|
||||
for k, _ in string_gmatch(cpath, "[^;]+") do
|
||||
local fpath = string_match(k, "(.*/)")
|
||||
fpath = fpath .. so_name
|
||||
-- Don't get me wrong, the only way to know if a file exist is
|
||||
-- trying to open it.
|
||||
local f = io_open(fpath)
|
||||
if f ~= nil then
|
||||
io_close(f)
|
||||
return ffi.load(fpath)
|
||||
end
|
||||
|
||||
tried_paths[i] = fpath
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
return nil, tried_paths
|
||||
end -- function
|
||||
end -- do
|
||||
|
||||
|
||||
local resty_signal, tried_paths = load_shared_lib("librestysignal.so")
|
||||
if not resty_signal then
|
||||
error("could not load librestysignal.so from the following paths:\n" ..
|
||||
table.concat(tried_paths, "\n"), 2)
|
||||
end
|
||||
|
||||
|
||||
ffi.cdef[[
|
||||
int resty_signal_signum(int num);
|
||||
]]
|
||||
|
||||
|
||||
if not pcall(function () return C.kill end) then
|
||||
ffi.cdef("int kill(int32_t pid, int sig);")
|
||||
end
|
||||
|
||||
|
||||
if not pcall(function () return C.strerror end) then
|
||||
ffi.cdef("char *strerror(int errnum);")
|
||||
end
|
||||
|
||||
|
||||
-- Below is just the ID numbers for each POSIX signal. We map these signal IDs
|
||||
-- to system-specific signal numbers on the C land (via librestysignal.so).
|
||||
local signals = {
|
||||
NONE = 0,
|
||||
HUP = 1,
|
||||
INT = 2,
|
||||
QUIT = 3,
|
||||
ILL = 4,
|
||||
TRAP = 5,
|
||||
ABRT = 6,
|
||||
BUS = 7,
|
||||
FPE = 8,
|
||||
KILL = 9,
|
||||
USR1 = 10,
|
||||
SEGV = 11,
|
||||
USR2 = 12,
|
||||
PIPE = 13,
|
||||
ALRM = 14,
|
||||
TERM = 15,
|
||||
CHLD = 17,
|
||||
CONT = 18,
|
||||
STOP = 19,
|
||||
TSTP = 20,
|
||||
TTIN = 21,
|
||||
TTOU = 22,
|
||||
URG = 23,
|
||||
XCPU = 24,
|
||||
XFSZ = 25,
|
||||
VTALRM = 26,
|
||||
PROF = 27,
|
||||
WINCH = 28,
|
||||
IO = 29,
|
||||
PWR = 30,
|
||||
EMT = 31,
|
||||
SYS = 32,
|
||||
INFO = 33
|
||||
}
|
||||
|
||||
|
||||
local function signum(name)
|
||||
local sig_num
|
||||
if type(name) == "number" then
|
||||
sig_num = name
|
||||
else
|
||||
local id = signals[name]
|
||||
if not id then
|
||||
return nil, "unknown signal name"
|
||||
end
|
||||
|
||||
sig_num = tonumber(resty_signal.resty_signal_signum(id))
|
||||
if sig_num < 0 then
|
||||
error(
|
||||
string_format("missing C def for signal %s = %d", name, id),
|
||||
2
|
||||
)
|
||||
end
|
||||
end
|
||||
return sig_num
|
||||
end
|
||||
|
||||
|
||||
function _M.kill(pid, sig)
|
||||
assert(sig)
|
||||
|
||||
local sig_num, err = signum(sig)
|
||||
if err then
|
||||
return nil, err
|
||||
end
|
||||
|
||||
local rc = tonumber(C.kill(assert(pid), sig_num))
|
||||
if rc == 0 then
|
||||
return true
|
||||
end
|
||||
|
||||
local err = ffi_str(C.strerror(errno()))
|
||||
return nil, err
|
||||
end
|
||||
|
||||
_M.signum = signum
|
||||
|
||||
return _M
|
|
@ -0,0 +1,152 @@
|
|||
#include <signal.h>
|
||||
|
||||
|
||||
enum {
|
||||
RS_NONE = 0,
|
||||
RS_HUP = 1,
|
||||
RS_INT = 2,
|
||||
RS_QUIT = 3,
|
||||
RS_ILL = 4,
|
||||
RS_TRAP = 5,
|
||||
RS_ABRT = 6,
|
||||
RS_BUS = 7,
|
||||
RS_FPE = 8,
|
||||
RS_KILL = 9,
|
||||
RS_USR1 = 10,
|
||||
RS_SEGV = 11,
|
||||
RS_USR2 = 12,
|
||||
RS_PIPE = 13,
|
||||
RS_ALRM = 14,
|
||||
RS_TERM = 15,
|
||||
RS_CHLD = 17,
|
||||
RS_CONT = 18,
|
||||
RS_STOP = 19,
|
||||
RS_TSTP = 20,
|
||||
RS_TTIN = 21,
|
||||
RS_TTOU = 22,
|
||||
RS_URG = 23,
|
||||
RS_XCPU = 24,
|
||||
RS_XFSZ = 25,
|
||||
RS_VTALRM = 26,
|
||||
RS_PROF = 27,
|
||||
RS_WINCH = 28,
|
||||
RS_IO = 29,
|
||||
RS_PWR = 30,
|
||||
RS_EMT = 31,
|
||||
RS_SYS = 32,
|
||||
RS_INFO = 33
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
resty_signal_signum(int num)
|
||||
{
|
||||
switch (num) {
|
||||
|
||||
case RS_NONE:
|
||||
return 0;
|
||||
|
||||
case RS_HUP:
|
||||
return SIGHUP;
|
||||
|
||||
case RS_INT:
|
||||
return SIGINT;
|
||||
|
||||
case RS_QUIT:
|
||||
return SIGQUIT;
|
||||
|
||||
case RS_ILL:
|
||||
return SIGILL;
|
||||
|
||||
case RS_TRAP:
|
||||
return SIGTRAP;
|
||||
|
||||
case RS_ABRT:
|
||||
return SIGABRT;
|
||||
|
||||
case RS_BUS:
|
||||
return SIGBUS;
|
||||
|
||||
case RS_FPE:
|
||||
return SIGFPE;
|
||||
|
||||
case RS_KILL:
|
||||
return SIGKILL;
|
||||
|
||||
case RS_SEGV:
|
||||
return SIGSEGV;
|
||||
|
||||
case RS_PIPE:
|
||||
return SIGPIPE;
|
||||
|
||||
case RS_ALRM:
|
||||
return SIGALRM;
|
||||
|
||||
case RS_TERM:
|
||||
return SIGTERM;
|
||||
|
||||
case RS_CHLD:
|
||||
return SIGCHLD;
|
||||
|
||||
case RS_CONT:
|
||||
return SIGCONT;
|
||||
|
||||
case RS_STOP:
|
||||
return SIGSTOP;
|
||||
|
||||
case RS_TSTP:
|
||||
return SIGTSTP;
|
||||
|
||||
case RS_TTIN:
|
||||
return SIGTTIN;
|
||||
|
||||
case RS_TTOU:
|
||||
return SIGTTOU;
|
||||
|
||||
case RS_XCPU:
|
||||
return SIGXCPU;
|
||||
|
||||
case RS_XFSZ:
|
||||
return SIGXFSZ;
|
||||
|
||||
case RS_VTALRM:
|
||||
return SIGVTALRM;
|
||||
|
||||
case RS_PROF:
|
||||
return SIGPROF;
|
||||
|
||||
case RS_WINCH:
|
||||
return SIGWINCH;
|
||||
|
||||
case RS_IO:
|
||||
return SIGIO;
|
||||
|
||||
#ifdef __linux__
|
||||
case RS_PWR:
|
||||
return SIGPWR;
|
||||
#endif
|
||||
|
||||
case RS_USR1:
|
||||
return SIGUSR1;
|
||||
|
||||
case RS_USR2:
|
||||
return SIGUSR2;
|
||||
|
||||
case RS_URG:
|
||||
return SIGURG;
|
||||
|
||||
#ifdef __APPLE__
|
||||
case RS_EMT:
|
||||
return SIGEMT;
|
||||
|
||||
case RS_SYS:
|
||||
return SIGSYS;
|
||||
|
||||
case RS_INFO:
|
||||
return SIGINFO;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package t::TestKiller;
|
||||
|
||||
use v5.10.1;
|
||||
use Test::Nginx::Socket::Lua -Base;
|
||||
|
||||
add_block_preprocessor(sub {
|
||||
my $block = shift;
|
||||
|
||||
my $http_config = $block->http_config // '';
|
||||
my $init_by_lua_block = $block->init_by_lua_block // 'require "resty.core"';
|
||||
|
||||
$http_config .= <<_EOC_;
|
||||
|
||||
lua_package_path "./lib/?.lua;../lua-resty-core/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;";
|
||||
lua_package_cpath "./?.so;;";
|
||||
init_by_lua_block {
|
||||
$init_by_lua_block
|
||||
}
|
||||
_EOC_
|
||||
|
||||
$block->set_value("http_config", $http_config);
|
||||
|
||||
if (!defined $block->error_log) {
|
||||
$block->set_value("no_error_log", "[error]");
|
||||
}
|
||||
|
||||
if (!defined $block->request) {
|
||||
$block->set_value("request", "GET /t");
|
||||
}
|
||||
});
|
||||
|
||||
1;
|
|
@ -0,0 +1,207 @@
|
|||
# vi:ft=
|
||||
|
||||
use lib '.';
|
||||
use t::TestKiller;
|
||||
|
||||
plan tests => 3 * blocks();
|
||||
|
||||
no_long_string();
|
||||
#no_diff();
|
||||
|
||||
run_tests();
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: returns an error if signal is unknown
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
local resty_signal = require "resty.signal"
|
||||
|
||||
local ok, err = resty_signal.kill(pid, "FOO")
|
||||
if not ok then
|
||||
ngx.say("failed to send FOO signal: ", err)
|
||||
return
|
||||
end
|
||||
ngx.say("ok")
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
failed to send FOO signal: unknown signal name
|
||||
|
||||
|
||||
|
||||
=== TEST 2: send NONE to a non-existing process
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
local resty_signal = require "resty.signal"
|
||||
|
||||
local say = ngx.say
|
||||
local ngx_pipe = require "ngx.pipe"
|
||||
local proc = assert(ngx_pipe.spawn("echo ok"))
|
||||
local pid = assert(proc:pid())
|
||||
assert(proc:wait())
|
||||
|
||||
local ok, err = resty_signal.kill(pid, "NONE")
|
||||
if not ok then
|
||||
ngx.say("failed to send NONE signal: ", err)
|
||||
return
|
||||
end
|
||||
ngx.say("ok")
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
failed to send NONE signal: No such process
|
||||
|
||||
|
||||
|
||||
=== TEST 3: send TERM to a non-existing process
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
local resty_signal = require "resty.signal"
|
||||
|
||||
local say = ngx.say
|
||||
local ngx_pipe = require "ngx.pipe"
|
||||
local proc = assert(ngx_pipe.spawn("echo ok"))
|
||||
local pid = assert(proc:pid())
|
||||
assert(proc:wait())
|
||||
|
||||
local ok, err = resty_signal.kill(pid, "TERM")
|
||||
if not ok then
|
||||
ngx.say("failed to send TERM signal: ", err)
|
||||
return
|
||||
end
|
||||
ngx.say("ok")
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
failed to send TERM signal: No such process
|
||||
|
||||
|
||||
|
||||
=== TEST 4: send NONE to an existing process
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
local resty_signal = require "resty.signal"
|
||||
|
||||
local say = ngx.say
|
||||
local ngx_pipe = require "ngx.pipe"
|
||||
local proc = assert(ngx_pipe.spawn("echo ok"))
|
||||
local pid = assert(proc:pid())
|
||||
-- assert(proc:wait())
|
||||
|
||||
for i = 1, 2 do
|
||||
ngx.say("i = ", i)
|
||||
local ok, err = resty_signal.kill(pid, "NONE")
|
||||
if not ok then
|
||||
ngx.say("failed to send NONE signal: ", err)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
ngx.say("ok")
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
i = 1
|
||||
i = 2
|
||||
ok
|
||||
|
||||
|
||||
|
||||
=== TEST 5: send TERM to an existing process
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
local resty_signal = require "resty.signal"
|
||||
|
||||
local say = ngx.say
|
||||
local ngx_pipe = require "ngx.pipe"
|
||||
local proc = assert(ngx_pipe.spawn("echo ok"))
|
||||
local pid = assert(proc:pid())
|
||||
-- assert(proc:wait())
|
||||
|
||||
for i = 1, 2 do
|
||||
ngx.say("i = ", i)
|
||||
local ok, err = resty_signal.kill(pid, "TERM")
|
||||
if not ok then
|
||||
ngx.say("failed to send TERM signal: ", err)
|
||||
return
|
||||
end
|
||||
ngx.sleep(0.01)
|
||||
end
|
||||
|
||||
ngx.say("ok")
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
i = 1
|
||||
i = 2
|
||||
failed to send TERM signal: No such process
|
||||
|
||||
|
||||
|
||||
=== TEST 6: send KILL to an existing process
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
local resty_signal = require "resty.signal"
|
||||
|
||||
local say = ngx.say
|
||||
local ngx_pipe = require "ngx.pipe"
|
||||
local proc = assert(ngx_pipe.spawn("echo ok"))
|
||||
local pid = assert(proc:pid())
|
||||
-- assert(proc:wait())
|
||||
|
||||
for i = 1, 2 do
|
||||
ngx.say("i = ", i)
|
||||
local ok, err = resty_signal.kill(pid, "KILL")
|
||||
if not ok then
|
||||
ngx.say("failed to send KILL signal: ", err)
|
||||
return
|
||||
end
|
||||
ngx.sleep(0.01)
|
||||
end
|
||||
|
||||
ngx.say("ok")
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
i = 1
|
||||
i = 2
|
||||
failed to send KILL signal: No such process
|
||||
|
||||
|
||||
|
||||
=== TEST 7: send TERM signal value, 15, directly to an existing process
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
local resty_signal = require "resty.signal"
|
||||
|
||||
local say = ngx.say
|
||||
local ngx_pipe = require "ngx.pipe"
|
||||
local proc = assert(ngx_pipe.spawn("echo ok"))
|
||||
local pid = assert(proc:pid())
|
||||
-- assert(proc:wait())
|
||||
|
||||
for i = 1, 2 do
|
||||
ngx.say("i = ", i)
|
||||
local ok, err = resty_signal.kill(pid, 15)
|
||||
if not ok then
|
||||
ngx.say("failed to send TERM signal: ", err)
|
||||
return
|
||||
end
|
||||
ngx.sleep(0.01)
|
||||
end
|
||||
|
||||
ngx.say("ok")
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
i = 1
|
||||
i = 2
|
||||
failed to send TERM signal: No such process
|
|
@ -0,0 +1,35 @@
|
|||
# vi:ft=
|
||||
|
||||
use lib '.';
|
||||
use t::TestKiller;
|
||||
|
||||
plan tests => 3 * blocks();
|
||||
|
||||
no_long_string();
|
||||
#no_diff();
|
||||
|
||||
run_tests();
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: failure to load librestysignal.so
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
local cpath = package.cpath
|
||||
package.cpath = "/foo/?.so;/bar/?.so;"
|
||||
|
||||
local ok, perr = pcall(require, "resty.signal")
|
||||
if not ok then
|
||||
ngx.say(perr)
|
||||
end
|
||||
|
||||
package.cpath = cpath
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
could not load librestysignal.so from the following paths:
|
||||
/foo/librestysignal.so
|
||||
/bar/librestysignal.so
|
||||
--- no_error_log
|
||||
[error]
|
|
@ -0,0 +1,116 @@
|
|||
# vi:ft=
|
||||
|
||||
use lib '.';
|
||||
use t::TestKiller;
|
||||
|
||||
plan tests => 3 * blocks();
|
||||
|
||||
no_long_string();
|
||||
#no_diff();
|
||||
|
||||
run_tests();
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: signals whose values are specified by POSIX
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
local resty_signal = require "resty.signal"
|
||||
local ffi = require "ffi"
|
||||
local say = ngx.say
|
||||
local signum = resty_signal.signum
|
||||
|
||||
for i, signame in ipairs{ "ABRT", "ALRM", "HUP", "INT", "KILL",
|
||||
"QUIT", "TERM", "TRAP", "BLAH" } do
|
||||
say(signame, ": ", tostring(signum(signame)))
|
||||
end
|
||||
|
||||
local linux_signals = {
|
||||
NONE = 0,
|
||||
HUP = 1,
|
||||
INT = 2,
|
||||
QUIT = 3,
|
||||
ILL = 4,
|
||||
TRAP = 5,
|
||||
ABRT = 6,
|
||||
BUS = 7,
|
||||
FPE = 8,
|
||||
KILL = 9,
|
||||
USR1 = 10,
|
||||
SEGV = 11,
|
||||
USR2 = 12,
|
||||
PIPE = 13,
|
||||
ALRM = 14,
|
||||
TERM = 15,
|
||||
CHLD = 17,
|
||||
CONT = 18,
|
||||
STOP = 19,
|
||||
TSTP = 20,
|
||||
TTIN = 21,
|
||||
TTOU = 22,
|
||||
URG = 23,
|
||||
XCPU = 24,
|
||||
XFSZ = 25,
|
||||
VTALRM = 26,
|
||||
PROF = 27,
|
||||
WINCH = 28,
|
||||
IO = 29,
|
||||
PWR = 30
|
||||
}
|
||||
|
||||
local macosx_signals = {
|
||||
HUP = 1,
|
||||
INT = 2,
|
||||
QUIT = 3,
|
||||
ILL = 4,
|
||||
TRAP = 5,
|
||||
ABRT = 6,
|
||||
EMT = 7,
|
||||
FPE = 8,
|
||||
KILL = 9,
|
||||
BUS = 10,
|
||||
SEGV = 11,
|
||||
SYS = 12,
|
||||
PIPE = 13,
|
||||
ALRM = 14,
|
||||
TERM = 15,
|
||||
URG = 16,
|
||||
STOP = 17,
|
||||
TSTP = 18,
|
||||
CONT = 19,
|
||||
CHLD = 20,
|
||||
TTIN = 21,
|
||||
TTOU = 22,
|
||||
IO = 23,
|
||||
XCPU = 24,
|
||||
XFSZ = 25,
|
||||
VTALRM = 26,
|
||||
PROF = 27,
|
||||
WINCH = 28,
|
||||
INFO = 29,
|
||||
USR1 = 30,
|
||||
USR2 = 31
|
||||
}
|
||||
|
||||
if ffi.os == "Linux" then
|
||||
for signame, num in pairs(linux_signals) do
|
||||
assert(num == tonumber(signum(signame)))
|
||||
end
|
||||
elseif ffi.os == "OSX" then
|
||||
for signame, num in pairs(macosx_signals) do
|
||||
assert(num == tonumber(signum(signame)))
|
||||
end
|
||||
end
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
ABRT: 6
|
||||
ALRM: 14
|
||||
HUP: 1
|
||||
INT: 2
|
||||
KILL: 9
|
||||
QUIT: 3
|
||||
TERM: 15
|
||||
TRAP: 5
|
||||
BLAH: nil
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Param
|
||||
epoll_ctl(event)
|
||||
fun:epoll_ctl
|
||||
fun:ngx_epoll_test_rdhup
|
||||
fun:ngx_epoll_init
|
||||
fun:ngx_event_process_init
|
||||
fun:ngx_single_process_cycle
|
||||
fun:main
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: definite
|
||||
fun:malloc
|
||||
fun:ngx_alloc
|
||||
fun:ngx_set_environment
|
||||
fun:ngx_single_process_cycle
|
||||
fun:main
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: definite
|
||||
fun:malloc
|
||||
fun:ngx_alloc
|
||||
fun:ngx_set_environment
|
||||
fun:ngx_worker_process_init
|
||||
}
|
Loading…
Reference in New Issue