Mon Apr 29 02:48:26 1996 Ulrich Drepper <drepper@cygnus.com>
[kopensolaris-gnu/glibc.git] / stdio / fopen.c
1 /* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB.  If
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA.  */
18
19 #include <ansidecl.h>
20 #include <ctype.h>
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26
27 #define badmode()       return ((errno = EINVAL), 0)
28
29 /* Dissect the given mode string into an __io_mode.  */
30 int
31 DEFUN(__getmode, (mode, mptr), CONST char *mode AND __io_mode *mptr)
32 {
33   register unsigned char i;
34
35   if (mode == NULL)
36     badmode ();
37
38   memset ((PTR) mptr, 0, sizeof (*mptr));
39
40   switch (*mode)
41     {
42     case 'a':
43       mptr->__write = mptr->__create = mptr->__append = 1;
44       break;
45     case 'w':
46       mptr->__write = mptr->__create = mptr->__truncate = 1;
47       break;
48     case 'r':
49       mptr->__read = 1;
50       break;
51     default:
52       badmode ();
53     }
54
55   for (i = 1; i < 3; ++i)
56     {
57       ++mode;
58       if (*mode == '\0')
59         break;
60       switch (*mode)
61         {
62         case '+':
63           mptr->__read = mptr->__write = 1;
64           break;
65         case 'b':
66           mptr->__binary = 1;
67           break;
68         }
69     }
70
71   if (!mptr->__read && !mptr->__write)
72     badmode ();
73
74   mptr->__exclusive = *mode == 'x';
75
76   return 1;
77 }
78 \f
79 /* Open a new stream on the given file.  */
80 FILE *
81 DEFUN(fopen, (filename, mode), CONST char *filename AND CONST char *mode)
82 {
83   FILE *stream;
84   __io_mode m;
85
86   if (filename == NULL)
87     {
88       errno = EINVAL;
89       return NULL;
90     }
91
92   if (!__getmode (mode, &m))
93     return NULL;
94
95   stream = __newstream ();
96   if (stream == NULL)
97     return NULL;
98
99   if (__stdio_open (filename, m, &stream->__cookie))
100     {
101       int save = errno;
102       (void) fclose (stream);
103       errno = save;
104       return NULL;
105     }
106
107   stream->__mode = m;
108
109   return stream;
110 }