diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2005-03-30 07:39:33 +0000 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2005-03-30 07:39:33 +0000 |
commit | c315ff58b3b0a1039073ff37cfbefff721830113 (patch) | |
tree | e755661ddd00cce86819d671127d21772d589d47 /lib | |
parent | bd3b936ce7a27e21cb1d205997a05753e7deb467 (diff) | |
download | coreutils-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.c | 64 |
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; } |