1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2009 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" 23 24 /* Swap two streams. If the second argument is NULL, 25 ** a new stream will be created. Always return the second argument 26 ** or the new stream. Note that this function will always work 27 ** unless streams are locked by SF_PUSH. 28 ** 29 ** Written by Kiem-Phong Vo. 30 */ 31 32 #if __STD_C 33 Sfio_t* sfswap(reg Sfio_t* f1, reg Sfio_t* f2) 34 #else 35 Sfio_t* sfswap(f1,f2) 36 reg Sfio_t* f1; 37 reg Sfio_t* f2; 38 #endif 39 { 40 Sfio_t tmp; 41 int f1pool, f2pool, f1mode, f2mode, f1flags, f2flags; 42 43 if(!f1 || (f1->mode&SF_AVAIL) || (SFFROZEN(f1) && (f1->mode&SF_PUSH)) ) 44 return NIL(Sfio_t*); 45 if(f2 && SFFROZEN(f2) && (f2->mode&SF_PUSH) ) 46 return NIL(Sfio_t*); 47 if(f1 == f2) 48 return f2; 49 50 f1mode = f1->mode; 51 SFLOCK(f1,0); 52 f1->mode |= SF_PUSH; /* make sure there is no recursion on f1 */ 53 54 if(f2) 55 { f2mode = f2->mode; 56 SFLOCK(f2,0); 57 f2->mode |= SF_PUSH; /* make sure there is no recursion on f2 */ 58 } 59 else 60 { f2 = f1->file == 0 ? sfstdin : 61 f1->file == 1 ? sfstdout : 62 f1->file == 2 ? sfstderr : NIL(Sfio_t*); 63 if((!f2 || !(f2->mode&SF_AVAIL)) ) 64 { if(!(f2 = (Sfio_t*)malloc(sizeof(Sfio_t))) ) 65 { f1->mode = f1mode; 66 SFOPEN(f1,0); 67 return NIL(Sfio_t*); 68 } 69 70 SFCLEAR(f2,NIL(Vtmutex_t*)); 71 } 72 f2->mode = SF_AVAIL|SF_LOCK; 73 f2mode = SF_AVAIL; 74 } 75 76 if(!f1->pool) 77 f1pool = -1; 78 else for(f1pool = f1->pool->n_sf-1; f1pool >= 0; --f1pool) 79 if(f1->pool->sf[f1pool] == f1) 80 break; 81 if(!f2->pool) 82 f2pool = -1; 83 else for(f2pool = f2->pool->n_sf-1; f2pool >= 0; --f2pool) 84 if(f2->pool->sf[f2pool] == f2) 85 break; 86 87 f1flags = f1->flags; 88 f2flags = f2->flags; 89 90 /* swap image and pool entries */ 91 memcpy((Void_t*)(&tmp),(Void_t*)f1,sizeof(Sfio_t)); 92 memcpy((Void_t*)f1,(Void_t*)f2,sizeof(Sfio_t)); 93 memcpy((Void_t*)f2,(Void_t*)(&tmp),sizeof(Sfio_t)); 94 if(f2pool >= 0) 95 f1->pool->sf[f2pool] = f1; 96 if(f1pool >= 0) 97 f2->pool->sf[f1pool] = f2; 98 99 if(f2flags&SF_STATIC) 100 f2->flags |= SF_STATIC; 101 else f2->flags &= ~SF_STATIC; 102 103 if(f1flags&SF_STATIC) 104 f1->flags |= SF_STATIC; 105 else f1->flags &= ~SF_STATIC; 106 107 if(f2mode&SF_AVAIL) /* swapping to a closed stream */ 108 { if(!(f1->flags&SF_STATIC) ) 109 free(f1); 110 } 111 else 112 { f1->mode = f2mode; 113 SFOPEN(f1,0); 114 } 115 116 f2->mode = f1mode; 117 SFOPEN(f2,0); 118 return f2; 119 } 120