Clarify how one is supposed to use the pointers returned by getutentries()
(the utmpentry.c code), specifically with respect to who owns them and when to free them. Now they're owned by utmpentry.c, only. Abolish the freeutentries() function, which was the wrong abstraction; add instead endutentries(), which flushes out the internally managed memory. Update callers as necessary. Some (e.g. talkd) had been leaking memory; others (e.g. syslogd) had been accidentally freeing and reloading utmp more often than necessary. There are a couple untidy bits in users and rwhod that someone should look after sometime, maybe. Fixes PR bin/35131, which was about talkd's memory leak.
This commit is contained in:
parent
96f87739b6
commit
16e3bec279
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dm.c,v 1.24 2007/12/15 19:44:40 perry Exp $ */
|
||||
/* $NetBSD: dm.c,v 1.25 2008/07/13 20:07:48 dholland Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987, 1993
|
||||
@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1987, 1993\n\
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)dm.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: dm.c,v 1.24 2007/12/15 19:44:40 perry Exp $");
|
||||
__RCSID("$NetBSD: dm.c,v 1.25 2008/07/13 20:07:48 dholland Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -247,15 +247,10 @@ load(void)
|
||||
int
|
||||
users(void)
|
||||
{
|
||||
static struct utmpentry *ohead = NULL;
|
||||
struct utmpentry *ep;
|
||||
int nusers;
|
||||
|
||||
nusers = getutentries(NULL, &ep);
|
||||
if (ep != ohead) {
|
||||
freeutentries(ep);
|
||||
ohead = ep;
|
||||
}
|
||||
return nusers;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: comsat.c,v 1.36 2007/05/03 15:09:41 christos Exp $ */
|
||||
/* $NetBSD: comsat.c,v 1.37 2008/07/13 20:07:48 dholland Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1993
|
||||
@ -36,7 +36,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1993\n\
|
||||
#if 0
|
||||
static char sccsid[] = "from: @(#)comsat.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: comsat.c,v 1.36 2007/05/03 15:09:41 christos Exp $");
|
||||
__RCSID("$NetBSD: comsat.c,v 1.37 2008/07/13 20:07:48 dholland Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -82,7 +82,6 @@ __RCSID("$NetBSD: comsat.c,v 1.36 2007/05/03 15:09:41 christos Exp $");
|
||||
static int logging;
|
||||
static int debug;
|
||||
static char hostname[MAXHOSTNAMELEN + 1];
|
||||
static time_t utmpmtime; /* last modification time for utmp/x */
|
||||
static int nutmp;
|
||||
static struct utmpentry *utmp = NULL;
|
||||
static time_t lastmsgtime;
|
||||
@ -173,9 +172,6 @@ onalrm(int signo)
|
||||
static void
|
||||
checkutmp(void)
|
||||
{
|
||||
struct stat statbf;
|
||||
time_t newtime = 0;
|
||||
|
||||
if (!needupdate)
|
||||
return;
|
||||
needupdate = 0;
|
||||
@ -183,21 +179,7 @@ checkutmp(void)
|
||||
if (time(NULL) - lastmsgtime >= MAXIDLE)
|
||||
exit(0);
|
||||
(void)alarm((u_int)15);
|
||||
#ifdef SUPPORT_UTMP
|
||||
if (stat(_PATH_UTMP, &statbf) != -1)
|
||||
if (statbf.st_mtime > newtime)
|
||||
newtime = statbf.st_mtime;
|
||||
#endif
|
||||
#ifdef SUPPORT_UTMPX
|
||||
if (stat(_PATH_UTMPX, &statbf) != -1)
|
||||
if (statbf.st_mtime > newtime)
|
||||
newtime = statbf.st_mtime;
|
||||
#endif
|
||||
if (newtime > utmpmtime) {
|
||||
freeutentries(utmp);
|
||||
nutmp = getutentries(NULL, &utmp);
|
||||
utmpmtime = newtime;
|
||||
}
|
||||
nutmp = getutentries(NULL, &utmp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: vmstat.c,v 1.70 2008/02/11 03:51:17 dyoung Exp $ */
|
||||
/* $NetBSD: vmstat.c,v 1.71 2008/07/13 20:07:48 dholland Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1983, 1989, 1992, 1993
|
||||
@ -34,7 +34,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 1/12/94";
|
||||
#endif
|
||||
__RCSID("$NetBSD: vmstat.c,v 1.70 2008/02/11 03:51:17 dyoung Exp $");
|
||||
__RCSID("$NetBSD: vmstat.c,v 1.71 2008/07/13 20:07:48 dholland Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
@ -680,15 +680,10 @@ static int
|
||||
ucount(void)
|
||||
{
|
||||
static int onusers = -1;
|
||||
static struct utmpentry *oehead = NULL;
|
||||
int nusers = 0;
|
||||
struct utmpentry *ehead;
|
||||
|
||||
nusers = getutentries(NULL, &ehead);
|
||||
if (oehead != ehead) {
|
||||
freeutentries(oehead);
|
||||
oehead = ehead;
|
||||
}
|
||||
|
||||
if (nusers != onusers) {
|
||||
if (nusers == 1)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: users.c,v 1.13 2004/01/05 23:23:37 jmmv Exp $ */
|
||||
/* $NetBSD: users.c,v 1.14 2008/07/13 20:07:48 dholland Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1987, 1993
|
||||
@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1987, 1993\n\
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)users.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif
|
||||
__RCSID("$NetBSD: users.c,v 1.13 2004/01/05 23:23:37 jmmv Exp $");
|
||||
__RCSID("$NetBSD: users.c,v 1.14 2008/07/13 20:07:48 dholland Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -79,6 +79,14 @@ main(argc, argv)
|
||||
if (ncnt == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* XXX the utmp list belongs to getutentries and we shouldn't
|
||||
* sort it in place. Since we don't call endutentries and we
|
||||
* don't call getutentries again it doesn't matter, but it's
|
||||
* untidy. Maybe give getutentries a sort function? It has to
|
||||
* sort anyway if it's merging utmp and utmpx data.
|
||||
*/
|
||||
|
||||
from = ehead;
|
||||
ehead = NULL;
|
||||
while (from != NULL) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: utmpentry.c,v 1.14 2008/04/28 20:24:15 martin Exp $ */
|
||||
/* $NetBSD: utmpentry.c,v 1.15 2008/07/13 20:07:48 dholland Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
@ -31,7 +31,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: utmpentry.c,v 1.14 2008/04/28 20:24:15 martin Exp $");
|
||||
__RCSID("$NetBSD: utmpentry.c,v 1.15 2008/07/13 20:07:48 dholland Exp $");
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
@ -157,23 +157,24 @@ setup(const char *fname)
|
||||
#endif
|
||||
|
||||
void
|
||||
freeutentries(struct utmpentry *ep)
|
||||
endutentries(void)
|
||||
{
|
||||
struct utmpentry *ep;
|
||||
|
||||
#ifdef SUPPORT_UTMP
|
||||
timespecclear(&utmptime);
|
||||
#endif
|
||||
#ifdef SUPPORT_UTMPX
|
||||
timespecclear(&utmpxtime);
|
||||
#endif
|
||||
if (ep == ehead) {
|
||||
ehead = NULL;
|
||||
numutmp = 0;
|
||||
}
|
||||
ep = ehead;
|
||||
while (ep) {
|
||||
struct utmpentry *sep = ep;
|
||||
ep = ep->next;
|
||||
free(sep);
|
||||
}
|
||||
ehead = NULL;
|
||||
numutmp = 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: utmpentry.h,v 1.6 2008/04/28 20:24:15 martin Exp $ */
|
||||
/* $NetBSD: utmpentry.h,v 1.7 2008/07/13 20:07:49 dholland Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
@ -60,5 +60,17 @@ struct utmpentry {
|
||||
extern int maxname, maxline, maxhost;
|
||||
extern int etype;
|
||||
|
||||
/*
|
||||
* getutentries provides a linked list of struct utmpentry and returns
|
||||
* the number of entries. The first argument, if not null, names an
|
||||
* alternate utmp(x) file to look in.
|
||||
*
|
||||
* The memory returned by getutentries belongs to getutentries. The
|
||||
* list returned (or elements of it) may be returned again later if
|
||||
* utmp hasn't changed in the meantime.
|
||||
*
|
||||
* endutentries clears and frees the cached data.
|
||||
*/
|
||||
|
||||
int getutentries(const char *, struct utmpentry **);
|
||||
void freeutentries(struct utmpentry *);
|
||||
void endutentries(void);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rwhod.c,v 1.35 2007/12/15 19:44:56 perry Exp $ */
|
||||
/* $NetBSD: rwhod.c,v 1.36 2008/07/13 20:07:49 dholland Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1993\n\
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)rwhod.c 8.1 (Berkeley) 6/6/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: rwhod.c,v 1.35 2007/12/15 19:44:56 perry Exp $");
|
||||
__RCSID("$NetBSD: rwhod.c,v 1.36 2008/07/13 20:07:49 dholland Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -373,8 +373,8 @@ send_host_information(int s)
|
||||
count++;
|
||||
|
||||
(void)getutentries(NULL, &ep);
|
||||
/* XXX probably should expose utmp mtime, check that instead */
|
||||
if (ep != ohead) {
|
||||
freeutentries(ep);
|
||||
wlast = &mywd.wd_we[1024 / sizeof(struct whoent) - 1];
|
||||
for (; ep; ep = ep->next) {
|
||||
(void)strncpy(we->we_utmp.out_line, ep->line,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: syslogd.c,v 1.84 2006/11/13 20:24:00 christos Exp $ */
|
||||
/* $NetBSD: syslogd.c,v 1.85 2008/07/13 20:07:49 dholland Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1988, 1993, 1994
|
||||
@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1988, 1993, 1994\n\
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)syslogd.c 8.3 (Berkeley) 4/4/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: syslogd.c,v 1.84 2006/11/13 20:24:00 christos Exp $");
|
||||
__RCSID("$NetBSD: syslogd.c,v 1.85 2008/07/13 20:07:49 dholland Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -1378,17 +1378,12 @@ wallmsg(struct filed *f, struct iovec *iov, size_t iovcnt)
|
||||
static int reenter; /* avoid calling ourselves */
|
||||
int i;
|
||||
char *p;
|
||||
static struct utmpentry *ohead = NULL;
|
||||
struct utmpentry *ep;
|
||||
|
||||
if (reenter++)
|
||||
return;
|
||||
|
||||
(void)getutentries(NULL, &ep);
|
||||
if (ep != ohead) {
|
||||
freeutentries(ohead);
|
||||
ohead = ep;
|
||||
}
|
||||
/* NOSTRICT */
|
||||
for (; ep; ep = ep->next) {
|
||||
if (f->f_type == F_WALL) {
|
||||
|
Loading…
Reference in New Issue
Block a user