summaryrefslogtreecommitdiffstats
path: root/src/application.c
blob: 538ac45d98bc88953fee29e9d22848fa04f97798 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*! \file application.c
 *  Routines for helping with the osmocom application setup. */
/*
 * (C) 2010 by Harald Welte <laforge@gnumonks.org>
 * (C) 2011 by Holger Hans Peter Freyther
 *
 * All Rights Reserved
 *
 * This program 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 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

/*! \mainpage libosmocore Documentation
 * \section sec_intro Introduction
 * This library is a collection of common code used in various
 * sub-projects inside the Osmocom family of projects.  It includes a
 * logging framework, select() loop abstraction, timers with callbacks,
 * bit vectors, bit packing/unpacking, convolutional decoding, GSMTAP, a
 * generic plugin interface, statistics counters, memory allocator,
 * socket abstraction, message buffers, etc.
 * \n\n
 * libosmocodec is developed as part of the Osmocom (Open Source Mobile
 * Communications) project, a community-based, collaborative development
 * project to create Free and Open Source implementations of mobile
 * communications systems.  For more information about Osmocom, please
 * see https://osmocom.org/
 *
 * Please note that C language projects inside Osmocom are typically
 * single-threaded event-loop state machine designs.  As such,
 * routines in libosmocore are not thread-safe.  If you must use them in
 * a multi-threaded context, you have to add your own locking.
 *
 * \section sec_copyright Copyright and License
 * Copyright © 2008-2017 - Harald Welte, Holger Freyther and contributors\n
 * All rights reserved. \n\n
 * The source code of libosmocore is licensed under the terms of the GNU
 * General Public License as published by the Free Software Foundation;
 * either version 2 of the License, or (at your option) any later
 * version.\n
 * See <http://www.gnu.org/licenses/> or COPYING included in the source
 * code package istelf.\n
 * The information detailed here is provided AS IS with NO WARRANTY OF
 * ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.
 * \n\n
 *
 * \section sec_tracker Homepage + Issue Tracker
 * The libosmocore project home page can be found at
 * https://osmocom.org/projects/libosmocore
 *
 * An Issue Tracker can be found at
 * https://osmocom.org/projects/libosmocore/issues
 *
 * \section sec_contact Contact and Support
 * Community-based support is available at the OpenBSC mailing list
 * <http://lists.osmocom.org/mailman/listinfo/openbsc>\n
 * Commercial support options available upon request from
 * <http://sysmocom.de/>
 */

#include <osmocom/core/application.h>
#include <osmocom/core/logging.h>

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>

struct log_target *osmo_stderr_target;

static void sighup_hdlr(int signal)
{
	log_targets_reopen();
}

/*! Ignore \ref SIGPIPE, \ref SIGALRM, \ref SIGHUP and \ref SIGIO */
void osmo_init_ignore_signals(void)
{
	/* Signals that by default would terminate */
#ifdef SIGPIPE
	signal(SIGPIPE, SIG_IGN);
#endif
	signal(SIGALRM, SIG_IGN);
#ifdef SIGHUP
	signal(SIGHUP, &sighup_hdlr);
#endif
#ifdef SIGIO
	signal(SIGIO, SIG_IGN);
#endif
}

/*! Initialize the osmocom logging framework
 *  \param[in] log_info Array of available logging sub-systems
 *  \returns 0 on success, -1 in case of error
 *
 * This function initializes the osmocom logging systems.  It also
 * creates the default (stderr) logging target.
 */
int osmo_init_logging(const struct log_info *log_info)
{
	static int logging_initialized = 0;

	if (logging_initialized)
		return -EEXIST;

	logging_initialized = 1;
	log_init(log_info, NULL);
	osmo_stderr_target = log_target_create_stderr();
	if (!osmo_stderr_target)
		return -1;

	log_add_target(osmo_stderr_target);
	log_set_all_filter(osmo_stderr_target, 1);
	return 0;
}

/*! Turn the current process into a background daemon
 *
 * This function will fork the process, exit the parent and set umask,
 * create a new session, close stdin/stdout/stderr and chdir to /tmp
 */
int osmo_daemonize(void)
{
	int rc;
	pid_t pid, sid;

	/* Check if parent PID == init, in which case we are already a daemon */
	if (getppid() == 1)
		return 0;

	/* Fork from the parent process */
	pid = fork();
	if (pid < 0) {
		/* some error happened */
		return pid;
	}

	if (pid > 0) {
		/* if we have received a positive PID, then we are the parent
		 * and can exit */
		exit(0);
	}

	/* FIXME: do we really want this? */
	umask(0);

	/* Create a new session and set process group ID */
	sid = setsid();
	if (sid < 0)
		return sid;

	/* Change to the /tmp directory, which prevents the CWD from being locked
	 * and unable to remove it */
	rc = chdir("/tmp");
	if (rc < 0)
		return rc;

	/* Redirect stdio to /dev/null */
/* since C89/C99 says stderr is a macro, we can safely do this! */
#ifdef stderr
/*
 * it does not make sense to check the return code here, so we just
 * ignore the compiler warning from gcc
 */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
	freopen("/dev/null", "r", stdin);
	freopen("/dev/null", "w", stdout);
	freopen("/dev/null", "w", stderr);
#pragma GCC diagnostic pop
#endif

	return 0;
}