deutsch@jplgodo.UUCP (Michael Deutsch ) (04/06/88)
I have a "C" program that records the program results into a file, provided that file already exists. In case the file DOES NOT exist I want the program to function identically but the results should be flushed down the tube, i.e. nowhere, i.e. written to a non-existing file? What sort of "file pointer" or trick should I use to accomplish my goal? Please reply by e-mail, or call me collect : Michael Deutsch (619) 452 - 8649 Thanks
lm@arizona.edu (Larry McVoy) (04/06/88)
In article <9654@jplgodo.UUCP> deutsch@jplgodo.UUCP (Michael Deutsch ) writes: > >I have a "C" program that records the program >results into a file, provided that file already >exists. In case the file DOES NOT exist I want >the program to function identically but the results >should be flushed down the tube, i.e. nowhere ------ UNTESTED! ------- If you are using FILE* # include <stdio.h> # include <sys/types.h> # include <sys/stat.h> FILE* myopen(name) char* name; { struct stat buf; extern errno; if (stat(name, &buf) == -1 && errno == ENOENT) return fopen("/dev/null", "w"); else return fopen(name, "w"); } Else myopen(name) char* name; { struct stat buf; extern errno; if (stat(name, &buf) == -1 && errno == ENOENT) return open("/dev/null", 1); else return open(name, 1); } How's that? -- "These aren't my thoughts, they're my cat walking on the keyboard." Larry McVoy lm@arizona.edu or ...!{uwvax,sun}!arizona.edu!lm
davidsen@steinmetz.steinmetz.ge.com (William E. Davidsen Jr) (04/06/88)
In article <9654@jplgodo.UUCP> deutsch@jplgodo.UUCP (Michael Deutsch ) writes: | | I have a "C" program that records the program | results into a file, provided that file already | exists. In case the file DOES NOT exist I want | the program to function identically but the results | should be flushed down the tube, i.e. nowhere, i.e. | written to a non-existing file? First problem is to open the file if it exists, by fp = fopen(MYFILE, "r+"); /* open, no create */ outflag = fp != NULL; /* set a flag */ if (outflag) fseek(fp, 0L, 2); /* rewind if open ok */ You can then print to the file using a macro, such as: #define cprintf if (outflag) fprintf . . cprintf(fp, "format", data); -- bill davidsen (wedu@ge-crd.arpa) {uunet | philabs | seismo}!steinmetz!crdos1!davidsen "Stupidity, like virtue, is its own reward" -me
ron@topaz.rutgers.edu (Ron Natalie) (04/08/88)
Contemplate the following: fd = open("file", 1); if(fd == -1) fd = open("/dev/null", 1);
flaps@dgp.toronto.edu (Alan J Rosenthal) (04/08/88)
davidsen@crdos1.UUCP (bill davidsen) writes: > if (outflag) fseek(fp, 0L, 2); /* rewind if open ok */ That's "fseek(fp,0L,0)". The given fseek() call seeks to the end of the file. > #define cprintf if (outflag) fprintf This kind of macro is very unsafe. Consider: if(something) cprintf(blah blah); else something else; The `else' clause will pair with the if in the cprintf expansion, much to your surprise and irritation. When at all possible, define macros to be expressions rather than larger amounts of code. For example: extern int fprintf(),mydonothing(); #define cprintf (outflag ? fprintf : mydonothing) and, elsewhere: int mydonothing() { return(0); } Some adjustments are needed to make it valid ANSI C due to mydonothing()'s being variadic; I think fprintf() will be declared in stdio.h but I'm not sure. ajr -- "Comment, Spock?" "Very bad poetry, Captain."
wes@obie.UUCP (Barnacle Wes) (04/11/88)
In article <9654@jplgodo.UUCP> deutsch@jplgodo.UUCP (Michael Deutsch ) writes: | I have a "C" program that records the program | results into a file, provided that file already | exists. In case the file DOES NOT exist I want | the program to function identically but the results | should be flushed down the tube, i.e. nowhere, i.e. | written to a non-existing file? In article <10285@steinmetz.steinmetz.ge.com>, davidsen@steinmetz.steinmetz.ge.com (William E. Davidsen Jr) replies: > First problem is to open the file if it exists, by > fp = fopen(MYFILE, "r+"); /* open, no create */ > outflag = fp != NULL; /* set a flag */ > if (outflag) fseek(fp, 0L, 2); /* rewind if open ok */ > > You can then print to the file using a macro, such as: > #define cprintf if (outflag) fprintf > . > . > cprintf(fp, "format", data); I'd do it slightly different. Unless you need speed, try using access(2) to determine if the file is available to you, and if not open /dev/null for writing: char *name; FILE *ofp; if (access("/data/file/name", 02)) /* 02 = write access */ name = "/data/file/name"; else name = "/dev/null"; ofp = fopen(name, "a"); ... Then just fprintf all of your data to handle "ofp". Less efficient in the no-output case, but it makes the program somewhat easier to read. -- /\ - "Against Stupidity, - {backbones}! /\/\ . /\ - The Gods Themselves - utah-cs!utah-gr! / \/ \/\/ \ - Contend in Vain." - uplherc!sp7040! / U i n T e c h \ - Schiller - obie!wes
friedl@vsi.UUCP (Stephen J. Friedl) (04/16/88)
In article <9654@jplgodo.UUCP> deutsch@jplgodo.UUCP (Michael Deutsch ) writes: > I have a "C" program that records the program results into a file, > provided that file already exists. In case the file DOES NOT exist > I want the program to function identically but the results should > be flushed down the tube, i.e. nowhere, i.e. written to a nong > file? Then (William E. Davidsen Jr) replies: > [little C fragment to do the above] In article <147@obie.UUCP>, wes@obie.UUCP (Barnacle Wes) writes: > I'd do it slightly different. Unless you need speed, try using > access(2) to determine if the file is available to you, and if not > open /dev/null for writing: > > [little C fragment to do the above] AAAAAAAAAARGH! Please do not use access(2) as a handy-dandy "does the file exist?" function. It is designed to be used by set-{user,group}-id programs to see if the underlying user has permission to access the file in the requested manner. I hate to sound like a flamer, but programmers who do not understand the troubles with access(2) should probably not use it; you will make life difficult for somebody down the road. Stat(2) can be used to do the same thing with just a little extra code. I wrote an "accfile(3)" function that does what you *think* access(2) is doing; send me a note to get a copy. Steve Friedl, resident access(2)-basher -- Steve Friedl V-Systems, Inc. "Yes, I'm jeff@unh's brother" friedl@vsi.com {backbones}!vsi.com!friedl attmail!vsi!friedl
henry@utzoo.uucp (Henry Spencer) (04/17/88)
> I'd do it slightly different. Unless you need speed, try using > access(2) to determine if the file is available to you... --------------------------> NO!!! <----------------------- You should never use access(2) except when a setuid program wants to determine whether a file would be accessible in the absence of setuid privileges. For determining accessibility in normal circumstances, use stat(2) and look at the mode bits. (There was an eaccess() function posted to one of the sources groups a few years ago that would do this for you.) If your program happens to be run under setuid conditions, and it is using access(2) for ordinary availability checking, it will get the wrong answers. -- "Noalias must go. This is | Henry Spencer @ U of Toronto Zoology non-negotiable." --DMR | {ihnp4,decvax,uunet!mnetor}!utzoo!henry
mouse@mcgill-vision.UUCP (der Mouse) (04/23/88)
In article <147@obie.UUCP>, wes@obie.UUCP (Barnacle Wes) writes: > I'd do it slightly different. Unless you need speed, try using > access(2) to determine if the file is available to you, and if not > open /dev/null for writing: [code which is supposed to do that - I didn't check it] This is wrong if the program might ever run setuid. access() does not exist to allow vanilla users to find out whether files are accessible; it's for setuid programs to determine whether the real user can access a file. (It's the wrong way to do even that, because of the resulting window, but that's another can of worms.) The right way to find out whether you can open a file for write is...try it! der Mouse uucp: mouse@mcgill-vision.uucp arpa: mouse@larry.mcrcim.mcgill.edu