|
Packit Service |
a8c26c |
/***********************************************************************
|
|
Packit Service |
a8c26c |
* *
|
|
Packit Service |
a8c26c |
* This software is part of the ast package *
|
|
Packit Service |
a8c26c |
* Copyright (c) 1985-2012 AT&T Intellectual Property *
|
|
Packit Service |
a8c26c |
* and is licensed under the *
|
|
Packit Service |
a8c26c |
* Eclipse Public License, Version 1.0 *
|
|
Packit Service |
a8c26c |
* by AT&T Intellectual Property *
|
|
Packit Service |
a8c26c |
* *
|
|
Packit Service |
a8c26c |
* A copy of the License is available at *
|
|
Packit Service |
a8c26c |
* http://www.eclipse.org/org/documents/epl-v10.html *
|
|
Packit Service |
a8c26c |
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
|
|
Packit Service |
a8c26c |
* *
|
|
Packit Service |
a8c26c |
* Information and Software Systems Research *
|
|
Packit Service |
a8c26c |
* AT&T Research *
|
|
Packit Service |
a8c26c |
* Florham Park NJ *
|
|
Packit Service |
a8c26c |
* *
|
|
Packit Service |
a8c26c |
* Glenn Fowler <gsf@research.att.com> *
|
|
Packit Service |
a8c26c |
* David Korn <dgk@research.att.com> *
|
|
Packit Service |
a8c26c |
* Phong Vo <kpv@research.att.com> *
|
|
Packit Service |
a8c26c |
* *
|
|
Packit Service |
a8c26c |
***********************************************************************/
|
|
Packit Service |
a8c26c |
#include "sfhdr.h"
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
/* Create a temporary stream for read/write.
|
|
Packit Service |
a8c26c |
** The stream is originally created as a memory-resident stream.
|
|
Packit Service |
a8c26c |
** When this memory is exceeded, a real temp file will be created.
|
|
Packit Service |
a8c26c |
** The temp file creation sequence is somewhat convoluted so that
|
|
Packit Service |
a8c26c |
** pool/stack/discipline will work correctly.
|
|
Packit Service |
a8c26c |
**
|
|
Packit Service |
a8c26c |
** Written by David Korn and Kiem-Phong Vo.
|
|
Packit Service |
a8c26c |
*/
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
#if _tmp_rmfail
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
/* File not removable while there is an open file descriptor.
|
|
Packit Service |
a8c26c |
** To ensure that temp files are properly removed, we need:
|
|
Packit Service |
a8c26c |
** 1. A discipline to remove a file when the corresponding stream is closed.
|
|
Packit Service |
a8c26c |
** Care must be taken to close the file descriptor before removing the
|
|
Packit Service |
a8c26c |
** file because systems such as NT do not allow file removal while
|
|
Packit Service |
a8c26c |
** there is an open file handle.
|
|
Packit Service |
a8c26c |
** 2. An atexit() function is set up to close temp files when process exits.
|
|
Packit Service |
a8c26c |
** 3. On systems with O_TEMPORARY (e.g., NT), this is used to further ensure
|
|
Packit Service |
a8c26c |
** that temp files will be removed after the last handle is closed.
|
|
Packit Service |
a8c26c |
*/
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
typedef struct _file_s File_t;
|
|
Packit Service |
a8c26c |
struct _file_s
|
|
Packit Service |
a8c26c |
{ File_t* next; /* link list */
|
|
Packit Service |
a8c26c |
Sfio_t* f; /* associated stream */
|
|
Packit Service |
a8c26c |
char name[1]; /* temp file name */
|
|
Packit Service |
a8c26c |
};
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
static File_t* File; /* list pf temp files */
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
#if __STD_C
|
|
Packit Service |
a8c26c |
static int _tmprmfile(Sfio_t* f, int type, Void_t* val, Sfdisc_t* disc)
|
|
Packit Service |
a8c26c |
#else
|
|
Packit Service |
a8c26c |
static int _tmprmfile(f, type, val, disc)
|
|
Packit Service |
a8c26c |
Sfio_t* f;
|
|
Packit Service |
a8c26c |
int type;
|
|
Packit Service |
a8c26c |
Void_t* val;
|
|
Packit Service |
a8c26c |
Sfdisc_t* disc;
|
|
Packit Service |
a8c26c |
#endif
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
reg File_t *ff, *last;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
NOTUSED(val);
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
if(type == SF_DPOP) /* don't allow this to pop */
|
|
Packit Service |
a8c26c |
return -1;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
if(type == SF_CLOSING)
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
(void)vtmtxlock(_Sfmutex);
|
|
Packit Service |
a8c26c |
for(last = NIL(File_t*), ff = File; ff; last = ff, ff = ff->next)
|
|
Packit Service |
a8c26c |
if(ff->f == f)
|
|
Packit Service |
a8c26c |
break;
|
|
Packit Service |
a8c26c |
if(ff)
|
|
Packit Service |
a8c26c |
{ if(!last)
|
|
Packit Service |
a8c26c |
File = ff->next;
|
|
Packit Service |
a8c26c |
else last->next = ff->next;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
if(_Sfnotify)
|
|
Packit Service |
a8c26c |
(*_Sfnotify)(f,SF_CLOSING,f->file);
|
|
Packit Service |
a8c26c |
CLOSE(f->file);
|
|
Packit Service |
a8c26c |
f->file = -1;
|
|
Packit Service |
a8c26c |
while(sysremovef(ff->name) < 0 && errno == EINTR)
|
|
Packit Service |
a8c26c |
errno = 0;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
free((Void_t*)ff);
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
(void)vtmtxunlock(_Sfmutex);
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
return 0;
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
#if __STD_C
|
|
Packit Service |
a8c26c |
static void _rmfiles(void)
|
|
Packit Service |
a8c26c |
#else
|
|
Packit Service |
a8c26c |
static void _rmfiles()
|
|
Packit Service |
a8c26c |
#endif
|
|
Packit Service |
a8c26c |
{ reg File_t *ff, *next;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
(void)vtmtxlock(_Sfmutex);
|
|
Packit Service |
a8c26c |
for(ff = File; ff; ff = next)
|
|
Packit Service |
a8c26c |
{ next = ff->next;
|
|
Packit Service |
a8c26c |
_tmprmfile(ff->f, SF_CLOSING, NIL(Void_t*), ff->f->disc);
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
(void)vtmtxunlock(_Sfmutex);
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
static Sfdisc_t Rmdisc =
|
|
Packit Service |
a8c26c |
{ NIL(Sfread_f), NIL(Sfwrite_f), NIL(Sfseek_f), _tmprmfile, NIL(Sfdisc_t*) };
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
#endif /*_tmp_rmfail*/
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
#if __STD_C
|
|
Packit Service |
a8c26c |
static int _rmtmp(Sfio_t* f, char* file)
|
|
Packit Service |
a8c26c |
#else
|
|
Packit Service |
a8c26c |
static int _rmtmp(f, file)
|
|
Packit Service |
a8c26c |
Sfio_t* f;
|
|
Packit Service |
a8c26c |
char* file;
|
|
Packit Service |
a8c26c |
#endif
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
#if _tmp_rmfail /* remove only when stream is closed */
|
|
Packit Service |
a8c26c |
reg File_t* ff;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
if(!File)
|
|
Packit Service |
a8c26c |
atexit(_rmfiles);
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
if(!(ff = (File_t*)malloc(sizeof(File_t)+strlen(file))) )
|
|
Packit Service |
a8c26c |
return -1;
|
|
Packit Service |
a8c26c |
(void)vtmtxlock(_Sfmutex);
|
|
Packit Service |
a8c26c |
ff->f = f;
|
|
Packit Service |
a8c26c |
strcpy(ff->name,file);
|
|
Packit Service |
a8c26c |
ff->next = File;
|
|
Packit Service |
a8c26c |
File = ff;
|
|
Packit Service |
a8c26c |
(void)vtmtxunlock(_Sfmutex);
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
#else /* can remove now */
|
|
Packit Service |
a8c26c |
while(sysremovef(file) < 0 && errno == EINTR)
|
|
Packit Service |
a8c26c |
errno = 0;
|
|
Packit Service |
a8c26c |
#endif
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
return 0;
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
#if !_PACKAGE_ast
|
|
Packit Service |
a8c26c |
#define TMPDFLT "/tmp"
|
|
Packit Service |
a8c26c |
static char **Tmppath, **Tmpcur;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
#if __STD_C
|
|
Packit Service |
a8c26c |
char** _sfgetpath(char* path)
|
|
Packit Service |
a8c26c |
#else
|
|
Packit Service |
a8c26c |
char** _sfgetpath(path)
|
|
Packit Service |
a8c26c |
char* path;
|
|
Packit Service |
a8c26c |
#endif
|
|
Packit Service |
a8c26c |
{ reg char *p, **dirs;
|
|
Packit Service |
a8c26c |
reg int n;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
if(!(path = getenv(path)) )
|
|
Packit Service |
a8c26c |
return NIL(char**);
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
for(p = path, n = 0;;) /* count number of directories */
|
|
Packit Service |
a8c26c |
{ while(*p == ':')
|
|
Packit Service |
a8c26c |
++p;
|
|
Packit Service |
a8c26c |
if(*p == 0)
|
|
Packit Service |
a8c26c |
break;
|
|
Packit Service |
a8c26c |
n += 1;
|
|
Packit Service |
a8c26c |
while(*p && *p != ':') /* skip dir name */
|
|
Packit Service |
a8c26c |
++p;
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
if(n == 0 || !(dirs = (char**)malloc((n+1)*sizeof(char*))) )
|
|
Packit Service |
a8c26c |
return NIL(char**);
|
|
Packit Service |
a8c26c |
if(!(p = (char*)malloc(strlen(path)+1)) )
|
|
Packit Service |
a8c26c |
{ free(dirs);
|
|
Packit Service |
a8c26c |
return NIL(char**);
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
strcpy(p,path);
|
|
Packit Service |
a8c26c |
for(n = 0;; ++n)
|
|
Packit Service |
a8c26c |
{ while(*p == ':')
|
|
Packit Service |
a8c26c |
++p;
|
|
Packit Service |
a8c26c |
if(*p == 0)
|
|
Packit Service |
a8c26c |
break;
|
|
Packit Service |
a8c26c |
dirs[n] = p;
|
|
Packit Service |
a8c26c |
while(*p && *p != ':')
|
|
Packit Service |
a8c26c |
++p;
|
|
Packit Service |
a8c26c |
if(*p == ':')
|
|
Packit Service |
a8c26c |
*p++ = 0;
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
dirs[n] = NIL(char*);
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
return dirs;
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
#endif /*!_PACKAGE_ast*/
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
#if __STD_C
|
|
Packit Service |
a8c26c |
static int _tmpfd(Sfio_t* f)
|
|
Packit Service |
a8c26c |
#else
|
|
Packit Service |
a8c26c |
static int _tmpfd(f)
|
|
Packit Service |
a8c26c |
Sfio_t* f;
|
|
Packit Service |
a8c26c |
#endif
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
reg char* file;
|
|
Packit Service |
a8c26c |
int fd;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
#if _PACKAGE_ast
|
|
Packit Service |
a8c26c |
if(!(file = pathtemp(NiL,PATH_MAX,NiL,"sf",&fd)))
|
|
Packit Service |
a8c26c |
return -1;
|
|
Packit Service |
a8c26c |
_rmtmp(f, file);
|
|
Packit Service |
a8c26c |
free(file);
|
|
Packit Service |
a8c26c |
#else
|
|
Packit Service |
a8c26c |
int t;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
/* set up path of dirs to create temp files */
|
|
Packit Service |
a8c26c |
if(!Tmppath && !(Tmppath = _sfgetpath("TMPPATH")) )
|
|
Packit Service |
a8c26c |
{ if(!(Tmppath = (char**)malloc(2*sizeof(char*))) )
|
|
Packit Service |
a8c26c |
return -1;
|
|
Packit Service |
a8c26c |
if(!(file = getenv("TMPDIR")) )
|
|
Packit Service |
a8c26c |
file = TMPDFLT;
|
|
Packit Service |
a8c26c |
if(!(Tmppath[0] = (char*)malloc(strlen(file)+1)) )
|
|
Packit Service |
a8c26c |
{ free(Tmppath);
|
|
Packit Service |
a8c26c |
Tmppath = NIL(char**);
|
|
Packit Service |
a8c26c |
return -1;
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
strcpy(Tmppath[0],file);
|
|
Packit Service |
a8c26c |
Tmppath[1] = NIL(char*);
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
/* set current directory to create this temp file */
|
|
Packit Service |
a8c26c |
if(Tmpcur)
|
|
Packit Service |
a8c26c |
Tmpcur += 1;
|
|
Packit Service |
a8c26c |
if(!Tmpcur || !Tmpcur[0])
|
|
Packit Service |
a8c26c |
Tmpcur = Tmppath;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
fd = -1;
|
|
Packit Service |
a8c26c |
for(t = 0; t < 10; ++t)
|
|
Packit Service |
a8c26c |
{ /* compute a random name */
|
|
Packit Service |
a8c26c |
static ulong Key, A;
|
|
Packit Service |
a8c26c |
if(A == 0 || t > 0) /* get a quasi-random coefficient */
|
|
Packit Service |
a8c26c |
{ reg int r;
|
|
Packit Service |
a8c26c |
A = (ulong)time(NIL(time_t*)) ^ (((ulong)(&t)) >> 3);
|
|
Packit Service |
a8c26c |
if(Key == 0)
|
|
Packit Service |
a8c26c |
Key = (A >> 16) | ((A&0xffff)<<16);
|
|
Packit Service |
a8c26c |
A ^= Key;
|
|
Packit Service |
a8c26c |
if((r = (A-1) & 03) != 0) /* Knuth vol.2, page.16, Thm.A */
|
|
Packit Service |
a8c26c |
A += 4-r;
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
Key = A*Key + 987654321;
|
|
Packit Service |
a8c26c |
file = sfprints("%s/sf%3.3.32lu.%3.3.32lu",
|
|
Packit Service |
a8c26c |
Tmpcur[0], (Key>>15)&0x7fff, Key&0x7fff);
|
|
Packit Service |
a8c26c |
if(!file)
|
|
Packit Service |
a8c26c |
return -1;
|
|
Packit Service |
a8c26c |
#if _has_oflags
|
|
Packit Service |
a8c26c |
if((fd = sysopenf(file,O_RDWR|O_CREAT|O_EXCL|O_TEMPORARY,SF_CREATMODE)) >= 0)
|
|
Packit Service |
a8c26c |
break;
|
|
Packit Service |
a8c26c |
#else
|
|
Packit Service |
a8c26c |
if((fd = sysopenf(file,O_RDONLY)) >= 0)
|
|
Packit Service |
a8c26c |
{ /* file already exists */
|
|
Packit Service |
a8c26c |
CLOSE(fd);
|
|
Packit Service |
a8c26c |
fd = -1;
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
else if((fd = syscreatf(file,SF_CREATMODE)) >= 0)
|
|
Packit Service |
a8c26c |
{ /* reopen for read and write */
|
|
Packit Service |
a8c26c |
CLOSE(fd);
|
|
Packit Service |
a8c26c |
if((fd = sysopenf(file,O_RDWR)) >= 0)
|
|
Packit Service |
a8c26c |
break;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
/* don't know what happened but must remove file */
|
|
Packit Service |
a8c26c |
while(sysremovef(file) < 0 && errno == EINTR)
|
|
Packit Service |
a8c26c |
errno = 0;
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
#endif /* _has_oflags */
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
if(fd >= 0)
|
|
Packit Service |
a8c26c |
_rmtmp(f, file);
|
|
Packit Service |
a8c26c |
#endif /* _PACKAGE_ast */
|
|
Packit Service |
a8c26c |
return fd;
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
#if __STD_C
|
|
Packit Service |
a8c26c |
static int _tmpexcept(Sfio_t* f, int type, Void_t* val, Sfdisc_t* disc)
|
|
Packit Service |
a8c26c |
#else
|
|
Packit Service |
a8c26c |
static int _tmpexcept(f,type,val,disc)
|
|
Packit Service |
a8c26c |
Sfio_t* f;
|
|
Packit Service |
a8c26c |
int type;
|
|
Packit Service |
a8c26c |
Void_t* val;
|
|
Packit Service |
a8c26c |
Sfdisc_t* disc;
|
|
Packit Service |
a8c26c |
#endif
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
reg int fd, m;
|
|
Packit Service |
a8c26c |
reg Sfio_t* sf;
|
|
Packit Service |
a8c26c |
Sfio_t newf, savf;
|
|
Packit Service |
a8c26c |
Sfnotify_f notify = _Sfnotify;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
NOTUSED(val);
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
/* the discipline needs to change only under the following exceptions */
|
|
Packit Service |
a8c26c |
if(type != SF_WRITE && type != SF_SEEK &&
|
|
Packit Service |
a8c26c |
type != SF_DPUSH && type != SF_DPOP && type != SF_DBUFFER)
|
|
Packit Service |
a8c26c |
return 0;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
/* try to create the temp file */
|
|
Packit Service |
a8c26c |
SFCLEAR(&newf,NIL(Vtmutex_t*));
|
|
Packit Service |
a8c26c |
newf.flags = SF_STATIC;
|
|
Packit Service |
a8c26c |
newf.mode = SF_AVAIL;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
if((fd = _tmpfd(f)) < 0 )
|
|
Packit Service |
a8c26c |
return -1;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
/* make sure that the notify function won't be called here since
|
|
Packit Service |
a8c26c |
we are only interested in creating the file, not the stream */
|
|
Packit Service |
a8c26c |
_Sfnotify = 0;
|
|
Packit Service |
a8c26c |
sf = sfnew(&newf,NIL(Void_t*),(size_t)SF_UNBOUND,fd,SF_READ|SF_WRITE);
|
|
Packit Service |
a8c26c |
_Sfnotify = notify;
|
|
Packit Service |
a8c26c |
if(!sf)
|
|
Packit Service |
a8c26c |
return -1;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
if(newf.mutex) /* don't need a mutex for this stream */
|
|
Packit Service |
a8c26c |
{ (void)vtmtxclrlock(newf.mutex);
|
|
Packit Service |
a8c26c |
(void)vtmtxclose(newf.mutex);
|
|
Packit Service |
a8c26c |
newf.mutex = NIL(Vtmutex_t*);
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
/* make sure that new stream has the same mode */
|
|
Packit Service |
a8c26c |
if((m = f->flags&(SF_READ|SF_WRITE)) != (SF_READ|SF_WRITE))
|
|
Packit Service |
a8c26c |
sfset(sf, ((~m)&(SF_READ|SF_WRITE)), 0);
|
|
Packit Service |
a8c26c |
sfset(sf, (f->mode&(SF_READ|SF_WRITE)), 1);
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
/* now remake the old stream into the new image */
|
|
Packit Service |
a8c26c |
memcpy((Void_t*)(&savf), (Void_t*)f, sizeof(Sfio_t));
|
|
Packit Service |
a8c26c |
memcpy((Void_t*)f, (Void_t*)sf, sizeof(Sfio_t));
|
|
Packit Service |
a8c26c |
f->push = savf.push;
|
|
Packit Service |
a8c26c |
f->pool = savf.pool;
|
|
Packit Service |
a8c26c |
f->rsrv = savf.rsrv;
|
|
Packit Service |
a8c26c |
f->proc = savf.proc;
|
|
Packit Service |
a8c26c |
f->mutex = savf.mutex;
|
|
Packit Service |
a8c26c |
f->stdio = savf.stdio;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
/* remove the SF_STATIC bit if it was only set above in making newf */
|
|
Packit Service |
a8c26c |
if(!(savf.flags&SF_STATIC) )
|
|
Packit Service |
a8c26c |
f->flags &= ~SF_STATIC;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
if(savf.data)
|
|
Packit Service |
a8c26c |
{ SFSTRSIZE(&savf);
|
|
Packit Service |
a8c26c |
if(!(savf.flags&SF_MALLOC) )
|
|
Packit Service |
a8c26c |
(void)sfsetbuf(f,(Void_t*)savf.data,savf.size);
|
|
Packit Service |
a8c26c |
if(savf.extent > 0)
|
|
Packit Service |
a8c26c |
(void)sfwrite(f,(Void_t*)savf.data,(size_t)savf.extent);
|
|
Packit Service |
a8c26c |
(void)sfseek(f,(Sfoff_t)(savf.next - savf.data),SEEK_SET);
|
|
Packit Service |
a8c26c |
if((savf.flags&SF_MALLOC) )
|
|
Packit Service |
a8c26c |
free((Void_t*)savf.data);
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
/* announce change of status */
|
|
Packit Service |
a8c26c |
f->disc = NIL(Sfdisc_t*);
|
|
Packit Service |
a8c26c |
if(_Sfnotify)
|
|
Packit Service |
a8c26c |
(*_Sfnotify)(f, SF_SETFD, (void*)((long)f->file));
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
/* erase all traces of newf */
|
|
Packit Service |
a8c26c |
newf.data = newf.endb = newf.endr = newf.endw = NIL(uchar*);
|
|
Packit Service |
a8c26c |
newf.file = -1;
|
|
Packit Service |
a8c26c |
_Sfnotify = 0;
|
|
Packit Service |
a8c26c |
sfclose(&newf);
|
|
Packit Service |
a8c26c |
_Sfnotify = notify;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
return 1;
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
#if __STD_C
|
|
Packit Service |
a8c26c |
Sfio_t* sftmp(size_t s)
|
|
Packit Service |
a8c26c |
#else
|
|
Packit Service |
a8c26c |
Sfio_t* sftmp(s)
|
|
Packit Service |
a8c26c |
size_t s;
|
|
Packit Service |
a8c26c |
#endif
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
Sfio_t *f;
|
|
Packit Service |
a8c26c |
int rv;
|
|
Packit Service |
a8c26c |
Sfnotify_f notify = _Sfnotify;
|
|
Packit Service |
a8c26c |
static Sfdisc_t Tmpdisc =
|
|
Packit Service |
a8c26c |
{ NIL(Sfread_f), NIL(Sfwrite_f), NIL(Sfseek_f), _tmpexcept,
|
|
Packit Service |
a8c26c |
#if _tmp_rmfail
|
|
Packit Service |
a8c26c |
&Rmdisc
|
|
Packit Service |
a8c26c |
#else
|
|
Packit Service |
a8c26c |
NIL(Sfdisc_t*)
|
|
Packit Service |
a8c26c |
#endif
|
|
Packit Service |
a8c26c |
};
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
/* start with a memory resident stream */
|
|
Packit Service |
a8c26c |
_Sfnotify = 0; /* local computation so no notification */
|
|
Packit Service |
a8c26c |
f = sfnew(NIL(Sfio_t*),NIL(char*),s,-1,SF_STRING|SF_READ|SF_WRITE);
|
|
Packit Service |
a8c26c |
_Sfnotify = notify;
|
|
Packit Service |
a8c26c |
if(!f)
|
|
Packit Service |
a8c26c |
return NIL(Sfio_t*);
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
if(s != (size_t)SF_UNBOUND) /* set up a discipline for out-of-bound, etc. */
|
|
Packit Service |
a8c26c |
f->disc = &Tmpdisc;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
if(s == 0) /* make the file now */
|
|
Packit Service |
a8c26c |
{ _Sfnotify = 0; /* local computation so no notification */
|
|
Packit Service |
a8c26c |
rv = _tmpexcept(f,SF_DPOP,NIL(Void_t*),f->disc);
|
|
Packit Service |
a8c26c |
_Sfnotify = notify;
|
|
Packit Service |
a8c26c |
if(rv < 0)
|
|
Packit Service |
a8c26c |
{ sfclose(f);
|
|
Packit Service |
a8c26c |
return NIL(Sfio_t*);
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
if(_Sfnotify)
|
|
Packit Service |
a8c26c |
(*_Sfnotify)(f, SF_NEW, (void*)((long)f->file));
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
return f;
|
|
Packit Service |
a8c26c |
}
|