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