Path: utzoo!mnetor!uunet!husc6!mailrus!ames!elroy!spl1!laidbak!daveb From: daveb@laidbak.UUCP (Dave Burton) Newsgroups: comp.unix.wizards Subject: Re: Writing to A NON-Existing File in C Message-ID: <1399@laidbak.UUCP> Date: 10 Apr 88 04:48:08 GMT References: <12895@brl-adm.ARPA> Reply-To: daveb@laidbak.UUCP (Dave Burton) Organization: is pretty bad/My method of Lines: 91 Summary: candidate for the 'n' key In article <12895@brl-adm.ARPA> drears@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 |#include |#include |#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 Naperville, IL 60540