summaryrefslogtreecommitdiffstats
path: root/usr.sbin/newsyslog
diff options
context:
space:
mode:
authorgad <gad@FreeBSD.org>2003-03-08 20:07:01 +0000
committergad <gad@FreeBSD.org>2003-03-08 20:07:01 +0000
commit1664ca4405c0ae8ca2f173edcfe621ce8a5e3bcc (patch)
tree9ee9dd268f471b5a852230b9b2c9224a254c3334 /usr.sbin/newsyslog
parentb454fc547a435fae75a4407133a6bd94e763cd66 (diff)
downloadFreeBSD-src-1664ca4405c0ae8ca2f173edcfe621ce8a5e3bcc.zip
FreeBSD-src-1664ca4405c0ae8ca2f173edcfe621ce8a5e3bcc.tar.gz
Add a config-file flag of 'U' or 'u' to indicate that the pid-file
will contain the pid for a process group. This means the file must contain a negative value (as would be needed in the 'kill' commmand). I still need to write man-page update before MFC-ing. This started by rewriting the get_pid() routine. Later I looked at what OpenBSD has, and included a few ideas from their send_signal() routine. So, parts of this change are from OpenBSD, even though OpenBSD does not actually have a 'U' flag. PR: bin/28435 Reviewed by: no objections on freebsd-arch MFC after: 3 weeks
Diffstat (limited to 'usr.sbin/newsyslog')
-rw-r--r--usr.sbin/newsyslog/newsyslog.c161
1 files changed, 115 insertions, 46 deletions
diff --git a/usr.sbin/newsyslog/newsyslog.c b/usr.sbin/newsyslog/newsyslog.c
index d447c4c..d0d255c 100644
--- a/usr.sbin/newsyslog/newsyslog.c
+++ b/usr.sbin/newsyslog/newsyslog.c
@@ -71,6 +71,8 @@ static const char rcsid[] =
/* trimming this file. */
#define CE_TRIMAT 0x0020 /* trim file at a specific time. */
#define CE_GLOB 0x0040 /* name of the log is file name pattern. */
+#define CE_SIGNALGROUP 0x0080 /* Signal a process-group instead of a single */
+ /* process when trimming this file. */
#define MIN_PID 5 /* Don't touch pids lower than this */
#define MAX_PID 99999 /* was lower, see /usr/include/sys/proc.h */
@@ -134,7 +136,7 @@ static void compress_log(char *log, int dowait);
static void bzcompress_log(char *log, int dowait);
static int sizefile(char *file);
static int age_old_log(char *file);
-static pid_t get_pid(const char *pid_file);
+static int send_signal(const struct conf_entry *ent);
static time_t parse8601(char *s, char *errline);
static void movefile(char *from, char *to, int perm, uid_t owner_uid,
gid_t group_gid);
@@ -363,6 +365,102 @@ do_entry(struct conf_entry * ent)
#undef REASON_MAX
}
+/* Send a signal to the pid specified by pidfile */
+static int
+send_signal(const struct conf_entry *ent)
+{
+ pid_t target_pid;
+ int did_notify;
+ FILE *f;
+ long minok, maxok, rval;
+ const char *target_name;
+ char *endp, *linep, line[BUFSIZ];
+
+ did_notify = 0;
+ f = fopen(ent->pid_file, "r");
+ if (f == NULL) {
+ warn("can't open pid file: %s", ent->pid_file);
+ return (did_notify);
+ /* NOTREACHED */
+ }
+
+ if (fgets(line, BUFSIZ, f) == NULL) {
+ /*
+ * XXX - If the pid file is empty, is that really a
+ * problem? Wouldn't that mean that the process
+ * has shut down? In that case there would be no
+ * problem with compressing the rotated log file.
+ */
+ if (feof(f))
+ warnx("pid file is empty: %s", ent->pid_file);
+ else
+ warn("can't read from pid file: %s", ent->pid_file);
+ (void) fclose(f);
+ return (did_notify);
+ /* NOTREACHED */
+ }
+ (void) fclose(f);
+
+ target_name = "daemon";
+ minok = MIN_PID;
+ maxok = MAX_PID;
+ if (ent->flags & CE_SIGNALGROUP) {
+ /*
+ * If we are expected to signal a process-group when
+ * rotating this logfile, then the value read in should
+ * be the negative of a valid process ID.
+ */
+ target_name = "process-group";
+ minok = -MAX_PID;
+ maxok = -MIN_PID;
+ }
+
+ errno = 0;
+ linep = line;
+ while (*linep == ' ')
+ linep++;
+ rval = strtol(linep, &endp, 10);
+ if (*endp != '\0' && !isspacech(*endp)) {
+ warnx("pid file does not start with a valid number: %s",
+ ent->pid_file);
+ rval = 0;
+ } else if (rval < minok || rval > maxok) {
+ warnx("bad value '%ld' for process number in %s",
+ rval, ent->pid_file);
+ if (verbose)
+ warnx("\t(expecting value between %ld and %ld)",
+ minok, maxok);
+ rval = 0;
+ }
+ if (rval == 0) {
+ return (did_notify);
+ /* NOTREACHED */
+ }
+
+ target_pid = rval;
+
+ if (noaction) {
+ did_notify = 1;
+ printf("\tkill -%d %d\n", ent->sig, (int) target_pid);
+ } else if (kill(target_pid, ent->sig)) {
+ /*
+ * XXX - Iff the error was "no such process", should that
+ * really be an error for us? Perhaps the process
+ * is already gone, in which case there would be no
+ * problem with compressing the rotated log file.
+ */
+ warn("can't notify %s, pid %d", target_name,
+ (int) target_pid);
+ } else {
+ did_notify = 1;
+ if (verbose)
+ printf("%s pid %d notified\n", target_name,
+ (int) target_pid);
+ }
+
+ return (did_notify);
+}
+
static void
parse_args(int argc, char **argv)
{
@@ -798,6 +896,9 @@ parse_file(FILE *cf, const char *cfname, struct conf_entry **work_p,
case 'n':
working->flags |= CE_NOSIGNAL;
break;
+ case 'u':
+ working->flags |= CE_SIGNALGROUP;
+ break;
case 'w':
working->flags |= CE_COMPACTWAIT;
break;
@@ -878,9 +979,16 @@ parse_file(FILE *cf, const char *cfname, struct conf_entry **work_p,
/*
* This entry did not specify the 'n' flag, which
* means it should signal syslogd unless it had
- * specified some other pid-file. But we only
- * try to notify syslog if we are root
+ * specified some other pid-file (and obviously the
+ * syslog pid-file will not be for a process-group).
+ * Also, we should only try to notify syslog if we
+ * are root.
*/
+ if (working->flags & CE_SIGNALGROUP) {
+ warnx("Ignoring flag 'U' in line:\n%s",
+ errline);
+ working->flags &= ~CE_SIGNALGROUP;
+ }
if (needroot)
working->pid_file = strdup(_PATH_SYSLOGPID);
}
@@ -909,7 +1017,6 @@ dotrim(const struct conf_entry *ent, char *log, int numdays, int flags)
char tfile[MAXPATHLEN];
int notified, need_notification, fd, _numdays;
struct stat st;
- pid_t pid;
if (archtodir) {
char *p;
@@ -1073,31 +1180,19 @@ dotrim(const struct conf_entry *ent, char *log, int numdays, int flags)
* to the logfile, and as such, that process has already made sure
* that the logfile is not presently in use.
*/
- pid = 0;
need_notification = notified = 0;
if (ent->pid_file != NULL) {
need_notification = 1;
if (!nosignal)
- pid = get_pid(ent->pid_file); /* the normal case! */
+ notified = send_signal(ent); /* the normal case! */
else if (rotatereq)
need_notification = 0;
}
- if (pid) {
- if (noaction) {
- notified = 1;
- printf("\tkill -%d %d\n", ent->sig, (int) pid);
- } else if (kill(pid, ent->sig))
- warn("can't notify daemon, pid %d", (int) pid);
- else {
- notified = 1;
- if (verbose)
- printf("daemon pid %d notified\n", (int) pid);
- }
- }
+
if ((flags & CE_COMPACT) || (flags & CE_BZCOMPACT)) {
if (need_notification && !notified)
warnx(
- "log %s.0 not compressed because daemon not notified",
+ "log %s.0 not compressed because daemon(s) not notified",
log);
else if (noaction)
if (flags & CE_COMPACT)
@@ -1107,7 +1202,7 @@ dotrim(const struct conf_entry *ent, char *log, int numdays, int flags)
else {
if (notified) {
if (verbose)
- printf("small pause to allow daemon to close log\n");
+ printf("small pause to allow daemon(s) to close log\n");
sleep(10);
}
if (archtodir) {
@@ -1243,32 +1338,6 @@ age_old_log(char *file)
return ((int)(timenow - sb.st_mtime + 1800) / 3600);
}
-static pid_t
-get_pid(const char *pid_file)
-{
- FILE *f;
- char line[BUFSIZ];
- pid_t pid = 0;
-
- if ((f = fopen(pid_file, "r")) == NULL)
- warn("can't open %s pid file to restart a daemon",
- pid_file);
- else {
- if (fgets(line, BUFSIZ, f)) {
- pid = atol(line);
- if (pid < MIN_PID || pid > MAX_PID) {
- warnx("preposterous process number: %d",
- (int)pid);
- pid = 0;
- }
- } else
- warn("can't read %s pid file to restart a daemon",
- pid_file);
- (void) fclose(f);
- }
- return (pid);
-}
-
/* Skip Over Blanks */
static char *
sob(char *p)
OpenPOWER on IntegriCloud