14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1985-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * David Korn <dgk@research.att.com> *
194887Schin * Phong Vo <kpv@research.att.com> *
204887Schin * *
214887Schin ***********************************************************************/
224887Schin #include "sfhdr.h"
234887Schin
244887Schin /* Fundamental function to create a new stream.
254887Schin ** The argument flags defines the type of stream and the scheme
264887Schin ** of buffering.
274887Schin **
284887Schin ** Written by Kiem-Phong Vo.
294887Schin */
304887Schin
314887Schin #if __STD_C
sfnew(Sfio_t * oldf,Void_t * buf,size_t size,int file,int flags)324887Schin Sfio_t* sfnew(Sfio_t* oldf, Void_t* buf, size_t size, int file, int flags)
334887Schin #else
344887Schin Sfio_t* sfnew(oldf,buf,size,file,flags)
354887Schin Sfio_t* oldf; /* old stream to be reused */
364887Schin Void_t* buf; /* a buffer to read/write, if NULL, will be allocated */
374887Schin size_t size; /* buffer size if buf is given or desired buffer size */
384887Schin int file; /* file descriptor to read/write from */
394887Schin int flags; /* type of file stream */
404887Schin #endif
414887Schin {
424887Schin reg Sfio_t* f;
434887Schin reg int sflags;
444887Schin
454887Schin SFONCE(); /* initialize mutexes */
464887Schin
474887Schin if(!(flags&SF_RDWR))
484887Schin return NIL(Sfio_t*);
494887Schin
504887Schin sflags = 0;
514887Schin if((f = oldf) )
524887Schin { if(flags&SF_EOF)
534887Schin { if(f != sfstdin && f != sfstdout && f != sfstderr)
544887Schin f->mutex = NIL(Vtmutex_t*);
554887Schin SFCLEAR(f, f->mutex);
564887Schin oldf = NIL(Sfio_t*);
574887Schin }
584887Schin else if(f->mode&SF_AVAIL)
594887Schin { /* only allow SF_STATIC to be already closed */
604887Schin if(!(f->flags&SF_STATIC) )
614887Schin return NIL(Sfio_t*);
624887Schin sflags = f->flags;
634887Schin oldf = NIL(Sfio_t*);
644887Schin }
654887Schin else
664887Schin { /* reopening an open stream, close it first */
674887Schin sflags = f->flags;
684887Schin
694887Schin if(((f->mode&SF_RDWR) != f->mode && _sfmode(f,0,0) < 0) ||
704887Schin SFCLOSE(f) < 0 )
714887Schin return NIL(Sfio_t*);
724887Schin
734887Schin if(f->data && ((flags&SF_STRING) || size != (size_t)SF_UNBOUND) )
744887Schin { if(sflags&SF_MALLOC)
754887Schin free((Void_t*)f->data);
764887Schin f->data = NIL(uchar*);
774887Schin }
784887Schin if(!f->data)
794887Schin sflags &= ~SF_MALLOC;
804887Schin }
814887Schin }
824887Schin
834887Schin if(!f)
844887Schin { /* reuse a standard stream structure if possible */
854887Schin if(!(flags&SF_STRING) && file >= 0 && file <= 2)
864887Schin { f = file == 0 ? sfstdin : file == 1 ? sfstdout : sfstderr;
874887Schin if(f)
884887Schin { if(f->mode&SF_AVAIL)
894887Schin { sflags = f->flags;
904887Schin SFCLEAR(f, f->mutex);
914887Schin }
924887Schin else f = NIL(Sfio_t*);
934887Schin }
944887Schin }
954887Schin
964887Schin if(!f)
974887Schin { if(!(f = (Sfio_t*)malloc(sizeof(Sfio_t))) )
984887Schin return NIL(Sfio_t*);
994887Schin SFCLEAR(f, NIL(Vtmutex_t*));
1004887Schin }
1014887Schin }
1024887Schin
1034887Schin /* create a mutex */
1044887Schin if(!f->mutex)
1054887Schin f->mutex = vtmtxopen(NIL(Vtmutex_t*), VT_INIT);
1064887Schin
1074887Schin /* stream type */
1084887Schin f->mode = (flags&SF_READ) ? SF_READ : SF_WRITE;
1094887Schin f->flags = (flags&SF_FLAGS) | (sflags&(SF_MALLOC|SF_STATIC));
1104887Schin f->bits = (flags&SF_RDWR) == SF_RDWR ? SF_BOTH : 0;
1114887Schin f->file = file;
1124887Schin f->here = f->extent = 0;
1134887Schin f->getr = f->tiny[0] = 0;
1144887Schin
1154887Schin f->mode |= SF_INIT;
1164887Schin if(size != (size_t)SF_UNBOUND)
1174887Schin { f->size = size;
1184887Schin f->data = size <= 0 ? NIL(uchar*) : (uchar*)buf;
1194887Schin }
1204887Schin f->endb = f->endr = f->endw = f->next = f->data;
1214887Schin
1224887Schin if(_Sfnotify)
1238462SApril.Chin@Sun.COM (*_Sfnotify)(f, SF_NEW, (void*)((long)f->file));
1244887Schin
1254887Schin if(f->flags&SF_STRING)
1264887Schin (void)_sfmode(f,f->mode&SF_RDWR,0);
1274887Schin
1284887Schin return f;
1294887Schin }
130