drears@ardec.arpa (Dennis G. Rears (FSAC)) (04/10/88)
ok. ok. After over 20 messages I admit I f*cked up on my posting and program. The errors pointed out were: 1) comment should have ended in "*/" not "*?" 2) The declaration #define NULL "/dev/null/" should not have used NUll and the / after null was wrong 3) I use the word FILE instead of FILENAME in my stat(2) call Next time I will not send a program while sleeping. Please no more messages about this. 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" 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 */ } ------------------------------------------------------------ ARPA: drears@ardec-ac4.arpa UUCP: ...!uunet!ardec-ac4.arpa!drears AT&T: 201-724-6639 Snailmail: Box 210, Wharton, NJ 07885 Govt Nonmail: US Army ARDEC, ATTN SMCAR-FSS-E, Dennis Rears Bldg 94, Picatinny Arsenal, NJ 07806 Flames: /dev/null ------------------------------------------------------------
daveb@laidbak.UUCP (Dave Burton) (04/10/88)
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 <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
karish@denali.UUCP (karish) (04/15/88)
Is there a pressing reason to actually WRITE to the bit-bucket, instead of not writing at all? My answer: No, unless the task is to wrap a canned program into a new interface. My solution, which has already been posted (by someone whose mailer screwed up, killing the second partr of the message) is to use a special function to do the output. If a disk file is available, write to it; otherwise, call a null function that doesn't write at all. This can be done either with the C preprocessor (wire in the behavior at compile time) or with pointers to functions. My employer is not so foolish as to agree with all of my opinions. Chuck Karish ARPA: karish@denali.stanford.edu UUCP: {decvax,hplabs!hpda}!mindcrf!karish paper: 1825 California St. #5 Mountain View, CA 94041