Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtksh / ksh93 / src / lib / libast / sfio / sfswap.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: sfswap.c /main/3 1995/11/01 18:37:12 rswiston $ */
24 /***************************************************************
25 *                                                              *
26 *                      AT&T - PROPRIETARY                      *
27 *                                                              *
28 *         THIS IS PROPRIETARY SOURCE CODE LICENSED BY          *
29 *                          AT&T CORP.                          *
30 *                                                              *
31 *                Copyright (c) 1995 AT&T Corp.                 *
32 *                     All Rights Reserved                      *
33 *                                                              *
34 *           This software is licensed by AT&T Corp.            *
35 *       under the terms and conditions of the license in       *
36 *       http://www.research.att.com/orgs/ssr/book/reuse        *
37 *                                                              *
38 *               This software was created by the               *
39 *           Software Engineering Research Department           *
40 *                    AT&T Bell Laboratories                    *
41 *                                                              *
42 *               For further information contact                *
43 *                     gsf@research.att.com                     *
44 *                                                              *
45 ***************************************************************/
46 #include        "sfhdr.h"
47
48 /*      Swap two streams. If the second argument is NULL,
49 **      a new stream will be created. Always return the second argument
50 **      or the new stream. Note that this function will always work
51 **      unless streams are locked by SF_PUSH.
52 **
53 **      Written by Kiem-Phong Vo (02/07/94)
54 */
55
56 #if __STD_C
57 Sfio_t* sfswap(reg Sfio_t* f1, reg Sfio_t* f2)
58 #else
59 Sfio_t* sfswap(f1,f2)
60 reg Sfio_t*     f1;
61 reg Sfio_t*     f2;
62 #endif
63 {
64         Sfio_t  tmp;
65         int     f1pool, f2pool, f1mode, f2mode, f1flags, f2flags;
66
67         if(!f1 || (f1->mode&SF_AVAIL) || (SFFROZEN(f1) && (f1->mode&SF_PUSH)) )
68                 return NIL(Sfio_t*);
69         if(f2 && SFFROZEN(f2) && (f2->mode&SF_PUSH) )
70                 return NIL(Sfio_t*);
71         if(f1 == f2)
72                 return f2;
73
74         f1mode = f1->mode;
75         SFLOCK(f1,0);
76         f1->mode |= SF_PUSH;            /* make sure there is no recursion on f1 */
77         
78         if(f2)
79         {       f2mode = f2->mode;
80                 SFLOCK(f2,0);
81                 f2->mode |= SF_PUSH;    /* make sure there is no recursion on f2 */
82         }
83         else
84         {       f2 = f1->file == 0 ? sfstdin :
85                      f1->file == 1 ? sfstdout :
86                      f1->file == 2 ? sfstderr : NIL(Sfio_t*);
87                 if((!f2 || !(f2->mode&SF_AVAIL)) )
88                 {       if(!SFALLOC(f2) )
89                         {       f1->mode = f1mode;
90                                 SFOPEN(f1,0);
91                                 return NIL(Sfio_t*);
92                         }
93                         else    SFCLEAR(f2);
94                 }
95                 f2->mode = SF_AVAIL|SF_LOCK;
96                 f2mode = SF_AVAIL;
97         }
98
99         if(!f1->pool)
100                 f1pool = -1;
101         else for(f1pool = f1->pool->n_sf-1; f1pool >= 0; --f1pool)
102                 if(f1->pool->sf[f1pool] == f1)
103                         break;
104         if(!f2->pool)
105                 f2pool = -1;
106         else for(f2pool = f2->pool->n_sf-1; f2pool >= 0; --f2pool)
107                 if(f2->pool->sf[f2pool] == f2)
108                         break;
109
110         f1flags = f1->flags;
111         f2flags = f2->flags;
112
113         /* swap image and pool entries */
114         memcpy((Void_t*)(&tmp),(Void_t*)f1,sizeof(Sfio_t));
115         memcpy((Void_t*)f1,(Void_t*)f2,sizeof(Sfio_t));
116         memcpy((Void_t*)f2,(Void_t*)(&tmp),sizeof(Sfio_t));
117         if(f2pool >= 0)
118                 f1->pool->sf[f2pool] = f1;
119         if(f1pool >= 0)
120                 f2->pool->sf[f1pool] = f2;
121
122         _sfswap(f1,f2,0);
123
124         if(f2flags&SF_STATIC)
125                 f2->flags |= SF_STATIC;
126         else    f2->flags &= ~SF_STATIC;
127
128         if(f1flags&SF_STATIC)
129                 f1->flags |= SF_STATIC;
130         else    f1->flags &= ~SF_STATIC;
131
132         if(f2mode&SF_AVAIL)     /* swapping to a closed stream */
133         {       if(!(f1->flags&SF_STATIC) )
134                         SFFREE(f1);
135         }
136         else
137         {       f1->mode = f2mode;
138                 SFOPEN(f1,0);
139         }
140
141         f2->mode = f1mode;
142         SFOPEN(f2,0);
143         return f2;
144 }