/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1985-2010 AT&T Intellectual Property *
* and is licensed under the *
* Common Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* Phong Vo <kpv@research.att.com> *
* *
***********************************************************************/
#include "sfhdr.h"
** The stream is originally created as a memory-resident stream.
** When this memory is exceeded, a real temp file will be created.
** The temp file creation sequence is somewhat convoluted so that
** pool/stack/discipline will work correctly.
**
** Written by David Korn and Kiem-Phong Vo.
*/
#if _tmp_rmfail
/* File not removable while there is an open file descriptor.
** To ensure that temp files are properly removed, we need:
** 1. A discipline to remove a file when the corresponding stream is closed.
** Care must be taken to close the file descriptor before removing the
** file because systems such as NT do not allow file removal while
** there is an open file handle.
** 2. An atexit() function is set up to close temp files when process exits.
** 3. On systems with O_TEMPORARY (e.g., NT), this is used to further ensure
** that temp files will be removed after the last handle is closed.
*/
struct _file_s
Sfio_t* f; /* associated stream */
};
#if __STD_C
#else
Sfio_t* f;
int type;
#endif
{
return -1;
if(type == SF_CLOSING)
{
if(ff->f == f)
break;
if(ff)
{ if(!last)
if(_Sfnotify)
f->file = -1;
errno = 0;
}
(void)vtmtxunlock(_Sfmutex);
}
return 0;
}
#if __STD_C
static void _rmfiles(void)
#else
static void _rmfiles()
#endif
}
(void)vtmtxunlock(_Sfmutex);
}
#endif /*_tmp_rmfail*/
#if __STD_C
#else
Sfio_t* f;
char* file;
#endif
{
#if _tmp_rmfail /* remove only when stream is closed */
if(!File)
return -1;
ff->f = f;
(void)vtmtxunlock(_Sfmutex);
#else /* can remove now */
errno = 0;
#endif
return 0;
}
#if !_PACKAGE_ast
#if __STD_C
#else
char** _sfgetpath(path)
char* path;
#endif
reg int n;
return NIL(char**);
for(p = path, n = 0;;) /* count number of directories */
{ while(*p == ':')
++p;
if(*p == 0)
break;
n += 1;
while(*p && *p != ':') /* skip dir name */
++p;
}
return NIL(char**);
return NIL(char**);
}
for(n = 0;; ++n)
{ while(*p == ':')
++p;
if(*p == 0)
break;
dirs[n] = p;
while(*p && *p != ':')
++p;
if(*p == ':')
*p++ = 0;
}
return dirs;
}
#endif /*!_PACKAGE_ast*/
#if __STD_C
#else
static int _tmpfd(f)
Sfio_t* f;
#endif
{
int fd;
#if _PACKAGE_ast
return -1;
#else
int t;
/* set up path of dirs to create temp files */
return -1;
return -1;
}
}
/* set current directory to create this temp file */
if(Tmpcur)
Tmpcur += 1;
fd = -1;
for(t = 0; t < 10; ++t)
{ /* compute a random name */
if(A == 0 || t > 0) /* get a quasi-random coefficient */
{ reg int r;
if(Key == 0)
A ^= Key;
if((r = (A-1) & 03) != 0) /* Knuth vol.2, page.16, Thm.A */
A += 4-r;
}
if(!file)
return -1;
#if _has_oflags
break;
#else
{ /* file already exists */
fd = -1;
}
{ /* reopen for read and write */
break;
/* don't know what happened but must remove file */
errno = 0;
}
#endif /* _has_oflags */
}
if(fd >= 0)
#endif /* _PACKAGE_ast */
return fd;
}
#if __STD_C
#else
Sfio_t* f;
int type;
#endif
{
/* the discipline needs to change only under the following exceptions */
return 0;
/* notify function */
/* try to create the temp file */
return -1;
/* make sure that the notify function won't be called here since
we are only interested in creating the file, not the stream */
_Sfnotify = 0;
if(!sf)
return -1;
}
/* make sure that new stream has the same mode */
/* now remake the old stream into the new image */
}
/* announce change of status */
if(notifyf)
/* erase all traces of newf */
return 1;
}
#if __STD_C
#else
size_t s;
#endif
{
Sfio_t* f;
#if _tmp_rmfail
#else
#endif
};
/* start with a memory resident stream */
/* make the file now */
{ sfclose(f);
}
return f;
}