mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-02-27 04:06:30 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b338cea90 | ||
|
|
e64a1a1688 | ||
|
|
2ad196b95e | ||
|
|
70c7bcc209 | ||
|
|
890b248563 | ||
|
|
be2de06b09 | ||
|
|
6175e6974c |
@@ -1,7 +1,7 @@
|
|||||||
[bumpversion]
|
[bumpversion]
|
||||||
commit = True
|
commit = True
|
||||||
tag = True
|
tag = True
|
||||||
current_version = 1.6
|
current_version = 1.7
|
||||||
parse = (?P<major>\d+)\.(?P<minor>\d+)(\.(?P<patch>\d+)(\-(?P<release>[a-z]+))?)?
|
parse = (?P<major>\d+)\.(?P<minor>\d+)(\.(?P<patch>\d+)(\-(?P<release>[a-z]+))?)?
|
||||||
serialize =
|
serialize =
|
||||||
{major}.{minor}
|
{major}.{minor}
|
||||||
|
|||||||
9
Makefile
9
Makefile
@@ -44,6 +44,15 @@ override CFLAGS += -DWITH_PTHREAD_NP
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
WITH_SETPROCTITLE ?= 1
|
||||||
|
ifneq ($(call optbool,$(WITH_SETPROCTITLE)),)
|
||||||
|
ifeq ($(shell uname -s | tr A-Z a-z),linux)
|
||||||
|
_LIBS += -lbsd
|
||||||
|
endif
|
||||||
|
override CFLAGS += -DWITH_SETPROCTITLE
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
# =====
|
# =====
|
||||||
all: $(PROG)
|
all: $(PROG)
|
||||||
|
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ If you're going to live-stream from your backyard webcam and need to control it,
|
|||||||
|
|
||||||
-----
|
-----
|
||||||
# Building
|
# Building
|
||||||
You'll need ```make```, ```gcc```, ```libevent``` with ```pthreads``` support, ```libjpeg8```/```libjpeg-turbo``` and ```libuuid```.
|
You'll need ```make```, ```gcc```, ```libevent``` with ```pthreads``` support, ```libjpeg8```/```libjpeg-turbo```, ```libuuid``` and ```libbsd``` (only for Linux).
|
||||||
|
|
||||||
On Raspberry Pi you can build the program with OpenMAX IL. To do this pass option ```WITH_OMX=1``` to ```make```. To enable GPIO support install [wiringPi](http://wiringpi.com) and pass option ```WITH_GPIO=1```. If the compiler reports about a missing function ```pthread_get_name_np()``` (or similar), add option ```WITH_PTHREAD_NP=0``` (it's enabled by default).
|
On Raspberry Pi you can build the program with OpenMAX IL. To do this pass option ```WITH_OMX=1``` to ```make```. To enable GPIO support install [wiringPi](http://wiringpi.com) and pass option ```WITH_GPIO=1```. If the compiler reports about a missing function ```pthread_get_name_np()``` (or similar), add option ```WITH_PTHREAD_NP=0``` (it's enabled by default). For the similar error with ```setproctitle()``` add option ```WITH_SETPROCTITLE=0```.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git clone --depth=1 https://github.com/pikvm/ustreamer
|
$ git clone --depth=1 https://github.com/pikvm/ustreamer
|
||||||
|
|||||||
@@ -30,9 +30,9 @@
|
|||||||
|
|
||||||
-----
|
-----
|
||||||
# Сборка
|
# Сборка
|
||||||
Для сборки вам понадобятся ```make```, ```gcc```, ```libevent``` с поддержкой ```pthreads```, ```libjpeg8```/```libjpeg-turbo``` и ```libuuid```.
|
Для сборки вам понадобятся ```make```, ```gcc```, ```libevent``` с поддержкой ```pthreads```, ```libjpeg8```/```libjpeg-turbo```, ```libuuid``` и ```libbsd``` (только для Linux).
|
||||||
|
|
||||||
На Raspberry Pi программу можно собрать с поддержкой OpenMAX IL. Для этого передайте ```make``` параметр ```WITH_OMX=1```. Для включения сборки с поддержкой GPIO установите [wiringPi](http://wiringpi.com) и добавьте параметр ```WITH_GPIO=1```. Если при сборке компилятор ругается на отсутствие функции ```pthread_get_name_np()``` или другой подобной, добавьте параметр ```WITH_PTHREAD_NP=0``` (по умолчанию он включен).
|
На Raspberry Pi программу можно собрать с поддержкой OpenMAX IL. Для этого передайте ```make``` параметр ```WITH_OMX=1```. Для включения сборки с поддержкой GPIO установите [wiringPi](http://wiringpi.com) и добавьте параметр ```WITH_GPIO=1```. Если при сборке компилятор ругается на отсутствие функции ```pthread_get_name_np()``` или другой подобной, добавьте параметр ```WITH_PTHREAD_NP=0``` (по умолчанию он включен). При аналогичной ошибке с функцией ```setproctitle()``` добавьте параметр ```WITH_SETPROCTITLE=0```.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git clone --depth=1 https://github.com/pikvm/ustreamer
|
$ git clone --depth=1 https://github.com/pikvm/ustreamer
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
|
|
||||||
|
|
||||||
pkgname=ustreamer
|
pkgname=ustreamer
|
||||||
pkgver=1.6
|
pkgver=1.7
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="Lightweight and fast MJPG-HTTP streamer"
|
pkgdesc="Lightweight and fast MJPG-HTTP streamer"
|
||||||
url="https://github.com/pikvm/ustreamer"
|
url="https://github.com/pikvm/ustreamer"
|
||||||
license=(GPL)
|
license=(GPL)
|
||||||
arch=(i686 x86_64 armv6h armv7h)
|
arch=(i686 x86_64 armv6h armv7h)
|
||||||
depends=(libjpeg libevent libutil-linux)
|
depends=(libjpeg libevent libutil-linux libbsd)
|
||||||
# optional: raspberrypi-firmware for OMX encoder
|
# optional: raspberrypi-firmware for OMX encoder
|
||||||
# optional: wiringpi for GPIO support
|
# optional: wiringpi for GPIO support
|
||||||
makedepends=(gcc make)
|
makedepends=(gcc make)
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ DEPEND="
|
|||||||
>=dev-libs/libevent-2.1.8
|
>=dev-libs/libevent-2.1.8
|
||||||
>=media-libs/libjpeg-turbo-1.5.3
|
>=media-libs/libjpeg-turbo-1.5.3
|
||||||
>=sys-apps/util-linux-2.33
|
>=sys-apps/util-linux-2.33
|
||||||
|
>=dev-libs/libbsd-0.9.1
|
||||||
"
|
"
|
||||||
RDEPEND="${DEPEND}"
|
RDEPEND="${DEPEND}"
|
||||||
BDEPEND=""
|
BDEPEND=""
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=ustreamer
|
PKG_NAME:=ustreamer
|
||||||
PKG_VERSION:=1.6
|
PKG_VERSION:=1.7
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
PKG_MAINTAINER:=Maxim Devaev <mdevaev@gmail.com>
|
PKG_MAINTAINER:=Maxim Devaev <mdevaev@gmail.com>
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ define Package/ustreamer
|
|||||||
SECTION:=multimedia
|
SECTION:=multimedia
|
||||||
CATEGORY:=Multimedia
|
CATEGORY:=Multimedia
|
||||||
TITLE:=uStreamer
|
TITLE:=uStreamer
|
||||||
DEPENDS:=+libpthread +libjpeg +libv4l +libuuid +libevent2 +libevent2-core +libevent2-extra +libevent2-pthreads
|
DEPENDS:=+libpthread +libjpeg +libv4l +libuuid +libbsd +libevent2 +libevent2-core +libevent2-extra +libevent2-pthreads
|
||||||
URL:=https://github.com/pikvm/ustreamer
|
URL:=https://github.com/pikvm/ustreamer
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
|||||||
@@ -23,5 +23,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef VERSION
|
#ifndef VERSION
|
||||||
# define VERSION "1.6"
|
# define VERSION "1.7"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ char *simplify_request_path(const char *str) {
|
|||||||
return simplified;
|
return simplified;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TEST_HTTP_PATH
|
#ifdef TEST_HTTP_PATH
|
||||||
|
|
||||||
int test_simplify_request_path(const char *sample, const char *expected) {
|
int test_simplify_request_path(const char *sample, const char *expected) {
|
||||||
char *result = simplify_request_path(sample);
|
char *result = simplify_request_path(sample);
|
||||||
|
|||||||
@@ -111,6 +111,9 @@ enum _OPT_VALUES {
|
|||||||
#ifdef HAS_PDEATHSIG
|
#ifdef HAS_PDEATHSIG
|
||||||
_O_EXIT_ON_PARENT_DEATH,
|
_O_EXIT_ON_PARENT_DEATH,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WITH_SETPROCTITLE
|
||||||
|
_O_PROCESS_NAME_PREFIX,
|
||||||
|
#endif
|
||||||
|
|
||||||
_O_LOG_LEVEL,
|
_O_LOG_LEVEL,
|
||||||
_O_PERF,
|
_O_PERF,
|
||||||
@@ -118,6 +121,8 @@ enum _OPT_VALUES {
|
|||||||
_O_DEBUG,
|
_O_DEBUG,
|
||||||
_O_FORCE_LOG_COLORS,
|
_O_FORCE_LOG_COLORS,
|
||||||
_O_NO_LOG_COLORS,
|
_O_NO_LOG_COLORS,
|
||||||
|
|
||||||
|
_O_FEATURES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct option _LONG_OPTS[] = {
|
static const struct option _LONG_OPTS[] = {
|
||||||
@@ -179,6 +184,9 @@ static const struct option _LONG_OPTS[] = {
|
|||||||
#ifdef HAS_PDEATHSIG
|
#ifdef HAS_PDEATHSIG
|
||||||
{"exit-on-parent-death", no_argument, NULL, _O_EXIT_ON_PARENT_DEATH},
|
{"exit-on-parent-death", no_argument, NULL, _O_EXIT_ON_PARENT_DEATH},
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WITH_SETPROCTITLE
|
||||||
|
{"process-name-prefix", required_argument, NULL, _O_PROCESS_NAME_PREFIX},
|
||||||
|
#endif
|
||||||
|
|
||||||
{"log-level", required_argument, NULL, _O_LOG_LEVEL},
|
{"log-level", required_argument, NULL, _O_LOG_LEVEL},
|
||||||
{"perf", no_argument, NULL, _O_PERF},
|
{"perf", no_argument, NULL, _O_PERF},
|
||||||
@@ -189,6 +197,7 @@ static const struct option _LONG_OPTS[] = {
|
|||||||
|
|
||||||
{"help", no_argument, NULL, _O_HELP},
|
{"help", no_argument, NULL, _O_HELP},
|
||||||
{"version", no_argument, NULL, _O_VERSION},
|
{"version", no_argument, NULL, _O_VERSION},
|
||||||
|
{"features", no_argument, NULL, _O_FEATURES},
|
||||||
|
|
||||||
{NULL, 0, NULL, 0},
|
{NULL, 0, NULL, 0},
|
||||||
};
|
};
|
||||||
@@ -199,7 +208,7 @@ static int _parse_resolution(const char *str, unsigned *width, unsigned *height,
|
|||||||
static int _parse_glitched_resolutions(const char *str, struct encoder_t *encoder);
|
static int _parse_glitched_resolutions(const char *str, struct encoder_t *encoder);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void _version(bool nl);
|
static void _features(void);
|
||||||
static void _help(struct device_t *dev, struct encoder_t *encoder, struct http_server_t *server);
|
static void _help(struct device_t *dev, struct encoder_t *encoder, struct http_server_t *server);
|
||||||
|
|
||||||
|
|
||||||
@@ -236,15 +245,6 @@ int parse_options(int argc, char *argv[], struct device_t *dev, struct encoder_t
|
|||||||
break; \
|
break; \
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifdef WITH_OMX
|
|
||||||
# define OPT_GLITCHED_RESOLUTIONS { \
|
|
||||||
if (_parse_glitched_resolutions(optarg, encoder) < 0) { \
|
|
||||||
return -1; \
|
|
||||||
} \
|
|
||||||
break; \
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# define OPT_PARSE(_name, _dest, _func, _invalid, _available) { \
|
# define OPT_PARSE(_name, _dest, _func, _invalid, _available) { \
|
||||||
if ((_dest = _func(optarg)) == _invalid) { \
|
if ((_dest = _func(optarg)) == _invalid) { \
|
||||||
printf("Unknown " _name ": %s; available: %s\n", optarg, _available); \
|
printf("Unknown " _name ": %s; available: %s\n", optarg, _available); \
|
||||||
@@ -270,6 +270,9 @@ int parse_options(int argc, char *argv[], struct device_t *dev, struct encoder_t
|
|||||||
int short_index;
|
int short_index;
|
||||||
int opt_index;
|
int opt_index;
|
||||||
char short_opts[1024] = {0};
|
char short_opts[1024] = {0};
|
||||||
|
# ifdef WITH_SETPROCTITLE
|
||||||
|
char *process_name_prefix = NULL;
|
||||||
|
# endif
|
||||||
|
|
||||||
for (short_index = 0, opt_index = 0; _LONG_OPTS[opt_index].name != NULL; ++opt_index) {
|
for (short_index = 0, opt_index = 0; _LONG_OPTS[opt_index].name != NULL; ++opt_index) {
|
||||||
if (isalpha(_LONG_OPTS[opt_index].val)) {
|
if (isalpha(_LONG_OPTS[opt_index].val)) {
|
||||||
@@ -301,7 +304,11 @@ int parse_options(int argc, char *argv[], struct device_t *dev, struct encoder_t
|
|||||||
case _O_QUALITY: OPT_NUMBER("--quality", encoder->quality, 1, 100, 0);
|
case _O_QUALITY: OPT_NUMBER("--quality", encoder->quality, 1, 100, 0);
|
||||||
case _O_ENCODER: OPT_PARSE("encoder type", encoder->type, encoder_parse_type, ENCODER_TYPE_UNKNOWN, ENCODER_TYPES_STR);
|
case _O_ENCODER: OPT_PARSE("encoder type", encoder->type, encoder_parse_type, ENCODER_TYPE_UNKNOWN, ENCODER_TYPES_STR);
|
||||||
# ifdef WITH_OMX
|
# ifdef WITH_OMX
|
||||||
case _O_GLITCHED_RESOLUTIONS: OPT_GLITCHED_RESOLUTIONS;
|
case _O_GLITCHED_RESOLUTIONS:
|
||||||
|
if (_parse_glitched_resolutions(optarg, encoder) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
# endif
|
# endif
|
||||||
case _O_DEVICE_TIMEOUT: OPT_NUMBER("--device-timeout", dev->timeout, 1, 60, 0);
|
case _O_DEVICE_TIMEOUT: OPT_NUMBER("--device-timeout", dev->timeout, 1, 60, 0);
|
||||||
case _O_DEVICE_ERROR_DELAY: OPT_NUMBER("--device-error-delay", dev->error_delay, 1, 60, 0);
|
case _O_DEVICE_ERROR_DELAY: OPT_NUMBER("--device-error-delay", dev->error_delay, 1, 60, 0);
|
||||||
@@ -343,7 +350,14 @@ int parse_options(int argc, char *argv[], struct device_t *dev, struct encoder_t
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef HAS_PDEATHSIG
|
# ifdef HAS_PDEATHSIG
|
||||||
case _O_EXIT_ON_PARENT_DEATH: process_set_pdeathsig_sigterm(); break;
|
case _O_EXIT_ON_PARENT_DEATH:
|
||||||
|
if (process_track_parent_death() < 0) {
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
# endif
|
||||||
|
# ifdef WITH_SETPROCTITLE
|
||||||
|
case _O_PROCESS_NAME_PREFIX: OPT_SET(process_name_prefix, optarg);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
case _O_LOG_LEVEL: OPT_NUMBER("--log-level", log_level, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, 0);
|
case _O_LOG_LEVEL: OPT_NUMBER("--log-level", log_level, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, 0);
|
||||||
@@ -354,19 +368,23 @@ int parse_options(int argc, char *argv[], struct device_t *dev, struct encoder_t
|
|||||||
case _O_NO_LOG_COLORS: OPT_SET(log_colored, false);
|
case _O_NO_LOG_COLORS: OPT_SET(log_colored, false);
|
||||||
|
|
||||||
case _O_HELP: _help(dev, encoder, server); return 1;
|
case _O_HELP: _help(dev, encoder, server); return 1;
|
||||||
case _O_VERSION: _version(true); return 1;
|
case _O_VERSION: puts(VERSION); return 1;
|
||||||
|
case _O_FEATURES: _features(); return 1;
|
||||||
|
|
||||||
case 0: break;
|
case 0: break;
|
||||||
default: _help(dev, encoder, server); return -1;
|
default: _help(dev, encoder, server); return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef WITH_SETPROCTITLE
|
||||||
|
if (process_name_prefix != NULL) {
|
||||||
|
process_set_name_prefix(argc, argv, process_name_prefix);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
# undef OPT_CTL_AUTO
|
# undef OPT_CTL_AUTO
|
||||||
# undef OPT_CTL
|
# undef OPT_CTL
|
||||||
# undef OPT_PARSE
|
# undef OPT_PARSE
|
||||||
# ifdef WITH_OMX
|
|
||||||
# undef OPT_GLITCHED_RESOLUTIONS
|
|
||||||
# endif
|
|
||||||
# undef OPT_RESOLUTION
|
# undef OPT_RESOLUTION
|
||||||
# undef OPT_NUMBER
|
# undef OPT_NUMBER
|
||||||
# undef OPT_SET
|
# undef OPT_SET
|
||||||
@@ -443,25 +461,42 @@ static int _parse_glitched_resolutions(const char *str, struct encoder_t *encode
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void _version(bool nl) {
|
static void _features(void) {
|
||||||
printf(VERSION);
|
|
||||||
# ifdef WITH_OMX
|
# ifdef WITH_OMX
|
||||||
printf(" + OMX");
|
puts("+ WITH_OMX");
|
||||||
|
# else
|
||||||
|
puts("- WITH_OMX");
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef WITH_GPIO
|
# ifdef WITH_GPIO
|
||||||
printf(" + GPIO");
|
puts("+ WITH_GPIO");
|
||||||
|
# else
|
||||||
|
puts("- WITH_GPIO");
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef WITH_PTHREAD_NP
|
||||||
|
puts("+ WITH_PTHREAD_NP");
|
||||||
|
# else
|
||||||
|
puts("- WITH_PTHREAD_NP");
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef WITH_SETPROCTITLE
|
||||||
|
puts("+ WITH_SETPROCTITLE");
|
||||||
|
# else
|
||||||
|
puts("- WITH_SETPROCTITLE");
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef HAS_PDEATHSIG
|
||||||
|
puts("+ HAS_PDEATHSIG");
|
||||||
|
# else
|
||||||
|
puts("- HAS_PDEATHSIG");
|
||||||
# endif
|
# endif
|
||||||
if (nl) {
|
|
||||||
putchar('\n');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _help(struct device_t *dev, struct encoder_t *encoder, struct http_server_t *server) {
|
static void _help(struct device_t *dev, struct encoder_t *encoder, struct http_server_t *server) {
|
||||||
printf("\nuStreamer - Lightweight and fast MJPG-HTTP streamer\n");
|
printf("\nuStreamer - Lightweight and fast MJPG-HTTP streamer\n");
|
||||||
printf("═══════════════════════════════════════════════════\n\n");
|
printf("═══════════════════════════════════════════════════\n\n");
|
||||||
printf("Version: ");
|
printf("Version: %s; license: GPLv3\n", VERSION);
|
||||||
_version(false);
|
|
||||||
printf("; license: GPLv3\n");
|
|
||||||
printf("Copyright (C) 2018 Maxim Devaev <mdevaev@gmail.com>\n\n");
|
printf("Copyright (C) 2018 Maxim Devaev <mdevaev@gmail.com>\n\n");
|
||||||
printf("Capturing options:\n");
|
printf("Capturing options:\n");
|
||||||
printf("══════════════════\n");
|
printf("══════════════════\n");
|
||||||
@@ -552,10 +587,16 @@ static void _help(struct device_t *dev, struct encoder_t *encoder, struct http_s
|
|||||||
printf(" --gpio-workers-busy-at <pin> ── Set 1 on (pin + N) while worker with number N has a job.\n");
|
printf(" --gpio-workers-busy-at <pin> ── Set 1 on (pin + N) while worker with number N has a job.\n");
|
||||||
printf(" The worker's numbering starts from 0. Default: disabled\n\n");
|
printf(" The worker's numbering starts from 0. Default: disabled\n\n");
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_PDEATHSIG
|
#if (defined(HAS_PDEATHSIG) || defined(WITH_SETPROCTITLE))
|
||||||
printf("Process options:\n");
|
printf("Process options:\n");
|
||||||
printf("════════════════\n");
|
printf("════════════════\n");
|
||||||
printf(" --exit-on-parent-death ─ Exit the program if the parent process is dead. Default: disabled.\n\n");
|
#endif
|
||||||
|
#ifdef HAS_PDEATHSIG
|
||||||
|
printf(" --exit-on-parent-death ─────── Exit the program if the parent process is dead. Default: disabled.\n\n");
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_SETPROCTITLE
|
||||||
|
printf(" --process-name-prefix <str> ── Set process name prefix which will be displayed in the process list\n");
|
||||||
|
printf(" like '<str>: ustreamer --blah-blah-blah'. Default: disabled.\n\n");
|
||||||
#endif
|
#endif
|
||||||
printf("Logging options:\n");
|
printf("Logging options:\n");
|
||||||
printf("════════════════\n");
|
printf("════════════════\n");
|
||||||
@@ -572,4 +613,5 @@ static void _help(struct device_t *dev, struct encoder_t *encoder, struct http_s
|
|||||||
printf("═════════════\n");
|
printf("═════════════\n");
|
||||||
printf(" -h|--help ─────── Print this text and exit.\n\n");
|
printf(" -h|--help ─────── Print this text and exit.\n\n");
|
||||||
printf(" -v|--version ──── Print version and exit.\n\n");
|
printf(" -v|--version ──── Print version and exit.\n\n");
|
||||||
|
printf(" --features ────── Print list of supporeted features.\n\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,29 +31,100 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAS_PDEATHSIG
|
#ifdef HAS_PDEATHSIG
|
||||||
# include <signal.h>
|
# include <signal.h>
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_SETPROCTITLE
|
||||||
|
# include <stdlib.h>
|
||||||
|
# include <string.h>
|
||||||
|
# if defined(__linux__)
|
||||||
|
# include <bsd/unistd.h>
|
||||||
|
# include <sys/types.h>
|
||||||
|
# elif (defined(__FreeBSD__) || defined(__DragonFly__))
|
||||||
|
# include <unistd.h>
|
||||||
|
# include <sys/types.h>
|
||||||
|
# elif (defined(__NetBSD__) || defined(__OpenBSD__)) // setproctitle() placed in stdlib.h
|
||||||
|
# else
|
||||||
|
# error setproctitle() not implemented, you can disable it using WITH_SETPROCTITLE=0
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#ifdef HAS_PDEATHSIG
|
||||||
# if defined(__linux__)
|
# if defined(__linux__)
|
||||||
# include <sys/prctl.h>
|
# include <sys/prctl.h>
|
||||||
# elif defined(__FreeBSD__)
|
# elif defined(__FreeBSD__)
|
||||||
# include <sys/procctl.h>
|
# include <sys/procctl.h>
|
||||||
# endif
|
# endif
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_SETPROCTITLE
|
||||||
|
# include "tools.h"
|
||||||
|
#endif
|
||||||
|
#ifdef HAS_PDEATHSIG
|
||||||
# include "logging.h"
|
# include "logging.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
INLINE void process_set_pdeathsig_sigterm(void) {
|
|
||||||
|
#ifdef WITH_SETPROCTITLE
|
||||||
|
extern char **environ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAS_PDEATHSIG
|
||||||
|
INLINE int process_track_parent_death(void) {
|
||||||
int signum = SIGTERM;
|
int signum = SIGTERM;
|
||||||
# ifdef __linux__
|
# if defined(__linux__)
|
||||||
int retval = prctl(PR_SET_PDEATHSIG, signum);
|
int retval = prctl(PR_SET_PDEATHSIG, signum);
|
||||||
# elif __FreeBSD__
|
# elif defined(__FreeBSD__)
|
||||||
int retval = procctl(P_PID, 0, PROC_PDEATHSIG_CTL, &signum);
|
int retval = procctl(P_PID, 0, PROC_PDEATHSIG_CTL, &signum);
|
||||||
# else
|
# else
|
||||||
# error WTF?
|
# error WTF?
|
||||||
# endif
|
# endif
|
||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
LOG_PERROR("Can't set to receive SIGTERM on parent process death");
|
LOG_PERROR("Can't set to receive SIGTERM on parent process death");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif // HAS_PDEATHSIG
|
if (kill(getppid(), 0) < 0) {
|
||||||
|
LOG_PERROR("The parent process is already dead");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_SETPROCTITLE
|
||||||
|
# pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||||
|
# pragma GCC diagnostic push
|
||||||
|
INLINE void process_set_name_prefix(int argc, char *argv[], const char *prefix) {
|
||||||
|
# pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
char *cmdline = NULL;
|
||||||
|
size_t allocated = 2048;
|
||||||
|
size_t used = 0;
|
||||||
|
size_t arg_len = 0;
|
||||||
|
|
||||||
|
A_REALLOC(cmdline, allocated);
|
||||||
|
cmdline[0] = '\0';
|
||||||
|
|
||||||
|
for (int index = 0; index < argc; ++index) {
|
||||||
|
arg_len = strlen(argv[index]);
|
||||||
|
if (used + arg_len + 16 >= allocated) {
|
||||||
|
allocated += arg_len + 2048;
|
||||||
|
A_REALLOC(cmdline, allocated);
|
||||||
|
}
|
||||||
|
|
||||||
|
strcat(cmdline, " ");
|
||||||
|
strcat(cmdline, argv[index]);
|
||||||
|
used = strlen(cmdline); // Не считаем вручную, так надежнее
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifdef __linux__
|
||||||
|
setproctitle_init(argc, argv, environ);
|
||||||
|
# endif
|
||||||
|
setproctitle("-%s:%s", prefix, cmdline);
|
||||||
|
|
||||||
|
free(cmdline);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user