xref: /titanic_44/usr/src/lib/libast/common/sfio/sfnew.c (revision 3e14f97f673e8a630f076077de35afdd43dc1587)
1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin *                                                                      *
3da2e3ebdSchin *               This software is part of the ast package               *
4*3e14f97fSRoger A. Faulkner *          Copyright (c) 1985-2010 AT&T Intellectual Property          *
5da2e3ebdSchin *                      and is licensed under the                       *
6da2e3ebdSchin *                  Common Public License, Version 1.0                  *
77c2fbfb3SApril Chin *                    by AT&T Intellectual Property                     *
8da2e3ebdSchin *                                                                      *
9da2e3ebdSchin *                A copy of the License is available at                 *
10da2e3ebdSchin *            http://www.opensource.org/licenses/cpl1.0.txt             *
11da2e3ebdSchin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12da2e3ebdSchin *                                                                      *
13da2e3ebdSchin *              Information and Software Systems Research               *
14da2e3ebdSchin *                            AT&T Research                             *
15da2e3ebdSchin *                           Florham Park NJ                            *
16da2e3ebdSchin *                                                                      *
17da2e3ebdSchin *                 Glenn Fowler <gsf@research.att.com>                  *
18da2e3ebdSchin *                  David Korn <dgk@research.att.com>                   *
19da2e3ebdSchin *                   Phong Vo <kpv@research.att.com>                    *
20da2e3ebdSchin *                                                                      *
21da2e3ebdSchin ***********************************************************************/
22da2e3ebdSchin #include	"sfhdr.h"
23da2e3ebdSchin 
24da2e3ebdSchin /*	Fundamental function to create a new stream.
25da2e3ebdSchin **	The argument flags defines the type of stream and the scheme
26da2e3ebdSchin **	of buffering.
27da2e3ebdSchin **
28da2e3ebdSchin **	Written by Kiem-Phong Vo.
29da2e3ebdSchin */
30da2e3ebdSchin 
31da2e3ebdSchin #if __STD_C
sfnew(Sfio_t * oldf,Void_t * buf,size_t size,int file,int flags)32da2e3ebdSchin Sfio_t* sfnew(Sfio_t* oldf, Void_t* buf, size_t size, int file, int flags)
33da2e3ebdSchin #else
34da2e3ebdSchin Sfio_t* sfnew(oldf,buf,size,file,flags)
35da2e3ebdSchin Sfio_t* oldf;	/* old stream to be reused */
36da2e3ebdSchin Void_t*	buf;	/* a buffer to read/write, if NULL, will be allocated */
37da2e3ebdSchin size_t	size;	/* buffer size if buf is given or desired buffer size */
38da2e3ebdSchin int	file;	/* file descriptor to read/write from */
39da2e3ebdSchin int	flags;	/* type of file stream */
40da2e3ebdSchin #endif
41da2e3ebdSchin {
42da2e3ebdSchin 	reg Sfio_t*	f;
43da2e3ebdSchin 	reg int		sflags;
44da2e3ebdSchin 
45da2e3ebdSchin 	SFONCE();	/* initialize mutexes */
46da2e3ebdSchin 
47da2e3ebdSchin 	if(!(flags&SF_RDWR))
48da2e3ebdSchin 		return NIL(Sfio_t*);
49da2e3ebdSchin 
50da2e3ebdSchin 	sflags = 0;
51da2e3ebdSchin 	if((f = oldf) )
52da2e3ebdSchin 	{	if(flags&SF_EOF)
53da2e3ebdSchin 		{	if(f != sfstdin && f != sfstdout && f != sfstderr)
54da2e3ebdSchin 				f->mutex = NIL(Vtmutex_t*);
55da2e3ebdSchin 			SFCLEAR(f, f->mutex);
56da2e3ebdSchin 			oldf = NIL(Sfio_t*);
57da2e3ebdSchin 		}
58da2e3ebdSchin 		else if(f->mode&SF_AVAIL)
59da2e3ebdSchin 		{	/* only allow SF_STATIC to be already closed */
60da2e3ebdSchin 			if(!(f->flags&SF_STATIC) )
61da2e3ebdSchin 				return NIL(Sfio_t*);
62da2e3ebdSchin 			sflags = f->flags;
63da2e3ebdSchin 			oldf = NIL(Sfio_t*);
64da2e3ebdSchin 		}
65da2e3ebdSchin 		else
66da2e3ebdSchin 		{	/* reopening an open stream, close it first */
67da2e3ebdSchin 			sflags = f->flags;
68da2e3ebdSchin 
69da2e3ebdSchin 			if(((f->mode&SF_RDWR) != f->mode && _sfmode(f,0,0) < 0) ||
70da2e3ebdSchin 			   SFCLOSE(f) < 0 )
71da2e3ebdSchin 				return NIL(Sfio_t*);
72da2e3ebdSchin 
73da2e3ebdSchin 			if(f->data && ((flags&SF_STRING) || size != (size_t)SF_UNBOUND) )
74da2e3ebdSchin 			{	if(sflags&SF_MALLOC)
75da2e3ebdSchin 					free((Void_t*)f->data);
76da2e3ebdSchin 				f->data = NIL(uchar*);
77da2e3ebdSchin 			}
78da2e3ebdSchin 			if(!f->data)
79da2e3ebdSchin 				sflags &= ~SF_MALLOC;
80da2e3ebdSchin 		}
81da2e3ebdSchin 	}
82da2e3ebdSchin 
83da2e3ebdSchin 	if(!f)
84da2e3ebdSchin 	{	/* reuse a standard stream structure if possible */
85da2e3ebdSchin 		if(!(flags&SF_STRING) && file >= 0 && file <= 2)
86da2e3ebdSchin 		{	f = file == 0 ? sfstdin : file == 1 ? sfstdout : sfstderr;
87da2e3ebdSchin 			if(f)
88da2e3ebdSchin 			{	if(f->mode&SF_AVAIL)
89da2e3ebdSchin 				{	sflags = f->flags;
90da2e3ebdSchin 					SFCLEAR(f, f->mutex);
91da2e3ebdSchin 				}
92da2e3ebdSchin 				else	f = NIL(Sfio_t*);
93da2e3ebdSchin 			}
94da2e3ebdSchin 		}
95da2e3ebdSchin 
96da2e3ebdSchin 		if(!f)
97da2e3ebdSchin 		{	if(!(f = (Sfio_t*)malloc(sizeof(Sfio_t))) )
98da2e3ebdSchin 				return NIL(Sfio_t*);
99da2e3ebdSchin 			SFCLEAR(f, NIL(Vtmutex_t*));
100da2e3ebdSchin 		}
101da2e3ebdSchin 	}
102da2e3ebdSchin 
103da2e3ebdSchin 	/* create a mutex */
104da2e3ebdSchin 	if(!f->mutex)
105da2e3ebdSchin 		f->mutex = vtmtxopen(NIL(Vtmutex_t*), VT_INIT);
106da2e3ebdSchin 
107da2e3ebdSchin 	/* stream type */
108da2e3ebdSchin 	f->mode = (flags&SF_READ) ? SF_READ : SF_WRITE;
109da2e3ebdSchin 	f->flags = (flags&SF_FLAGS) | (sflags&(SF_MALLOC|SF_STATIC));
110da2e3ebdSchin 	f->bits = (flags&SF_RDWR) == SF_RDWR ? SF_BOTH : 0;
111da2e3ebdSchin 	f->file = file;
112da2e3ebdSchin 	f->here = f->extent = 0;
113da2e3ebdSchin 	f->getr = f->tiny[0] = 0;
114da2e3ebdSchin 
115da2e3ebdSchin 	f->mode |= SF_INIT;
116da2e3ebdSchin 	if(size != (size_t)SF_UNBOUND)
117da2e3ebdSchin 	{	f->size = size;
118da2e3ebdSchin 		f->data = size <= 0 ? NIL(uchar*) : (uchar*)buf;
119da2e3ebdSchin 	}
120da2e3ebdSchin 	f->endb = f->endr = f->endw = f->next = f->data;
121da2e3ebdSchin 
122da2e3ebdSchin 	if(_Sfnotify)
1237c2fbfb3SApril Chin 		(*_Sfnotify)(f, SF_NEW, (void*)((long)f->file));
124da2e3ebdSchin 
125da2e3ebdSchin 	if(f->flags&SF_STRING)
126da2e3ebdSchin 		(void)_sfmode(f,f->mode&SF_RDWR,0);
127da2e3ebdSchin 
128da2e3ebdSchin 	return f;
129da2e3ebdSchin }
130