Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtksh / ksh93 / src / lib / libast / sfio / sfopen.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: sfopen.c /main/3 1995/11/01 18:32:00 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 /*      Open a file/string for IO.
49 **      If f is not nil, it is taken as an existing stream that should be
50 **      closed and its structure reused for the new stream.
51 **
52 **      Written by Kiem-Phong Vo (06/27/90)
53 */
54
55 #if __STD_C
56 Sfio_t *sfopen(reg Sfio_t* f, const char* file, const char* mode)
57 #else
58 Sfio_t *sfopen(f,file,mode)
59 reg Sfio_t      *f;             /* old stream structure */
60 char            *file;          /* file/string to be opened */
61 reg char        *mode;          /* mode of the stream */
62 #endif
63 {
64         int     fd, oldfd, oflags, sflags;
65
66         if((sflags = _sftype(mode,&oflags)) == 0)
67                 return NIL(Sfio_t*);
68
69         if(sflags&SF_STRING)
70                 fd = -1;
71         else
72         {       /* open the file */
73                 if(!file)
74                         return NIL(Sfio_t*);
75
76 #ifndef NO_OFLAGS
77                 while((fd = open((char*)file,oflags,0666)) < 0 && errno == EINTR)
78                         errno = 0;
79 #else
80                 while((fd = open(file,oflags&03)) < 0 && errno == EINTR)
81                         errno = 0;
82                 if(fd >= 0)
83                 {       if(oflags&O_TRUNC)
84                         {       reg int tf;
85                                 while((tf = creat(file,0666)) < 0 && errno == EINTR)
86                                         errno = 0;
87                                 CLOSE(tf);
88                         }
89                 }
90                 else if(oflags&O_CREAT)
91                 {       while((fd = creat(file,0666)) < 0 && errno == EINTR)
92                                 errno = 0;
93                         if(!(oflags&O_WRONLY))
94                         {       /* the file now exists, reopen it for read/write */
95                                 CLOSE(fd);
96                                 while((fd = open(file,oflags&03)) < 0 && errno == EINTR)
97                                         errno = 0;
98                         }
99                 }
100 #endif
101                 if(fd < 0)
102                         return NIL(Sfio_t*);
103         }
104
105         oldfd = (f && !(f->flags&SF_STRING)) ? f->file : -1;
106
107         if(sflags&SF_STRING)
108                 f = sfnew(f,(char*)file,file ? (int)strlen((char*)file) : -1,fd,sflags);
109         else if((f = sfnew(f,NIL(char*),-1,fd,sflags|SF_OPEN)) && oldfd >= 0)
110                 (void)sfsetfd(f,oldfd);
111
112         return f;
113 }
114
115 #if __STD_C
116 _sftype(reg const char *mode, int *oflagsp)
117 #else
118 _sftype(mode, oflagsp)
119 reg char        *mode;
120 int             *oflagsp;
121 #endif
122 {
123         reg int sflags, oflags;
124
125         if(!mode)
126                 return 0;
127
128         /* construct the open flags */
129         sflags = oflags = 0;
130         while(1) switch(*mode++)
131         {
132         case 'w' :
133                 sflags |= SF_WRITE;
134                 oflags |= O_WRONLY | O_CREAT;
135                 if(!(sflags&SF_READ))
136                         oflags |= O_TRUNC;
137                 continue;
138         case 'a' :
139                 sflags |= SF_WRITE | SF_APPEND;
140                 oflags |= O_WRONLY | O_APPEND | O_CREAT;
141                 continue;
142         case 'r' :
143                 sflags |= SF_READ;
144                 oflags |= O_RDONLY;
145                 continue;
146         case 's' :
147                 sflags |= SF_STRING;
148                 continue;
149         case 'b' :
150                 oflags &= ~O_TEXT;
151                 oflags |= O_BINARY;
152                 continue;
153         case 't' :
154                 oflags &= ~O_BINARY;
155                 oflags |= O_TEXT;
156                 continue;
157         case '+' :
158                 if(sflags)
159                         sflags |= SF_READ|SF_WRITE;
160                 continue;
161         default :
162                 if((sflags&SF_RDWR) == SF_RDWR)
163                         oflags = (oflags&~(O_RDONLY|O_WRONLY))|O_RDWR;
164                 if(!(oflags&O_BINARY) && (sflags&SF_READ))
165                         oflags |= O_TEXT;
166                 if(oflagsp)
167                         *oflagsp = oflags;
168                 if((sflags&(SF_STRING|SF_RDWR)) == SF_STRING)
169                         sflags |= SF_READ;
170                 return sflags;
171         }
172 }