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