xref: /onnv-gate/usr/src/lib/libast/common/sfio/sfnew.c (revision 12068:08a39a083754)
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