1 /***********************************************************************
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 *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
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.
29 ** Written by Kiem-Phong Vo.
33 Sfio_t
* sfswap(reg Sfio_t
* f1
, reg Sfio_t
* f2
)
41 int f1pool
, f2pool
, f1mode
, f2mode
, f1flags
, f2flags
;
43 if(!f1
|| (f1
->mode
&SF_AVAIL
) || (SFFROZEN(f1
) && (f1
->mode
&SF_PUSH
)) )
45 if(f2
&& SFFROZEN(f2
) && (f2
->mode
&SF_PUSH
) )
52 f1
->mode
|= SF_PUSH
; /* make sure there is no recursion on f1 */
57 f2
->mode
|= SF_PUSH
; /* make sure there is no recursion on f2 */
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
))) )
70 SFCLEAR(f2
,NIL(Vtmutex_t
*));
72 f2
->mode
= SF_AVAIL
|SF_LOCK
;
78 else for(f1pool
= f1
->pool
->n_sf
-1; f1pool
>= 0; --f1pool
)
79 if(f1
->pool
->sf
[f1pool
] == f1
)
83 else for(f2pool
= f2
->pool
->n_sf
-1; f2pool
>= 0; --f2pool
)
84 if(f2
->pool
->sf
[f2pool
] == f2
)
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
));
95 f1
->pool
->sf
[f2pool
] = f1
;
97 f2
->pool
->sf
[f1pool
] = f2
;
100 f2
->flags
|= SF_STATIC
;
101 else f2
->flags
&= ~SF_STATIC
;
103 if(f1flags
&SF_STATIC
)
104 f1
->flags
|= SF_STATIC
;
105 else f1
->flags
&= ~SF_STATIC
;
107 if(f2mode
&SF_AVAIL
) /* swapping to a closed stream */
108 { if(!(f1
->flags
&SF_STATIC
) )