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:
Joachim Nilsson 2019-11-02 20:57:07 +01:00
parent 1236334c39
commit ff4f2cdb31
10 changed files with 267 additions and 363 deletions

View File

@ -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
View 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
View 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;
}

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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:
*/

View File

@ -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_ */

View File

@ -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);
} }