On Friday, 2000-02-04 at 06:48:37 -0700, Tom Christiansen wrote:

> ...
>       CODE:
>     #ifdef PerlIO
>           fp = PerlIO_tmpfile();
>     #else
>           fp = tmpfile();
>     #endif
> ...

> Which is just calling the standard POSIX tmpfile() function.  Well,
> sometimes.  If you use the Perl I/O abstraction, then you get either
> the real tmpfile(), or under sfio, some sftmp(0) thingie that I
> know nothing about.  The only hole I see is in my ignorance of the
> possible sfio-related sftmp(0) call.  Enlightenment in this area
> is welcome.

--- Also sprach Tom Christiansen ---

Both sfio97 and sfio98 have (except for one teensy change) the same
sftmp.c. sftmp.c has this file creation code:

        file = NIL(char*); fd = -1;
        for(t = 0; t < 10; ++t)
        {       /* compute a random name */
#if !_PACKAGE_ast
                static ulong    Key, A;
                if(A == 0 || t > 0)     /* get a quasi-random coefficient */
                {       reg int r;
                        A = (ulong)time(NIL(time_t*)) ^ (((ulong)(&t)) >> 3);
                        if(Key == 0)
                                Key = (A >> 16) | ((A&0xffff)<<16);
                        A ^= Key;
                        if((r = (A-1) & 03) != 0) /* Knuth vol.2, page.16, Thm.A */
                                A += 4-r;
                }

                Key = A*Key + 987654321;
                file = sfprints("%s/sf%3.3.32lu.%3.3.32lu",
                                Tmpcur[0], (Key>>15)&0x7fff, Key&0x7fff);
#else
                file = pathtmp(file,NiL,"sf",NiL);
#endif /*!_PACKAGE_ast*/

                if(!file)
                        return -1;
#if _has_oflags
                if((fd = open(file,O_RDWR|O_CREAT|O_EXCL|O_TEMPORARY,SF_CREATMODE)) >= 
0)
                        break;
#else
                if((fd = open(file,O_RDONLY)) >= 0)
                {       /* file already exists */
                        CLOSE(fd);
                        fd = -1;
                }
                else if((fd = creat(file,SF_CREATMODE)) >= 0)
                {       /* reopen for read and write */
                        CLOSE(fd);
                        if((fd = open(file,O_RDWR)) >= 0)
                                break;

                        /* don't know what happened but must remove file */
                        while(remove(file) < 0 && errno == EINTR)
                                errno = 0;
                }
#endif
        }

        if(fd >= 0)
                _rmtmp(f, file);

I suppose ast is a Win32 matter *I* know nothing about.

So sfio goes to some length to randomize the filename, and then insists
on creating a new file. The randomization seems to be reasonably safe
from denial of service. sftmp can also use TMPPATH and TMPDIR.

sftmp will remove the file (_rmtmp) immediately unless _tmp_rmfail is
defined. I found no #define for that in the sfio98 code. (?)

Lupe Christoph
--
| [EMAIL PROTECTED]       |        http://free.prohosting.com/~lupe |
| "jryy vg ybbxf yvxr gur l2x oht qvqa'g erne vg'f htyl urnq." "lrc. gur |
| qbbzfnlref unir orra cebira jebat lrg ntnva."  ....  "qvq lbh frr gung |
| gbb?" "ubhfgba. jr unir n ceboyrz."           User Friendly 2000-01-01 |

Reply via email to