Writing to A NON-Existing File in C
Dave Burton
daveb at laidbak.UUCP
Sun Apr 10 14:48:08 AEST 1988
In article <12895 at brl-adm.ARPA> drears at ardec.arpa (Dennis G. Rears (FSAC)) writes:
| ok. ok. After over 20 messages I admit I ------ up on my posting
|and program. The errors pointed out were:
|...
| 2) The declaration #define NULL "/dev/null/"
| should not have used NUll and the / after null was wrong
|...
|Here is a corrected version of it:
|
|#include <stdio.h>
|#include <sys/types.h>
|#include <sys/stat.h>
|#define FILENAME "/usr/foobar" /* not a trademark of AT&T */
|#define DEVNULL "dev/null"
^
Oops - that extra slash belongs here, right? :-)
|main(a,b)
|int a;
|char *b[];
|{
| struct stat buf;
| FILE *fopen(), *fp;
|
| if(stat(FILENAME,&buf)){
| if ( (fp=fopen(DEVNULL,"a")) == NULL ) {
| /* or use perror() */
| (void)fprintf (stderr,
| "%s: Can not open /dev/null file\n",b[0]);
| exit(-1);
| }
| }
| else
| if ( (fp=fopen(FILENAME,"a")) == NULL ) {
| (void)fprintf (stderr,
| "%s: Can not open %sfile\n",b[0],FILENAME);
| exit(-1);
|
| }
|/* go on writing to filepointer fp */
|}
|...
|Flames: /dev/null
^
But we know you know what you're trying to say. :-)
At the risk of beating this topic to death, (oops, too late),
a slight reorganization of your code will
. centralize error exits
. standardize message text (one format string, not two)
. enhance code clarity
. use less string space, at least with some compilers
. provide the correct filename for later error messages
. provide another target for flamers
One alternate is:
filename = FILENAME;
if (!stat(filename, &buf))
filename = DEVNULL;
if ((fp = fopen(filename, "a")) == NULL) {
perror(filename);
exit(1);
}
Note that both versions have a problem. If the problem definition
is "write data to FILENAME if it exists _and_ is writable, else use
the bit bucket", then stat() is not the proper operation. A fix:
filename = FILENAME;
if ((fd = open(filename, O_WRONLY|O_APPEND)) != -1) /* available? */
if ((fp = fdopen(fd, "a")) == NULL)
close(fd);
if (fp == NULL) { /* if not available */
filename = DEVNULL;
if ((fp = fopen(filename, "a")) == NULL) {
perror(filename);
exit(1);
}
}
To the Original Poster:
Generally, it is best to write all error/warning messages to stderr
and allow the invoking entity (now that's non-sexist ;-) to redirect
any unwanted output to /dev/null from the command line. This will also
remove the need for the above code.
--
--------------------"Well, it looked good when I wrote it"---------------------
Verbal: Dave Burton Net: ...!ihnp4!laidbak!daveb
V-MAIL: (312) 505-9100 x325 USSnail: 1901 N. Naper Blvd.
#include <disclaimer.h> Naperville, IL 60540
More information about the Comp.unix.wizards
mailing list