summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2005-03-30 07:39:33 +0000
committerPaul Eggert <eggert@cs.ucla.edu>2005-03-30 07:39:33 +0000
commitc315ff58b3b0a1039073ff37cfbefff721830113 (patch)
treee755661ddd00cce86819d671127d21772d589d47 /lib
parentbd3b936ce7a27e21cb1d205997a05753e7deb467 (diff)
downloadcoreutils-c315ff58b3b0a1039073ff37cfbefff721830113.tar.xz
(read_utmp) [!defied UTMP_NAME_FUNCTION]: Add support for options.
Don't assume the file is a regular file.
Diffstat (limited to 'lib')
-rw-r--r--lib/readutmp.c64
1 files changed, 24 insertions, 40 deletions
diff --git a/lib/readutmp.c b/lib/readutmp.c
index c44b47fa7..c3ce7f987 100644
--- a/lib/readutmp.c
+++ b/lib/readutmp.c
@@ -118,55 +118,39 @@ read_utmp (const char *filename, size_t *n_entries, STRUCT_UTMP **utmp_buf,
#else
int
-read_utmp (const char *filename, size_t *n_entries, STRUCT_UTMP **utmp_buf)
+read_utmp (const char *filename, size_t *n_entries, STRUCT_UTMP **utmp_buf,
+ int options)
{
- FILE *utmp;
- struct stat file_stats;
- size_t n_read;
- size_t size;
- size_t i;
- size_t n_desired;
- STRUCT_UTMP *buf;
-
- utmp = fopen (filename, "r");
- if (utmp == NULL)
+ size_t n_read = 0;
+ size_t n_alloc = 0;
+ STRUCT_UTMP *utmp = NULL;
+ int saved_errno;
+ FILE *f = fopen (filename, "r");
+
+ if (! f)
return -1;
- if (fstat (fileno (utmp), &file_stats) != 0)
- {
- int e = errno;
- fclose (utmp);
- errno = e;
- return -1;
- }
- if (! (0 <= file_stats.st_size && file_stats.st_size <= SIZE_MAX))
- xalloc_die ();
- size = file_stats.st_size;
- buf = xmalloc (size);
- n_read = fread (buf, sizeof *buf, size / sizeof *buf, utmp);
- if (ferror (utmp))
+ for (;;)
{
- int e = errno;
- free (buf);
- fclose (utmp);
- errno = e;
- return -1;
+ if (n_read == n_alloc)
+ utmp = x2nrealloc (utmp, &n_alloc, sizeof *utmp);
+ if (fread (&utmp[n_read], sizeof utmp[n_read], 1, f) == 0)
+ break;
+ n_read += desirable_utmp_entry (&utmp[n_read], options);
}
- if (fclose (utmp) != 0)
+
+ saved_errno = ferror (f) ? errno : 0;
+ if (fclose (f) != 0)
+ saved_errno = errno;
+ if (saved_errno != 0)
{
- int e = errno;
- free (buf);
- errno = e;
+ free (utmp);
+ errno = saved_errno;
return -1;
}
- n_desired = 0;
- for (i = 0; i < n_read; i++)
- if (desirable_utmp_entry (&utmp[i], options))
- utmp[n_desired++] = utmp[i];
-
- *n_entries = n_desired;
- *utmp_buf = buf;
+ *n_entries = n_read;
+ *utmp_buf = utmp;
return 0;
}