summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2016-05-25 20:54:21 (GMT)
committerChristian Pointner <equinox@spreadspace.org>2016-05-25 20:54:21 (GMT)
commit0c4e68d5afb47b2e378cf782f289c328c05a11d3 (patch)
treebb761f3e6509bd52fcecf58ec4a6c5d3dfa4e37f
parent69aff9a20479a97fa4a29b0e36ad4195785f424e (diff)
major cleanup and refactoring
-rw-r--r--src/Makefile1
-rwxr-xr-xsrc/configure23
-rw-r--r--src/daemon.h6
-rw-r--r--src/gstdvbbackend.c19
-rw-r--r--src/log.c31
-rw-r--r--src/log.h4
-rw-r--r--src/log_targets.h3
-rw-r--r--src/options.c6
-rw-r--r--src/sig_handler.c110
-rw-r--r--src/sig_handler.h35
-rw-r--r--src/streamer.c50
-rw-r--r--src/streamer.h1
-rw-r--r--src/sysexec.c5
13 files changed, 91 insertions, 203 deletions
diff --git a/src/Makefile b/src/Makefile
index 17b47be..ad05106 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -30,7 +30,6 @@ endif
EXECUTABLE := gstdvbbackend
C_OBJS := log.o \
- sig_handler.o \
options.o \
slist.o \
string_list.o \
diff --git a/src/configure b/src/configure
index 2752afa..0bbd66c 100755
--- a/src/configure
+++ b/src/configure
@@ -28,9 +28,7 @@ set -e
TARGET=`uname -s`
EBUILD_COMPAT=0
-
-CFLAGS='-g -O2'
-LDFLAGS='-g -Wall -O2'
+USE_CLANG=0
PREFIX='/usr/local'
BINDIR=''
@@ -64,6 +62,9 @@ do
--no-manpage)
INSTALLMANPAGE=0
;;
+ --use-clang)
+ USE_CLANG=1
+ ;;
--ebuild-compat)
EBUILD_COMPAT=1
;;
@@ -86,8 +87,18 @@ if [ -n "$ERRORS" ] && [ $EBUILD_COMPAT -ne 1 ]; then
exit 1
fi
-CFLAGS="$CFLAGS $(pkg-config --cflags gstreamer-0.10)"
-LDFLAGS="$LDFLAGS $(pkg-config --libs gstreamer-0.10)"
+if [ $USE_CLANG -eq 0 ]; then
+ CFLAGS='-g -Wall -O2'
+ LDFLAGS='-g -Wall -O2'
+ COMPILER='gcc'
+else
+ CFLAGS='-g -O2'
+ LDFLAGS='-g -O2'
+ COMPILER='clang'
+fi
+
+CFLAGS="$CFLAGS $(pkg-config --cflags gstreamer-1.0 gthread-2.0 gio-2.0)"
+LDFLAGS="$LDFLAGS $(pkg-config --libs gstreamer-1.0 gthread-2.0 gio-2.0)"
rm -f include.mk
rm -f config.h
@@ -118,7 +129,7 @@ cat > include.mk <<EOF
# use ./configure instead
TARGET := '$TARGET'
-CC := gcc
+CC := $COMPILER
CFLAGS := $CFLAGS
LDFLAGS := $LDFLAGS
STRIP := strip
diff --git a/src/daemon.h b/src/daemon.h
index 6a264d0..f362e07 100644
--- a/src/daemon.h
+++ b/src/daemon.h
@@ -50,7 +50,7 @@ int priv_init(priv_info_t* priv, const char* username, const char* groupname)
priv->pw_ = getpwnam(username);
if(!priv->pw_) {
- log_printf(ERROR, "unkown user %s", username);
+ log_printf(ERROR, "unknown user %s", username);
return -1;
}
@@ -60,7 +60,7 @@ int priv_init(priv_info_t* priv, const char* username, const char* groupname)
priv->gr_ = getgrgid(priv->pw_->pw_gid);
if(!priv->gr_) {
- log_printf(ERROR, "unkown group %s", groupname);
+ log_printf(ERROR, "unknown group %s", groupname);
return -1;
}
@@ -112,6 +112,8 @@ int do_chroot(const char* chrootdir)
log_printf(ERROR, "can't change to /: %s", strerror(errno));
return -1;
}
+
+ return 0;
}
void daemonize()
diff --git a/src/gstdvbbackend.c b/src/gstdvbbackend.c
index afe5246..277d16b 100644
--- a/src/gstdvbbackend.c
+++ b/src/gstdvbbackend.c
@@ -29,6 +29,8 @@
#include <string.h>
#include <sys/select.h>
+#include <glib.h>
+#include <glib-unix.h>
#include <gst/gst.h>
#include "datatypes.h"
@@ -38,6 +40,15 @@
#include "daemon.h"
#include "streamer.h"
+static gboolean sig_handler_terminate(gpointer user_data)
+{
+ GMainLoop *loop = (GMainLoop *)user_data;
+
+ log_printf(NOTICE, "signal received, closing application");
+ g_main_loop_quit(loop);
+ return TRUE;
+}
+
static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data)
{
GMainLoop *loop = (GMainLoop *)data;
@@ -81,7 +92,7 @@ int main_loop(options_t* opt)
log_printf(INFO, "entering main loop");
GMainLoop *loop;
- GstElement *pipeline, *source, *sink;
+ GstElement *pipeline, *source;
GstBus *bus;
streamer_t streamer;
@@ -126,12 +137,13 @@ int main_loop(options_t* opt)
log_printf(INFO, "Set State: Playing");
gst_element_set_state(pipeline, GST_STATE_PLAYING);
- signal_start(loop);
ret = streamer_start(&streamer);
if(!ret) {
+ g_unix_signal_add(SIGHUP, sig_handler_terminate, loop);
+ g_unix_signal_add(SIGINT, sig_handler_terminate, loop);
+ g_unix_signal_add(SIGTERM, sig_handler_terminate, loop);
g_main_loop_run(loop);
streamer_stop(&streamer);
- signal_stop();
}
log_printf(NOTICE, "Stopping pipeline");
@@ -229,7 +241,6 @@ int main(int argc, char* argv[])
fclose(pid_file);
}
- signal_init();
gst_init(NULL, NULL);
const gchar *nano_str;
guint major, minor, micro, nano;
diff --git a/src/log.c b/src/log.c
index 0d097bb..47e018d 100644
--- a/src/log.c
+++ b/src/log.c
@@ -1,4 +1,4 @@
-x/*
+/*
* gstdvbbackend
*
* gstdvbbackend is a small programm which captures a given set of dvb
@@ -181,15 +181,14 @@ void log_init()
{
stdlog.max_prio_ = 0;
stdlog.targets_.first_ = NULL;
- g_thread_init(NULL);
- stdlog.log_mutex_ = g_mutex_new();
+ g_mutex_init(&(stdlog.log_mutex_));
}
void log_close()
{
- g_mutex_lock(stdlog.log_mutex_);
+ g_mutex_lock(&(stdlog.log_mutex_));
log_targets_clear(&stdlog.targets_);
- g_mutex_unlock(stdlog.log_mutex_);
+ g_mutex_unlock(&(stdlog.log_mutex_));
}
void update_max_prio()
@@ -208,10 +207,10 @@ int log_add_target(const char* conf)
if(!conf)
return -1;
- g_mutex_lock(stdlog.log_mutex_);
+ g_mutex_lock(&(stdlog.log_mutex_));
int ret = log_targets_add(&stdlog.targets_, conf);
if(!ret) update_max_prio();
- g_mutex_unlock(stdlog.log_mutex_);
+ g_mutex_unlock(&(stdlog.log_mutex_));
return ret;
}
@@ -220,34 +219,34 @@ void log_printf(log_prio_t prio, const char* fmt, ...)
if(stdlog.max_prio_ < prio)
return;
- char msg[MSG_LENGTH_MAX];
+ static char msg[MSG_LENGTH_MAX];
va_list args;
va_start(args, fmt);
vsnprintf(msg, MSG_LENGTH_MAX, fmt, args);
va_end(args);
- g_mutex_lock(stdlog.log_mutex_);
+ g_mutex_lock(&(stdlog.log_mutex_));
log_targets_log(&stdlog.targets_, prio, msg);
- g_mutex_unlock(stdlog.log_mutex_);
+ g_mutex_unlock(&(stdlog.log_mutex_));
}
-void log_print_hex_dump(log_prio_t prio, const uint8_t* buf, uint32_t len)
+void log_print_hex_dump(log_prio_t prio, const u_int8_t* buf, u_int32_t len)
{
if(stdlog.max_prio_ < prio)
return;
- char msg[MSG_LENGTH_MAX];
+ static char msg[MSG_LENGTH_MAX];
if(!buf) {
snprintf(msg, MSG_LENGTH_MAX, "(NULL)");
}
else {
- uint32_t i;
+ u_int32_t i;
int offset = snprintf(msg, MSG_LENGTH_MAX, "dump(%d): ", len);
if(offset < 0)
return;
- uint8_t* ptr = &msg[offset];
+ char* ptr = &msg[offset];
for(i=0; i < len; i++) {
if(((i+1)*3) >= (MSG_LENGTH_MAX - offset))
@@ -256,7 +255,7 @@ void log_print_hex_dump(log_prio_t prio, const uint8_t* buf, uint32_t len)
ptr+=3;
}
}
- g_mutex_lock(stdlog.log_mutex_);
+ g_mutex_lock(&(stdlog.log_mutex_));
log_targets_log(&stdlog.targets_, prio, msg);
- g_mutex_unlock(stdlog.log_mutex_);
+ g_mutex_unlock(&(stdlog.log_mutex_));
}
diff --git a/src/log.h b/src/log.h
index 6c5b3f6..350014d 100644
--- a/src/log.h
+++ b/src/log.h
@@ -69,7 +69,7 @@ void log_targets_clear(log_targets_t* targets);
struct log_struct {
log_prio_t max_prio_;
log_targets_t targets_;
- GMutex* log_mutex_;
+ GMutex log_mutex_;
};
typedef struct log_struct log_t;
@@ -78,6 +78,6 @@ void log_close();
void update_max_prio();
int log_add_target(const char* conf);
void log_printf(log_prio_t prio, const char* fmt, ...);
-void log_print_hex_dump(log_prio_t prio, const uint8_t* buf, uint32_t len);
+void log_print_hex_dump(log_prio_t prio, const u_int8_t* buf, u_int32_t len);
#endif
diff --git a/src/log_targets.h b/src/log_targets.h
index 27370c5..7a8f6be 100644
--- a/src/log_targets.h
+++ b/src/log_targets.h
@@ -47,7 +47,6 @@ static char* get_time_formatted()
return time_string;
}
-#ifndef WINVER
enum syslog_facility_enum { USER = LOG_USER, MAIL = LOG_MAIL,
DAEMON = LOG_DAEMON, AUTH = LOG_AUTH,
SYSLOG = LOG_SYSLOG, LPR = LOG_LPR,
@@ -188,7 +187,7 @@ log_target_t* log_target_syslog_new()
return tmp;
}
-#endif
+
struct log_target_file_param_struct {
char* logfilename_;
diff --git a/src/options.c b/src/options.c
index f4874b2..e8de727 100644
--- a/src/options.c
+++ b/src/options.c
@@ -302,7 +302,13 @@ void options_print_usage()
void options_print_version()
{
printf("%s\n", VERSION_STRING_0);
+#if defined(__clang__)
+ printf("%s, using CLANG %s\n", VERSION_STRING_1, __clang_version__);
+#elif defined(__GNUC__)
+ printf("%s, using GCC %d.%d.%d\n", VERSION_STRING_1, __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
+#else
printf("%s\n", VERSION_STRING_1);
+#endif
}
void options_print(options_t* opt)
diff --git a/src/sig_handler.c b/src/sig_handler.c
deleted file mode 100644
index 1597276..0000000
--- a/src/sig_handler.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * gstdvbbackend
- *
- * gstdvbbackend is a small programm which captures a given set of dvb
- * channels from one dvb device and provides the streams via minimal http.
- *
- *
- * Copyright (C) 2011-2016 Christian Pointner <equinox@spreadspace.org>
- *
- * This file is part of gstdvbbackend.
- *
- * gstdvbbackend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * gstdvbbackend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with gstdvbbackend. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "datatypes.h"
-
-#include "log.h"
-
-#include <signal.h>
-#include "sig_handler.h"
-
-#include <glib.h>
-#include <errno.h>
-
-static GThread *signal_thread;
-
-void signal_init()
-{
- sigset_t signal_set;
-
- sigemptyset(&signal_set);
- sigaddset(&signal_set, SIGINT);
- sigaddset(&signal_set, SIGQUIT);
- sigaddset(&signal_set, SIGHUP);
- sigaddset(&signal_set, SIGTERM);
- sigaddset(&signal_set, SIGUSR1);
- sigaddset(&signal_set, SIGUSR2);
-
- pthread_sigmask(SIG_BLOCK, &signal_set, NULL);
-}
-
-static gpointer signal_thread_func(gpointer data)
-{
- GMainLoop *loop = (GMainLoop *)data;
-
- struct timespec timeout;
- sigset_t signal_set;
- int sig_num;
- for(;;) {
- sigemptyset(&signal_set);
- sigaddset(&signal_set, SIGINT);
- sigaddset(&signal_set, SIGQUIT);
- sigaddset(&signal_set, SIGHUP);
- sigaddset(&signal_set, SIGTERM);
- sigaddset(&signal_set, SIGUSR1);
- sigaddset(&signal_set, SIGUSR2);
- timeout.tv_sec = 1;
- timeout.tv_nsec = 0;
- sig_num = sigtimedwait(&signal_set, NULL, &timeout);
- if(sig_num == -1) {
- if(errno != EINTR && errno != EAGAIN) {
- log_printf(ERROR, "sigwait failed with error: %d, signal handling will be disabled", errno);
- break;
- }
- } else {
- switch(sig_num) {
- case SIGTERM:
- case SIGINT:
- case SIGQUIT: {
- log_printf(NOTICE, "signal %d received, exiting", sig_num);
- g_main_loop_quit(loop);
- break;
- }
- default: {
- log_printf(NOTICE, "signal %d received, ignoring", sig_num);
- break;
- }
- }
- }
- }
-
- return NULL;
-}
-
-int signal_start(GMainLoop *loop)
-{
- g_assert(!signal_thread);
-
- signal_thread = g_thread_create_full(signal_thread_func, loop, 8192, FALSE, TRUE, G_THREAD_PRIORITY_HIGH, NULL);
- if(!signal_thread)
- return -1;
-
- return 0;
-}
-
-void signal_stop()
-{
- // nothing yet..
-}
diff --git a/src/sig_handler.h b/src/sig_handler.h
deleted file mode 100644
index 9121dcc..0000000
--- a/src/sig_handler.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * gstdvbbackend
- *
- * gstdvbbackend is a small programm which captures a given set of dvb
- * channels from one dvb device and provides the streams via minimal http.
- *
- *
- * Copyright (C) 2011-2016 Christian Pointner <equinox@spreadspace.org>
- *
- * This file is part of gstdvbbackend.
- *
- * gstdvbbackend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * gstdvbbackend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with gstdvbbackend. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GSTDVBBACKEND_sig_handler_h_INCLUDED
-#define GSTDVBBACKEND_sig_handler_h_INCLUDED
-
-#include <glib.h>
-
-void signal_init();
-int signal_start(GMainLoop *loop);
-void signal_stop();
-
-#endif
diff --git a/src/streamer.c b/src/streamer.c
index 4475562..1d49fcb 100644
--- a/src/streamer.c
+++ b/src/streamer.c
@@ -145,28 +145,25 @@ static void add_fd(streamer_t* streamer, int fd)
g_signal_emit_by_name(G_OBJECT(streamer->sink_), "add", fd, NULL);
}
+/*
static void remove_fd(streamer_t* streamer, int fd)
{
log_printf(INFO, "removing fd %d from fdsink", fd);
g_signal_emit_by_name(G_OBJECT(streamer->sink_), "remove-flush", fd, NULL);
}
+*/
-struct client_struct {
- int fd_;
- streamer_t* streamer_;
-};
-
-static gpointer client_thread_func(gpointer data)
+void client_thread_func(gpointer data, gpointer user_data)
{
- struct client_struct *client = (struct client_struct*)data;
+ streamer_t *streamer = (streamer_t*)user_data;
+ int fd = *((int*)user_data);
char buf;
int nlcnt = 0;
for(;;) {
- int len = recv(client->fd_, &buf, 1, 0);
+ int len = recv(fd, &buf, 1, 0);
if(len!=1) {
- free(client);
- return NULL;
+ return;
}
if(buf == '\n') nlcnt++;
@@ -179,10 +176,9 @@ static gpointer client_thread_func(gpointer data)
char* answer = "HTTP/1.0 200 OK\n\n";
int written = 0;
for(;;) {
- int len = send(client->fd_, &answer[written], strlen(answer) - written, 0);
+ int len = send(fd, &answer[written], strlen(answer) - written, 0);
if(len < 0) {
- free(client);
- return NULL;
+ return;
}
written+=len;
@@ -190,9 +186,7 @@ static gpointer client_thread_func(gpointer data)
break;
}
- add_fd(client->streamer_, client->fd_);
- free(client);
- return NULL;
+ add_fd(streamer, fd);
}
static gpointer streamer_thread_func(gpointer data)
@@ -200,25 +194,25 @@ static gpointer streamer_thread_func(gpointer data)
streamer_t *streamer = (streamer_t*)data;
log_printf(NOTICE, "streamer thread started");
- GstBuffer* buf = NULL;
struct sockaddr_in remote_addr;
memset (&remote_addr, 0, sizeof(remote_addr));
for(;;) {
- int alen=sizeof(remote_addr);
+ socklen_t alen=sizeof(remote_addr);
int new_client = accept(streamer->fd_, (struct sockaddr *)&remote_addr, &alen);
if(new_client==-1) {
log_printf(ERROR, "accept() call failed");
break;
}
log_printf(INFO, "streamer: new connection %s:%d (fd=%d)", inet_ntoa(remote_addr.sin_addr), ntohs(remote_addr.sin_port), new_client);
- struct client_struct* client = malloc(sizeof(struct client_struct));
- if(!client) {
+
+ int *client_fd = malloc(sizeof(int));
+ if (!new_client) {
log_printf(ERROR, "streamer: memory error");
break;
}
- client->fd_ = new_client;
- client->streamer_ = streamer;
- g_thread_create(client_thread_func, client, FALSE, NULL);
+
+ *client_fd = new_client;
+ g_thread_pool_push(streamer->client_pool_, client_fd, NULL);
}
log_printf(NOTICE, "streamer thread stopped");
@@ -231,12 +225,18 @@ int streamer_start(streamer_t* streamer)
if(!streamer)
return -1;
- streamer->thread_ = g_thread_create(streamer_thread_func, streamer, TRUE, NULL);
+ streamer->thread_ = g_thread_new("streamer", streamer_thread_func, streamer);
if(!streamer->thread_) {
log_printf(ERROR, "streamer thread could not be started");
return -1;
}
+ streamer->client_pool_ = g_thread_pool_new (client_thread_func, streamer, 8, TRUE, NULL);
+ if(!streamer->client_pool_) {
+ log_printf(ERROR, "streamer thread could not be started");
+ return -1;
+ }
+
return 0;
}
@@ -247,6 +247,8 @@ void streamer_stop(streamer_t* streamer)
shutdown(streamer->fd_, SHUT_RDWR);
+ g_thread_pool_free(streamer->client_pool_, TRUE, TRUE);
+
if(streamer->thread_) {
log_printf(NOTICE, "waiting for streamer thread to stop");
g_thread_join(streamer->thread_);
diff --git a/src/streamer.h b/src/streamer.h
index a68e874..f7f11f3 100644
--- a/src/streamer.h
+++ b/src/streamer.h
@@ -33,6 +33,7 @@ struct streamer_struct {
GMainLoop *loop_;
GstElement* sink_;
GThread* thread_;
+ GThreadPool *client_pool_;
int fd_;
};
typedef struct streamer_struct streamer_t;
diff --git a/src/sysexec.c b/src/sysexec.c
index 1e50e53..c248ec6 100644
--- a/src/sysexec.c
+++ b/src/sysexec.c
@@ -25,6 +25,7 @@
#include "datatypes.h"
+#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -32,6 +33,7 @@
#include <sys/wait.h>
#include <sys/select.h>
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include "sysexec.h"
@@ -172,7 +174,8 @@ child_t* rh_exec(const char* script, char* const argv[], char* const evp[])
// if execve returns, an error occurred, but logging doesn't work
// because we closed all file descriptors, so just write errno to
// pipe and call exit
- write(pipefd[1], (void*)(&errno), sizeof(errno));
+ int ret = write(pipefd[1], (void*)(&errno), sizeof(errno));
+ if(ret == -1) exit(-1);
exit(-1);
}
close(pipefd[1]);