Replace homegrown PID file functions with std BSD pidfile()
- Import pidfile() v1.11 from OpenBSD and libite (-lite) project - Import utimensat() replacement, for systems that don't have it - Simplify syslogd and klogd program start and PID file creation - Rip out -i and -I from klogd, uses old PID file functions, and they're only kill(1) wrappers anyway Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
parent
1236334c39
commit
ff4f2cdb31
@ -40,7 +40,7 @@ AC_HEADER_STDC
|
|||||||
PKG_PROG_PKG_CONFIG
|
PKG_PROG_PKG_CONFIG
|
||||||
|
|
||||||
# Check for usually missing API's, which we can replace
|
# Check for usually missing API's, which we can replace
|
||||||
AC_REPLACE_FUNCS([strlcpy strlcat])
|
AC_REPLACE_FUNCS([pidfile strlcpy strlcat utimensat])
|
||||||
AC_CONFIG_LIBOBJ_DIR([lib])
|
AC_CONFIG_LIBOBJ_DIR([lib])
|
||||||
|
|
||||||
# Command line options
|
# Command line options
|
||||||
|
138
lib/pidfile.c
Normal file
138
lib/pidfile.c
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
/* Updated by troglobit for libite/finit/uftpd projects 2016/07/04 */
|
||||||
|
/* $OpenBSD: pidfile.c,v 1.11 2015/06/03 02:24:36 millert Exp $ */
|
||||||
|
/* $NetBSD: pidfile.c,v 1.4 2001/02/19 22:43:42 cgd Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE /* Needed with GLIBC to get asprintf() */
|
||||||
|
#include <sys/stat.h> /* utimensat() */
|
||||||
|
#include <sys/time.h> /* utimensat() on *BSD */
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "compat.h"
|
||||||
|
|
||||||
|
#ifndef HAVE_UTIMENSAT
|
||||||
|
int utimensat(int dirfd, const char *pathname, const struct timespec ts[2], int flags);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static char *pidfile_path = NULL;
|
||||||
|
static pid_t pidfile_pid = 0;
|
||||||
|
|
||||||
|
static void pidfile_cleanup(void);
|
||||||
|
|
||||||
|
const char *__pidfile_path = LOCALSTATEDIR "/run";
|
||||||
|
const char *__pidfile_name = NULL;
|
||||||
|
|
||||||
|
int
|
||||||
|
pidfile(const char *basename)
|
||||||
|
{
|
||||||
|
int save_errno;
|
||||||
|
int atexit_already;
|
||||||
|
pid_t pid;
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
if (basename == NULL)
|
||||||
|
basename = getprogname();
|
||||||
|
|
||||||
|
pid = getpid();
|
||||||
|
atexit_already = 0;
|
||||||
|
|
||||||
|
if (pidfile_path != NULL) {
|
||||||
|
if (!access(pidfile_path, R_OK) && pid == pidfile_pid) {
|
||||||
|
utimensat(0, pidfile_path, NULL, 0);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
free(pidfile_path);
|
||||||
|
pidfile_path = NULL;
|
||||||
|
__pidfile_name = NULL;
|
||||||
|
atexit_already = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (basename[0] != '/') {
|
||||||
|
if (asprintf(&pidfile_path, "%s/%s.pid", __pidfile_path, basename) == -1)
|
||||||
|
return (-1);
|
||||||
|
} else {
|
||||||
|
if (asprintf(&pidfile_path, "%s", basename) == -1)
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((f = fopen(pidfile_path, "w")) == NULL) {
|
||||||
|
save_errno = errno;
|
||||||
|
free(pidfile_path);
|
||||||
|
pidfile_path = NULL;
|
||||||
|
errno = save_errno;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fprintf(f, "%ld\n", (long)pid) <= 0 || fflush(f) != 0) {
|
||||||
|
save_errno = errno;
|
||||||
|
(void) fclose(f);
|
||||||
|
(void) unlink(pidfile_path);
|
||||||
|
free(pidfile_path);
|
||||||
|
pidfile_path = NULL;
|
||||||
|
errno = save_errno;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
(void) fclose(f);
|
||||||
|
__pidfile_name = pidfile_path;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LITE extension, no need to set up another atexit() handler
|
||||||
|
* if user only called us to update the mtime of the PID file
|
||||||
|
*/
|
||||||
|
if (atexit_already)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
pidfile_pid = pid;
|
||||||
|
if (atexit(pidfile_cleanup) < 0) {
|
||||||
|
save_errno = errno;
|
||||||
|
(void) unlink(pidfile_path);
|
||||||
|
free(pidfile_path);
|
||||||
|
pidfile_path = NULL;
|
||||||
|
pidfile_pid = 0;
|
||||||
|
errno = save_errno;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pidfile_cleanup(void)
|
||||||
|
{
|
||||||
|
if (pidfile_path != NULL && pidfile_pid == getpid()) {
|
||||||
|
(void) unlink(pidfile_path);
|
||||||
|
free(pidfile_path);
|
||||||
|
pidfile_path = NULL;
|
||||||
|
}
|
||||||
|
}
|
47
lib/utimensat.c
Normal file
47
lib/utimensat.c
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/* Replacement in case utimensat(2) is missing
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017-2018 Joachim Nilsson <troglobit@gmail.com>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#ifdef HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/time.h> /* lutimes(), utimes(), utimensat() */
|
||||||
|
|
||||||
|
int utimensat(int dirfd, const char *pathname, const struct timespec ts[2], int flags)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
struct timeval tv[2];
|
||||||
|
|
||||||
|
if (dirfd != 0) {
|
||||||
|
errno = ENOTSUP;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
TIMESPEC_TO_TIMEVAL(&tv[0], &ts[0]);
|
||||||
|
TIMESPEC_TO_TIMEVAL(&tv[1], &ts[1]);
|
||||||
|
|
||||||
|
#ifdef AT_SYMLINK_NOFOLLOW
|
||||||
|
if ((flags & AT_SYMLINK_NOFOLLOW) == AT_SYMLINK_NOFOLLOW)
|
||||||
|
ret = lutimes(pathname, tv);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
ret = utimes(pathname, tv);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
29
man/klogd.8
29
man/klogd.8
@ -31,14 +31,6 @@ Enable debugging mode. This will generate potentially LOTS of output to
|
|||||||
stderr.
|
stderr.
|
||||||
.It Fl f Ar FILE
|
.It Fl f Ar FILE
|
||||||
Log messages to the specified filename rather than to the syslog facility.
|
Log messages to the specified filename rather than to the syslog facility.
|
||||||
.It Fl i | Fl I
|
|
||||||
Signal the currently executing klogd daemon. Both of these switches control
|
|
||||||
the loading/reloading of symbol information. The
|
|
||||||
.Fl i
|
|
||||||
switch signals the daemon to reload the kernel module symbols. The
|
|
||||||
.Fl I
|
|
||||||
switch signals for a reload of both the static kernel symbols and the
|
|
||||||
kernel module symbols.
|
|
||||||
.It Fl n
|
.It Fl n
|
||||||
Avoid auto-backgrounding. This is needed especially if
|
Avoid auto-backgrounding. This is needed especially if
|
||||||
.Nm
|
.Nm
|
||||||
@ -251,22 +243,23 @@ Proper and accurate resolution of addresses in kernel modules requires
|
|||||||
that
|
that
|
||||||
.Nm
|
.Nm
|
||||||
be informed whenever the kernel module status changes. The
|
be informed whenever the kernel module status changes. The
|
||||||
.Fl i
|
.Ar SIGUSR1
|
||||||
and
|
and
|
||||||
.Fl I
|
.Ar SIGUSR2
|
||||||
switches can be used to signal the currently executing daemon that
|
signals can be used to signal the currently executing
|
||||||
symbol information be reloaded. Of most importance to proper resolution
|
.Nm
|
||||||
of module symbols is the
|
that symbol information should be reloaded. Of most importance to
|
||||||
.Fl i
|
proper resolution of module symbols is
|
||||||
switch. Each time a kernel module is loaded or removed from the kernel
|
.Ar SIGUSR1 .
|
||||||
the following command should be executed:
|
Each time a kernel module is loaded or removed from the kernel the
|
||||||
|
following command should be executed:
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
klogd -i
|
kill -USR1 `cat /run/klogd.pid`
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
.Fl p
|
.Fl p
|
||||||
switch can also be used to insure that module symbol information is up
|
switch can also be used to ensure that module symbol information is up
|
||||||
to date. This switch instructs
|
to date. This switch instructs
|
||||||
.Nm
|
.Nm
|
||||||
to reload the module symbol information whenever a protection fault
|
to reload the module symbol information whenever a protection fault
|
||||||
|
@ -23,19 +23,20 @@ lib_LTLIBRARIES = libsyslog.la
|
|||||||
|
|
||||||
AM_CFLAGS = -W -Wall -Wextra
|
AM_CFLAGS = -W -Wall -Wextra
|
||||||
AM_CFLAGS += -Wno-unused-result -Wno-unused-parameter -fno-strict-aliasing
|
AM_CFLAGS += -Wno-unused-result -Wno-unused-parameter -fno-strict-aliasing
|
||||||
|
AM_CPPFLAGS = -DSYSCONFDIR=\"@sysconfdir@\" -DLOCALSTATEDIR=\"@localstatedir@\"
|
||||||
|
AM_CPPFLAGS += -D_BSD_SOURCE -D_DEFAULT_SOURCE
|
||||||
|
|
||||||
syslogd_SOURCES = syslogd.c syslog.h pidfile.c pidfile.h queue.h
|
syslogd_SOURCES = syslogd.c syslog.h queue.h
|
||||||
syslogd_CPPFLAGS = -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE
|
syslogd_CPPFLAGS = $(AM_CPPFLAGS) -D_XOPEN_SOURCE=600
|
||||||
syslogd_LDADD = $(LIBS) $(LIBOBJS)
|
syslogd_LDADD = $(LIBS) $(LIBOBJS)
|
||||||
|
|
||||||
klogd_SOURCES = klogd.c klogd.h syslog.h pidfile.c pidfile.h \
|
klogd_SOURCES = klogd.c klogd.h syslog.h ksym.c ksyms.h ksym_mod.c module.h
|
||||||
ksym.c ksyms.h ksym_mod.c module.h
|
klogd_CPPFLAGS = $(AM_CPPFLAGS) -DALLOW_KERNEL_LOGGING
|
||||||
klogd_CPPFLAGS = -DALLOW_KERNEL_LOGGING -D_BSD_SOURCE -D_DEFAULT_SOURCE
|
|
||||||
klogd_LDADD = $(LIBS) $(LIBOBJS)
|
klogd_LDADD = $(LIBS) $(LIBOBJS)
|
||||||
klogd_LDADD += libsyslog.la
|
klogd_LDADD += libsyslog.la
|
||||||
|
|
||||||
logger_SOURCES = logger.c syslog.h
|
logger_SOURCES = logger.c syslog.h
|
||||||
logger_CPPFLAGS = -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE
|
logger_CPPFLAGS = $(AM_CPPFLAGS) -D_XOPEN_SOURCE=600
|
||||||
logger_LDADD = $(LIBS) $(LIBOBJS)
|
logger_LDADD = $(LIBS) $(LIBOBJS)
|
||||||
logger_LDADD += libsyslog.la
|
logger_LDADD += libsyslog.la
|
||||||
|
|
||||||
@ -44,5 +45,5 @@ pkgincludedir = $(includedir)/syslog
|
|||||||
pkgconfig_DATA = libsyslog.pc
|
pkgconfig_DATA = libsyslog.pc
|
||||||
pkginclude_HEADERS = syslog.h
|
pkginclude_HEADERS = syslog.h
|
||||||
libsyslog_la_SOURCES = syslog.c syslog.h
|
libsyslog_la_SOURCES = syslog.c syslog.h
|
||||||
libsyslog_la_CPPFLAGS = -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE
|
libsyslog_la_CPPFLAGS = $(AM_CPPFLAGS) -D_XOPEN_SOURCE=600
|
||||||
libsyslog_la_LDFLAGS = $(AM_LDFLAGS) -version-info 0:0:0
|
libsyslog_la_LDFLAGS = $(AM_LDFLAGS) -version-info 0:0:0
|
||||||
|
@ -65,6 +65,10 @@ size_t strlcpy(char *dst, const char *src, size_t siz);
|
|||||||
size_t strlcat(char *dst, const char *src, size_t siz);
|
size_t strlcat(char *dst, const char *src, size_t siz);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef pidfile
|
||||||
|
int pidfile(const char *basename);
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline char *getprogname(void)
|
static inline char *getprogname(void)
|
||||||
{
|
{
|
||||||
extern char *__progname;
|
extern char *__progname;
|
||||||
|
111
src/klogd.c
111
src/klogd.c
@ -23,6 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "compat.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -35,9 +36,6 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#ifndef TESTING
|
|
||||||
#include "pidfile.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define __LIBRARY__
|
#define __LIBRARY__
|
||||||
#include <linux/unistd.h>
|
#include <linux/unistd.h>
|
||||||
@ -47,9 +45,7 @@
|
|||||||
#define LOG_BUFFER_SIZE 4096
|
#define LOG_BUFFER_SIZE 4096
|
||||||
#define LOG_LINE_LENGTH 1000
|
#define LOG_LINE_LENGTH 1000
|
||||||
|
|
||||||
#ifndef TESTING
|
|
||||||
static char *PidFile = _PATH_VARRUN "klogd.pid";
|
static char *PidFile = _PATH_VARRUN "klogd.pid";
|
||||||
#endif
|
|
||||||
|
|
||||||
static int kmsg;
|
static int kmsg;
|
||||||
static int change_state = 0;
|
static int change_state = 0;
|
||||||
@ -81,7 +77,6 @@ extern void stop_logging(int sig);
|
|||||||
extern void stop_daemon(int sig);
|
extern void stop_daemon(int sig);
|
||||||
extern void reload_daemon(int sig);
|
extern void reload_daemon(int sig);
|
||||||
static void Terminate(void);
|
static void Terminate(void);
|
||||||
static void SignalDaemon(int);
|
|
||||||
static void ReloadSymbols(void);
|
static void ReloadSymbols(void);
|
||||||
static void ChangeLogging(void);
|
static void ChangeLogging(void);
|
||||||
static enum LOGSRC GetKernelLogSrc(void);
|
static enum LOGSRC GetKernelLogSrc(void);
|
||||||
@ -115,12 +110,10 @@ static void CloseLogSrc(void)
|
|||||||
/*
|
/*
|
||||||
* Signal handler to terminate the parent process.
|
* Signal handler to terminate the parent process.
|
||||||
*/
|
*/
|
||||||
#ifndef TESTING
|
|
||||||
void doexit(int signo)
|
void doexit(int signo)
|
||||||
{
|
{
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void restart(int signo)
|
void restart(int signo)
|
||||||
{
|
{
|
||||||
@ -153,26 +146,14 @@ static void Terminate(void)
|
|||||||
CloseLogSrc();
|
CloseLogSrc();
|
||||||
Syslog(LOG_INFO, "Kernel log daemon terminating.");
|
Syslog(LOG_INFO, "Kernel log daemon terminating.");
|
||||||
sleep(1);
|
sleep(1);
|
||||||
|
|
||||||
if (output_file != NULL)
|
if (output_file != NULL)
|
||||||
fclose(output_file);
|
fclose(output_file);
|
||||||
closelog();
|
closelog();
|
||||||
#ifndef TESTING
|
|
||||||
(void)remove_pid(PidFile);
|
|
||||||
#endif
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SignalDaemon(int signo)
|
|
||||||
{
|
|
||||||
#ifndef TESTING
|
|
||||||
int pid = check_pid(PidFile);
|
|
||||||
|
|
||||||
kill(pid, signo);
|
|
||||||
#else
|
|
||||||
kill(getpid(), signo);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ReloadSymbols(void)
|
static void ReloadSymbols(void)
|
||||||
{
|
{
|
||||||
if (symbol_lookup) {
|
if (symbol_lookup) {
|
||||||
@ -257,7 +238,6 @@ static enum LOGSRC GetKernelLogSrc(void)
|
|||||||
return kernel;
|
return kernel;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TESTING
|
|
||||||
if ((kmsg = open(_PATH_KLOG, O_RDONLY)) < 0) {
|
if ((kmsg = open(_PATH_KLOG, O_RDONLY)) < 0) {
|
||||||
fprintf(stderr, "klogd: Cannot open proc file system, "
|
fprintf(stderr, "klogd: Cannot open proc file system, "
|
||||||
"%d - %s.\n",
|
"%d - %s.\n",
|
||||||
@ -265,12 +245,10 @@ static enum LOGSRC GetKernelLogSrc(void)
|
|||||||
ksyslog(7, NULL, 0);
|
ksyslog(7, NULL, 0);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
kmsg = fileno(stdin);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Syslog(LOG_INFO, "klogd v%s, log source = %s started.",
|
Syslog(LOG_INFO, "klogd v%s, log source = %s started.",
|
||||||
VERSION, _PATH_KLOG);
|
VERSION, _PATH_KLOG);
|
||||||
|
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,18 +311,12 @@ extern void Syslog(int priority, char *fmt, ...)
|
|||||||
}
|
}
|
||||||
syslog(priority, fmt, argl);
|
syslog(priority, fmt, argl);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
#ifdef TESTING
|
|
||||||
putchar('\n');
|
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
vsyslog(priority, fmt, ap);
|
vsyslog(priority, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
#ifdef TESTING
|
|
||||||
printf("\n");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -648,6 +620,8 @@ int usage(int code)
|
|||||||
" -v Show program version and exit\n"
|
" -v Show program version and exit\n"
|
||||||
" -x Omit EIP translation, i.e. do not read System.map file\n"
|
" -x Omit EIP translation, i.e. do not read System.map file\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
"SIGUSR1 reloads kernel module symbols, SIGUSR2 reloads all kernel symbols.\n"
|
||||||
|
"\n"
|
||||||
"Bug report address: %s\n",
|
"Bug report address: %s\n",
|
||||||
PACKAGE_BUGREPORT);
|
PACKAGE_BUGREPORT);
|
||||||
exit(code);
|
exit(code);
|
||||||
@ -659,14 +633,10 @@ int main(int argc, char *argv[])
|
|||||||
char *output = NULL;
|
char *output = NULL;
|
||||||
int use_output = 0;
|
int use_output = 0;
|
||||||
int ch;
|
int ch;
|
||||||
#ifndef TESTING
|
|
||||||
pid_t ppid = getpid();
|
pid_t ppid = getpid();
|
||||||
|
|
||||||
chdir("/");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Parse the command-line. */
|
/* Parse the command-line. */
|
||||||
while ((ch = getopt(argc, argv, "c:df:iIk:nopsvx2?")) != EOF) {
|
while ((ch = getopt(argc, argv, "c:df:k:nopsvx2?")) != EOF) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '2': /* Print lines with symbols twice. */
|
case '2': /* Print lines with symbols twice. */
|
||||||
symbols_twice = 1;
|
symbols_twice = 1;
|
||||||
@ -685,14 +655,6 @@ int main(int argc, char *argv[])
|
|||||||
use_output++;
|
use_output++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'i': /* Reload module symbols. */
|
|
||||||
SignalDaemon(SIGUSR1);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case 'I':
|
|
||||||
SignalDaemon(SIGUSR2);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case 'k': /* Kernel symbol file. */
|
case 'k': /* Kernel symbol file. */
|
||||||
symfile = optarg;
|
symfile = optarg;
|
||||||
break;
|
break;
|
||||||
@ -743,7 +705,6 @@ int main(int argc, char *argv[])
|
|||||||
console_log_level = *log_level - '0';
|
console_log_level = *log_level - '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TESTING
|
|
||||||
/*
|
/*
|
||||||
* The following code allows klogd to auto-background itself.
|
* The following code allows klogd to auto-background itself.
|
||||||
* What happens is that the program forks and the parent quits.
|
* What happens is that the program forks and the parent quits.
|
||||||
@ -756,48 +717,40 @@ int main(int argc, char *argv[])
|
|||||||
* such process running.
|
* such process running.
|
||||||
*/
|
*/
|
||||||
if ((!one_shot) && (!no_fork)) {
|
if ((!one_shot) && (!no_fork)) {
|
||||||
if (!check_pid(PidFile)) {
|
signal(SIGTERM, doexit);
|
||||||
signal(SIGTERM, doexit);
|
if (fork() == 0) {
|
||||||
if (fork() == 0) {
|
int num_fds = getdtablesize();
|
||||||
int num_fds = getdtablesize();
|
int fl;
|
||||||
int fl;
|
|
||||||
|
|
||||||
signal(SIGTERM, SIG_DFL);
|
signal(SIGTERM, SIG_DFL);
|
||||||
|
|
||||||
/* This is the child closing its file descriptors. */
|
/* This is the child closing its file descriptors. */
|
||||||
for (fl = 0; fl <= num_fds; ++fl) {
|
for (fl = 0; fl <= num_fds; ++fl) {
|
||||||
if (fileno(stdout) == fl && use_output)
|
if (fileno(stdout) == fl && use_output)
|
||||||
if (strcmp(output, "-") == 0)
|
if (strcmp(output, "-") == 0)
|
||||||
continue;
|
continue;
|
||||||
close(fl);
|
close(fl);
|
||||||
}
|
|
||||||
|
|
||||||
setsid();
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* Parent process
|
|
||||||
*/
|
|
||||||
sleep(300);
|
|
||||||
/*
|
|
||||||
* Not reached unless something major went wrong.
|
|
||||||
*/
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chdir("/");
|
||||||
|
setsid();
|
||||||
} else {
|
} else {
|
||||||
fputs("klogd: Already running.\n", stderr);
|
/*
|
||||||
|
* Parent process
|
||||||
|
*/
|
||||||
|
sleep(300);
|
||||||
|
/*
|
||||||
|
* Not reached unless something major went wrong.
|
||||||
|
*/
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tuck my process id away */
|
if (pidfile(PidFile)) {
|
||||||
if (!check_pid(PidFile)) {
|
Syslog(LOG_ERR, "Failed creating PID file %s: %s",
|
||||||
if (!write_pid(PidFile))
|
PidFile, strerror(errno));
|
||||||
Terminate();
|
|
||||||
} else {
|
|
||||||
fputs("klogd: Already running.\n", stderr);
|
|
||||||
Terminate();
|
Terminate();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Signal setups. */
|
/* Signal setups. */
|
||||||
for (ch = 1; ch < NSIG; ++ch)
|
for (ch = 1; ch < NSIG; ++ch)
|
||||||
|
147
src/pidfile.c
147
src/pidfile.c
@ -1,147 +0,0 @@
|
|||||||
/*-
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
*
|
|
||||||
* pidfile.c - interact with pidfiles
|
|
||||||
* Copyright (c) 1995 Martin Schulze <Martin.Schulze@Linux.DE>
|
|
||||||
*
|
|
||||||
* This file is part of the sysklogd package, a kernel and system log daemon.
|
|
||||||
*
|
|
||||||
* 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 file; see the file COPYING. If not, write to the
|
|
||||||
* Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
|
|
||||||
* MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/file.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
/* read_pid
|
|
||||||
*
|
|
||||||
* Reads the specified pidfile and returns the read pid.
|
|
||||||
* 0 is returned if either there's no pidfile, it's empty
|
|
||||||
* or no pid can be read.
|
|
||||||
*/
|
|
||||||
int read_pid(char *pidfile)
|
|
||||||
{
|
|
||||||
FILE *fp;
|
|
||||||
int pid;
|
|
||||||
|
|
||||||
fp = fopen(pidfile, "r");
|
|
||||||
if (!fp)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fscanf(fp, "%d", &pid);
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
return pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check_pid
|
|
||||||
*
|
|
||||||
* Reads the pid using read_pid and looks up the pid in the process
|
|
||||||
* table (using /proc) to determine if the process already exists. If
|
|
||||||
* so 1 is returned, otherwise 0.
|
|
||||||
*/
|
|
||||||
int check_pid(char *pidfile)
|
|
||||||
{
|
|
||||||
int pid = read_pid(pidfile);
|
|
||||||
|
|
||||||
/* Amazing ! _I_ am already holding the pid file... */
|
|
||||||
if ((!pid) || (pid == getpid()))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The 'standard' method of doing this is to try and do a 'fake' kill
|
|
||||||
* of the process. If an ESRCH error is returned the process cannot
|
|
||||||
* be found -- GW
|
|
||||||
*/
|
|
||||||
/* But... errno is usually changed only on error.. */
|
|
||||||
if (kill(pid, 0) && errno == ESRCH)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* write_pid
|
|
||||||
*
|
|
||||||
* Writes the pid to the specified file. If that fails 0 is
|
|
||||||
* returned, otherwise the pid.
|
|
||||||
*/
|
|
||||||
int write_pid(char *pidfile)
|
|
||||||
{
|
|
||||||
FILE *fp;
|
|
||||||
int fd;
|
|
||||||
int pid;
|
|
||||||
|
|
||||||
if (((fd = open(pidfile, O_RDWR | O_CREAT | O_TRUNC, 0644)) == -1) || ((fp = fdopen(fd, "r+")) == NULL)) {
|
|
||||||
fprintf(stderr, "Can't open or create %s.\n", pidfile);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flock(fd, LOCK_EX | LOCK_NB) == -1) {
|
|
||||||
fscanf(fp, "%d", &pid);
|
|
||||||
fclose(fp);
|
|
||||||
printf("Can't lock, lock is held by pid %d.\n", pid);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pid = getpid();
|
|
||||||
if (!fprintf(fp, "%d\n", pid)) {
|
|
||||||
printf("Can't write pid , %s.\n", strerror(errno));
|
|
||||||
close(fd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
fflush(fp);
|
|
||||||
|
|
||||||
if (flock(fd, LOCK_UN) == -1) {
|
|
||||||
printf("Can't unlock pidfile %s, %s.\n", pidfile, strerror(errno));
|
|
||||||
close(fd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
return pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* touch_pid
|
|
||||||
*
|
|
||||||
* Touches the specified pidfile f.ex. when receiving a SIGHUP
|
|
||||||
* The result from utimensat() is returned
|
|
||||||
*/
|
|
||||||
int touch_pid(char *pidfile)
|
|
||||||
{
|
|
||||||
return utimensat(0, pidfile, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remove_pid
|
|
||||||
*
|
|
||||||
* Remove the the specified file. The result from unlink(2)
|
|
||||||
* is returned
|
|
||||||
*/
|
|
||||||
int remove_pid(char *pidfile)
|
|
||||||
{
|
|
||||||
return unlink(pidfile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Local Variables:
|
|
||||||
* indent-tabs-mode: t
|
|
||||||
* c-file-style: "linux"
|
|
||||||
* End:
|
|
||||||
*/
|
|
@ -1,65 +0,0 @@
|
|||||||
/*-
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
*
|
|
||||||
* pidfile.h - interact with pidfiles
|
|
||||||
* Copyright (c) 1995 Martin Schulze <Martin.Schulze@Linux.DE>
|
|
||||||
*
|
|
||||||
* This file is part of the sysklogd package, a kernel and system log daemon.
|
|
||||||
*
|
|
||||||
* 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 file; see the file COPYING. If not, write to the
|
|
||||||
* Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
|
|
||||||
* MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SYSKLOGD_PIDFILE_H_
|
|
||||||
#define SYSKLOGD_PIDFILE_H_
|
|
||||||
|
|
||||||
/* read_pid
|
|
||||||
*
|
|
||||||
* Reads the specified pidfile and returns the read pid.
|
|
||||||
* 0 is returned if either there's no pidfile, it's empty
|
|
||||||
* or no pid can be read.
|
|
||||||
*/
|
|
||||||
int read_pid (char *pidfile);
|
|
||||||
|
|
||||||
/* check_pid
|
|
||||||
*
|
|
||||||
* Reads the pid using read_pid and looks up the pid in the process
|
|
||||||
* table (using /proc) to determine if the process already exists. If
|
|
||||||
* so 1 is returned, otherwise 0.
|
|
||||||
*/
|
|
||||||
int check_pid (char *pidfile);
|
|
||||||
|
|
||||||
/* write_pid
|
|
||||||
*
|
|
||||||
* Writes the pid to the specified file. If that fails 0 is
|
|
||||||
* returned, otherwise the pid.
|
|
||||||
*/
|
|
||||||
int write_pid (char *pidfile);
|
|
||||||
|
|
||||||
/* touch_pid
|
|
||||||
*
|
|
||||||
* Touches the specified pidfile f.ex. when receiving a SIGHUP
|
|
||||||
* The result from utimensat() is returned
|
|
||||||
*/
|
|
||||||
int touch_pid (char *pidfile);
|
|
||||||
|
|
||||||
/* remove_pid
|
|
||||||
*
|
|
||||||
* Remove the the specified file. The result from unlink(2)
|
|
||||||
* is returned
|
|
||||||
*/
|
|
||||||
int remove_pid (char *pidfile);
|
|
||||||
|
|
||||||
#endif /* SYSKLOGD_PIDFILE_H_ */
|
|
@ -96,7 +96,6 @@ static char sccsid[] __attribute__((unused)) =
|
|||||||
#include <syscall.h>
|
#include <syscall.h>
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
|
|
||||||
#include "pidfile.h"
|
|
||||||
#include "syslogd.h"
|
#include "syslogd.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
|
||||||
@ -448,52 +447,39 @@ int main(int argc, char *argv[])
|
|||||||
usage(1);
|
usage(1);
|
||||||
|
|
||||||
if ((!Foreground) && (!Debug)) {
|
if ((!Foreground) && (!Debug)) {
|
||||||
logit("Checking pidfile.\n");
|
signal(SIGTERM, doexit);
|
||||||
if (!check_pid(PidFile)) {
|
chdir("/");
|
||||||
signal(SIGTERM, doexit);
|
|
||||||
chdir("/");
|
|
||||||
|
|
||||||
if (fork()) {
|
if (fork()) {
|
||||||
/*
|
/*
|
||||||
* Parent process
|
* Parent process
|
||||||
*/
|
*/
|
||||||
sleep(300);
|
sleep(300);
|
||||||
/*
|
/*
|
||||||
* Not reached unless something major went wrong. 5
|
* Not reached unless something major went wrong. 5
|
||||||
* minutes should be a fair amount of time to wait.
|
* minutes should be a fair amount of time to wait.
|
||||||
* Please note that this procedure is important since
|
* Please note that this procedure is important since
|
||||||
* the father must not exit before syslogd isn't
|
* the father must not exit before syslogd isn't
|
||||||
* initialized or the klogd won't be able to flush its
|
* initialized or the klogd won't be able to flush its
|
||||||
* logs. -Joey
|
* logs. -Joey
|
||||||
*/
|
*/
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
signal(SIGTERM, SIG_DFL);
|
|
||||||
num_fds = getdtablesize();
|
|
||||||
for (i = 0; i < num_fds; i++)
|
|
||||||
(void)close(i);
|
|
||||||
untty();
|
|
||||||
} else {
|
|
||||||
fputs("syslogd: Already running.\n", stderr);
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signal(SIGTERM, SIG_DFL);
|
||||||
|
num_fds = getdtablesize();
|
||||||
|
for (i = 0; i < num_fds; i++)
|
||||||
|
(void)close(i);
|
||||||
|
untty();
|
||||||
} else {
|
} else {
|
||||||
debugging_on = 1;
|
debugging_on = 1;
|
||||||
setlinebuf(stdout);
|
setlinebuf(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tuck my process id away */
|
|
||||||
if (!Debug) {
|
if (!Debug) {
|
||||||
logit("Writing pidfile.\n");
|
if (pidfile(PidFile)) {
|
||||||
if (!check_pid(PidFile)) {
|
logit("Failed creating PID file %s: %s",
|
||||||
if (!write_pid(PidFile)) {
|
PidFile, strerror(errno));
|
||||||
logit("Can't write pid.\n");
|
|
||||||
if (getpid() != ppid)
|
|
||||||
kill(ppid, SIGTERM);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logit("Pidfile (and pid) already exist.\n");
|
|
||||||
if (getpid() != ppid)
|
if (getpid() != ppid)
|
||||||
kill(ppid, SIGTERM);
|
kill(ppid, SIGTERM);
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -593,13 +579,8 @@ int main(int argc, char *argv[])
|
|||||||
logit("\nReceived SIGHUP, reloading syslogd.\n");
|
logit("\nReceived SIGHUP, reloading syslogd.\n");
|
||||||
init();
|
init();
|
||||||
|
|
||||||
if (check_pid(PidFile)) {
|
if (pidfile(PidFile))
|
||||||
if (touch_pid(PidFile))
|
flog(LOG_SYSLOG | LOG_ERR, "Failed writing %s", PidFile);
|
||||||
logerror("Not possible to touch pidfile");
|
|
||||||
} else {
|
|
||||||
if (!write_pid(PidFile))
|
|
||||||
logerror("Failed to write pidfile");
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2267,7 +2248,6 @@ void die(int signo)
|
|||||||
if (parts)
|
if (parts)
|
||||||
free(parts);
|
free(parts);
|
||||||
|
|
||||||
(void)remove_pid(PidFile);
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user