mirror of
git://git.code.sf.net/p/dhcpd-pools/code
synced 2025-12-16 15:57:00 +00:00
output: verify stream status when closing files
Includes also closing stdout and stderr at the end of execution. Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
parent
97e5b59b78
commit
3ef5d6c07f
4 changed files with 39 additions and 4 deletions
|
|
@ -77,6 +77,8 @@ int main(int argc, char **argv)
|
|||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
atexit(close_stdout);
|
||||
|
||||
/* FIXME: make these allocations dynamic up on need. */
|
||||
config.dhcpdconf_file = safe_malloc(sizeof(char) * MAXLEN);
|
||||
config.dhcpdlease_file = safe_malloc(sizeof(char) * MAXLEN);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include <config.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Feature test switches */
|
||||
#define _POSIX_SOURCE 1
|
||||
|
|
@ -167,6 +168,8 @@ void *safe_malloc(const size_t size)
|
|||
void *safe_realloc(void *__restrict ptr, const size_t size);
|
||||
char *safe_strdup(const char *__restrict str) __attribute__ ((nonnull(1)));
|
||||
int xstrstr(char *__restrict a, char *__restrict b, int len);
|
||||
int close_stream(FILE * stream);
|
||||
void close_stdout(void);
|
||||
void print_version(void) __attribute__ ((noreturn));
|
||||
void usage(int status) __attribute__ ((noreturn));
|
||||
/* qsort required functions... */
|
||||
|
|
|
|||
30
src/other.c
30
src/other.c
|
|
@ -42,6 +42,7 @@
|
|||
#else
|
||||
extern void exit();
|
||||
extern char *malloc();
|
||||
extern void _exit();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
|
|
@ -52,9 +53,12 @@ extern char *malloc();
|
|||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdio_ext.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* Simple memory allocation wrapper */
|
||||
void *safe_malloc(const size_t size)
|
||||
|
|
@ -150,6 +154,32 @@ void clean_up(void)
|
|||
free(shared_networks);
|
||||
}
|
||||
|
||||
int close_stream(FILE * stream)
|
||||
{
|
||||
const int some_pending = (__fpending(stream) != 0);
|
||||
const int prev_fail = (ferror(stream) != 0);
|
||||
const int fclose_fail = (fclose(stream) != 0);
|
||||
if (prev_fail || (fclose_fail && (some_pending || errno != EBADF))) {
|
||||
if (!fclose_fail)
|
||||
errno = 0;
|
||||
return EOF;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Use atexit(); */
|
||||
void close_stdout(void)
|
||||
{
|
||||
if (close_stream(stdout) != 0 && !(errno == EPIPE)) {
|
||||
char const *write_error = "write error";
|
||||
error(0, errno, "%s", write_error);
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (close_stream(stderr) != 0)
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void __attribute__ ((__noreturn__)) print_version(void)
|
||||
{
|
||||
fprintf(stdout, "%s\n"
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ int output_txt(void)
|
|||
warn("output_txt: fflush");
|
||||
}
|
||||
} else {
|
||||
ret = fclose(outfile);
|
||||
ret = close_stream(outfile);
|
||||
if (ret) {
|
||||
warn("output_txt: fclose");
|
||||
}
|
||||
|
|
@ -304,7 +304,7 @@ int output_xml(void)
|
|||
warn("output_xml: fflush");
|
||||
}
|
||||
} else {
|
||||
ret = fclose(outfile);
|
||||
ret = close_stream(outfile);
|
||||
if (ret) {
|
||||
warn("output_xml: fclose");
|
||||
}
|
||||
|
|
@ -633,7 +633,7 @@ int output_html(void)
|
|||
warn("output_html: fflush");
|
||||
}
|
||||
} else {
|
||||
ret = fclose(outfile);
|
||||
ret = close_stream(outfile);
|
||||
if (ret) {
|
||||
warn("output_html: fclose");
|
||||
}
|
||||
|
|
@ -781,7 +781,7 @@ int output_csv(void)
|
|||
warn("output_cvs: fflush");
|
||||
}
|
||||
} else {
|
||||
ret = fclose(outfile);
|
||||
ret = close_stream(outfile);
|
||||
if (ret) {
|
||||
warn("output_cvs: fclose");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue