1/*********************************************************************** 2* * 3* This software is part of the ast package * 4* Copyright (c) 1985-2011 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 33Sfio_t* sfswap(reg Sfio_t* f1, reg Sfio_t* f2) 34#else 35Sfio_t* sfswap(f1,f2) 36reg Sfio_t* f1; 37reg 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