1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2007 AT&T Knowledge Ventures * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Knowledge Ventures * 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" 23 24 /* Fundamental function to create a new stream. 25 ** The argument flags defines the type of stream and the scheme 26 ** of buffering. 27 ** 28 ** Written by Kiem-Phong Vo. 29 */ 30 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 41 { 42 reg Sfio_t* f; 43 reg int sflags; 44 45 SFONCE(); /* initialize mutexes */ 46 47 if(!(flags&SF_RDWR)) 48 return NIL(Sfio_t*); 49 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*); 57 } 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*); 64 } 65 else 66 { /* reopening an open stream, close it first */ 67 sflags = f->flags; 68 69 if(((f->mode&SF_RDWR) != f->mode && _sfmode(f,0,0) < 0) || 70 SFCLOSE(f) < 0 ) 71 return NIL(Sfio_t*); 72 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*); 77 } 78 if(!f->data) 79 sflags &= ~SF_MALLOC; 80 } 81 } 82 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); 91 } 92 else f = NIL(Sfio_t*); 93 } 94 } 95 96 if(!f) 97 { if(!(f = (Sfio_t*)malloc(sizeof(Sfio_t))) ) 98 return NIL(Sfio_t*); 99 SFCLEAR(f, NIL(Vtmutex_t*)); 100 } 101 } 102 103 /* create a mutex */ 104 if(!f->mutex) 105 f->mutex = vtmtxopen(NIL(Vtmutex_t*), VT_INIT); 106 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; 114 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; 119 } 120 f->endb = f->endr = f->endw = f->next = f->data; 121 122 if(_Sfnotify) 123 (*_Sfnotify)(f,SF_NEW,f->file); 124 125 if(f->flags&SF_STRING) 126 (void)_sfmode(f,f->mode&SF_RDWR,0); 127 128 return f; 129 } 130