14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1985-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * David Korn <dgk@research.att.com> *
194887Schin * Phong Vo <kpv@research.att.com> *
204887Schin * *
214887Schin ***********************************************************************/
224887Schin #include "sfhdr.h"
234887Schin
244887Schin /* Swap two streams. If the second argument is NULL,
254887Schin ** a new stream will be created. Always return the second argument
264887Schin ** or the new stream. Note that this function will always work
274887Schin ** unless streams are locked by SF_PUSH.
284887Schin **
294887Schin ** Written by Kiem-Phong Vo.
304887Schin */
314887Schin
324887Schin #if __STD_C
sfswap(reg Sfio_t * f1,reg Sfio_t * f2)334887Schin Sfio_t* sfswap(reg Sfio_t* f1, reg Sfio_t* f2)
344887Schin #else
354887Schin Sfio_t* sfswap(f1,f2)
364887Schin reg Sfio_t* f1;
374887Schin reg Sfio_t* f2;
384887Schin #endif
394887Schin {
404887Schin Sfio_t tmp;
414887Schin int f1pool, f2pool, f1mode, f2mode, f1flags, f2flags;
424887Schin
434887Schin if(!f1 || (f1->mode&SF_AVAIL) || (SFFROZEN(f1) && (f1->mode&SF_PUSH)) )
444887Schin return NIL(Sfio_t*);
454887Schin if(f2 && SFFROZEN(f2) && (f2->mode&SF_PUSH) )
464887Schin return NIL(Sfio_t*);
474887Schin if(f1 == f2)
484887Schin return f2;
494887Schin
504887Schin f1mode = f1->mode;
514887Schin SFLOCK(f1,0);
524887Schin f1->mode |= SF_PUSH; /* make sure there is no recursion on f1 */
534887Schin
544887Schin if(f2)
554887Schin { f2mode = f2->mode;
564887Schin SFLOCK(f2,0);
574887Schin f2->mode |= SF_PUSH; /* make sure there is no recursion on f2 */
584887Schin }
594887Schin else
604887Schin { f2 = f1->file == 0 ? sfstdin :
614887Schin f1->file == 1 ? sfstdout :
624887Schin f1->file == 2 ? sfstderr : NIL(Sfio_t*);
634887Schin if((!f2 || !(f2->mode&SF_AVAIL)) )
644887Schin { if(!(f2 = (Sfio_t*)malloc(sizeof(Sfio_t))) )
654887Schin { f1->mode = f1mode;
664887Schin SFOPEN(f1,0);
674887Schin return NIL(Sfio_t*);
684887Schin }
694887Schin
704887Schin SFCLEAR(f2,NIL(Vtmutex_t*));
714887Schin }
724887Schin f2->mode = SF_AVAIL|SF_LOCK;
734887Schin f2mode = SF_AVAIL;
744887Schin }
754887Schin
764887Schin if(!f1->pool)
774887Schin f1pool = -1;
784887Schin else for(f1pool = f1->pool->n_sf-1; f1pool >= 0; --f1pool)
794887Schin if(f1->pool->sf[f1pool] == f1)
804887Schin break;
814887Schin if(!f2->pool)
824887Schin f2pool = -1;
834887Schin else for(f2pool = f2->pool->n_sf-1; f2pool >= 0; --f2pool)
844887Schin if(f2->pool->sf[f2pool] == f2)
854887Schin break;
864887Schin
874887Schin f1flags = f1->flags;
884887Schin f2flags = f2->flags;
894887Schin
904887Schin /* swap image and pool entries */
914887Schin memcpy((Void_t*)(&tmp),(Void_t*)f1,sizeof(Sfio_t));
924887Schin memcpy((Void_t*)f1,(Void_t*)f2,sizeof(Sfio_t));
934887Schin memcpy((Void_t*)f2,(Void_t*)(&tmp),sizeof(Sfio_t));
944887Schin if(f2pool >= 0)
954887Schin f1->pool->sf[f2pool] = f1;
964887Schin if(f1pool >= 0)
974887Schin f2->pool->sf[f1pool] = f2;
984887Schin
994887Schin if(f2flags&SF_STATIC)
1004887Schin f2->flags |= SF_STATIC;
1014887Schin else f2->flags &= ~SF_STATIC;
1024887Schin
1034887Schin if(f1flags&SF_STATIC)
1044887Schin f1->flags |= SF_STATIC;
1054887Schin else f1->flags &= ~SF_STATIC;
1064887Schin
1074887Schin if(f2mode&SF_AVAIL) /* swapping to a closed stream */
1084887Schin { if(!(f1->flags&SF_STATIC) )
1094887Schin free(f1);
1104887Schin }
1114887Schin else
1124887Schin { f1->mode = f2mode;
1134887Schin SFOPEN(f1,0);
1144887Schin }
1154887Schin
1164887Schin f2->mode = f1mode;
1174887Schin SFOPEN(f2,0);
1184887Schin return f2;
1194887Schin }
120