commit 6b1d371b95b67c1490abf30c3bffe34a3f591e97
| author | 斟酌 鵬兄 <tgckpg@gmail.com> |
| date | 2026-05-26T12:10:09Z |
| subject | Basic signal handling |
commit 6b1d371b95b67c1490abf30c3bffe34a3f591e97
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date: 2026-05-26T12:10:09Z
Basic signal handling
---
Dockerfile | 9 ++++----
Makefile | 52 +++++++++++++++++++++++--------------------
signal.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
signal.h | 14 ++++++++++++
tinyproxy.c | 11 ++++++++++
5 files changed, 130 insertions(+), 29 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index b846dd6..9d7b853 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -8,10 +8,10 @@ WORKDIR /src
COPY [ "*.c", "*.h", "*.conf", "Makefile", "/src" ]
-RUN make all
+RUN make all STATIC=1
COPY tests ./tests
-RUN STATIC=1 make test
+RUN make test STATIC=1
RUN cp /src/tinyproxy.conf /etc/ && cp /src/bin/tinyproxy /usr/bin/
@@ -20,6 +20,5 @@ FROM scratch
COPY --from=build /src/bin/tinyproxy /usr/bin/tinyproxy
COPY --from=build /src/tinyproxy.conf /etc/tinyproxy.conf
-RUN /usr/bin/tinyproxy
-
-CMD [ "tinyproxy", "-c", "/etc/tinyproxy.conf" ]
+ENTRYPOINT ["/usr/bin/tinyproxy"]
+CMD ["-c", "/etc/tinyproxy.conf"]
diff --git a/Makefile b/Makefile
index 69433c7..ed1d3b5 100644
--- a/Makefile
+++ b/Makefile
@@ -1,18 +1,18 @@
export
CC ?= cc
-AR := /usr/bin/ar
-RANLIB := /usr/bin/ranlib
+AR ?= ar
+RANLIB ?= ranlib
STRIP ?= strip
-STATIC ?= 1
PROJECT_ROOT := $(CURDIR)
BIN_DIR := $(CURDIR)/bin
SRC := klog.c \
- proxy_proto_v2.c \
- route.c \
- tcp_route.c \
+ proxy_proto_v2.c \
+ signal.c \
+ route.c \
+ tcp_route.c \
file_conf.c \
tinyproxy.c
@@ -20,29 +20,37 @@ BIN := $(BIN_DIR)/tinyproxy
BUILD_DIR := $(PROJECT_ROOT)/build
-# Optional. Set this only when you want to build vendored libevent.
-# Example:
-# make LIBEVENT_SRC=$(PROJECT_ROOT)/libevent2
LIBEVENT_SRC ?=
-
LIBEVENT_PREFIX := $(BUILD_DIR)/libevent-install
LIBEVENT_CORE_A := $(LIBEVENT_PREFIX)/lib/libevent_core.a
CFLAGS ?= -Os -Wall -Wextra -ffunction-sections -fdata-sections
+UNAME_S := $(shell uname)
+
+ifeq ($(UNAME_S),Darwin)
+STATIC ?= 0
+LDFLAGS += -Wl,-dead_strip
+TEST_FLAGS := CONCURRENCY=1000 TOTAL=1000 FD_LIMIT=2560
+else
+STATIC ?= 1
+LDFLAGS += -Wl,--gc-sections
+TEST_FLAGS :=
+endif
+
ifeq ($(STATIC),1)
LDFLAGS += -static
PKG_CONFIG_STATIC := --static
+else
+PKG_CONFIG_STATIC :=
endif
ifeq ($(strip $(LIBEVENT_SRC)),)
-# System libevent, statically linked
LIBEVENT_CPPFLAGS := $(shell pkg-config --cflags libevent_core)
LIBEVENT_LDFLAGS :=
-LIBEVENT_LDLIBS := $(shell pkg-config --static --libs libevent_core)
+LIBEVENT_LDLIBS := $(shell pkg-config $(PKG_CONFIG_STATIC) --libs libevent_core)
LIBEVENT_DEPS :=
else
-# Vendored libevent
LIBEVENT_CPPFLAGS := -I$(LIBEVENT_PREFIX)/include
LIBEVENT_LDFLAGS := -L$(LIBEVENT_PREFIX)/lib
LIBEVENT_LDLIBS := -levent_core
@@ -50,9 +58,11 @@ LIBEVENT_DEPS := $(LIBEVENT_CORE_A)
endif
CPPFLAGS += $(LIBEVENT_CPPFLAGS)
-LDFLAGS += -static $(LIBEVENT_LDFLAGS)
+LDFLAGS += $(LIBEVENT_LDFLAGS)
LDLIBS += $(LIBEVENT_LDLIBS)
+all: $(BIN)
+
$(BIN): $(SRC) $(LIBEVENT_DEPS)
mkdir -p $(BIN_DIR)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(SRC) $(LDFLAGS) $(LDLIBS)
@@ -75,18 +85,12 @@ $(LIBEVENT_CORE_A):
AR=$(AR) RANLIB=$(RANLIB) $(MAKE) -C $(LIBEVENT_SRC) install
endif
-ifeq ($(shell uname),Darwin)
-LDFLAGS += -Wl,-dead_strip
-TEST_FLAGS := CONCURRENCY=1000 TOTAL=1000 FD_LIMIT=2560
-else
-LDFLAGS += -Wl,--gc-sections
-TEST_FLAGS :=
-endif
-
-all: $(BIN)
-
strip: $(BIN)
+ifeq ($(UNAME_S),Darwin)
+ $(error strip target is not supported on macOS; build without stripping, or strip inside the Linux/Alpine container)
+else
$(STRIP) $(BIN)
+endif
test: $(BIN)
$(TEST_FLAGS) python3 tests/test_proxy.py $(BIN)
diff --git a/signal.c b/signal.c
new file mode 100644
index 0000000..2e23425
--- /dev/null
+++ b/signal.c
@@ -0,0 +1,73 @@
+#include "signal.h"
+
+#include <signal.h>
+#include <string.h>
+
+#include "klog.h"
+
+static void signal_cb(evutil_socket_t sig, short events, void *arg)
+{
+ (void)events;
+
+ struct event_base *base = arg;
+
+ switch (sig) {
+ case SIGINT:
+ LOG_INFO("received signal, shutting down", "signal", "SIGINT");
+ break;
+ case SIGTERM:
+ LOG_INFO("received signal, shutting down", "signal", "SIGTERM");
+ break;
+ default:
+ LOG_INFO("received signal, shutting down", "signal", "unknown");
+ break;
+ }
+
+ event_base_loopbreak(base);
+}
+
+int setup_signal_handlers(struct event_base *base, struct signal_events *signals)
+{
+ if (base == NULL || signals == NULL) {
+ return -1;
+ }
+
+ memset(signals, 0, sizeof(*signals));
+
+ signals->sigint_ev = evsignal_new(base, SIGINT, signal_cb, base);
+ if (signals->sigint_ev == NULL) {
+ free_signal_handlers(signals);
+ return -1;
+ }
+
+ signals->sigterm_ev = evsignal_new(base, SIGTERM, signal_cb, base);
+ if (signals->sigterm_ev == NULL) {
+ free_signal_handlers(signals);
+ return -1;
+ }
+
+ if (event_add(signals->sigint_ev, NULL) != 0) {
+ free_signal_handlers(signals);
+ return -1;
+ }
+
+ if (event_add(signals->sigterm_ev, NULL) != 0) {
+ free_signal_handlers(signals);
+ return -1;
+ }
+
+ return 0;
+}
+
+void free_signal_handlers(struct signal_events *signals)
+{
+ if (signals == NULL) {
+ return;
+ }
+
+ event_free(signals->sigint_ev);
+ event_free(signals->sigterm_ev);
+
+ signals->sigint_ev = NULL;
+ signals->sigterm_ev = NULL;
+}
diff --git a/signal.h b/signal.h
new file mode 100644
index 0000000..abfb370
--- /dev/null
+++ b/signal.h
@@ -0,0 +1,14 @@
+#ifndef SIGNAL_H
+#define SIGNAL_H
+
+#include <event2/event.h>
+
+struct signal_events {
+ struct event *sigint_ev;
+ struct event *sigterm_ev;
+};
+
+int setup_signal_handlers(struct event_base *base, struct signal_events *signals);
+void free_signal_handlers(struct signal_events *signals);
+
+#endif
diff --git a/tinyproxy.c b/tinyproxy.c
index 171e483..e831c5b 100644
--- a/tinyproxy.c
+++ b/tinyproxy.c
@@ -7,6 +7,7 @@
#include <unistd.h>
#include "klog.h"
+#include "signal.h"
#include "file_conf.h"
#include "tcp_route.h"
@@ -86,6 +87,15 @@ int main(int argc, char **argv)
return 1;
}
+ struct signal_events signals;
+
+ if (setup_signal_handlers(base, &signals) != 0) {
+ LOG_ERROR("failed to setup signal handlers");
+ event_base_free(base);
+ free_routes(routes);
+ return 1;
+ }
+
struct worker w = {
.base = base,
.id = 0,
@@ -137,6 +147,7 @@ int main(int argc, char **argv)
free_tcp_route(tcp_ctxs[i]);
}
+ free_signal_handlers(&signals);
free(tcp_ctxs);
event_base_free(base);
free_routes(routes);