_fpopen.c - scc - simple c99 compiler
HTML git clone git://git.simple-cc.org/scc
DIR Log
DIR Files
DIR Refs
DIR Submodules
DIR README
DIR LICENSE
---
_fpopen.c (1350B)
---
1 #include <errno.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <wchar.h>
6
7 #include <sys.h>
8
9 #include "../syscall.h"
10 #include "../libc.h"
11
12 FILE *
13 _fpopen(const char *restrict fname,
14 const char *restrict mode,
15 FILE * restrict fp)
16 {
17 int i, flags, fd, rw, bin, rights;
18
19 flags = rw = bin = 0;
20 rights = 0666;
21
22 if (mode[0] == '\0')
23 goto einval;
24
25 for (i = 1; mode[i]; ++i) {
26 switch (mode[i]) {
27 case '+':
28 if (rw)
29 goto einval;
30 rw = 1;
31 break;
32 case 'b':
33 if (bin)
34 goto einval;
35 bin = 1;
36 break;
37 case 't':
38 flags |= O_EXCL | O_CLOEXEC;
39 rights = 0600;
40 break;
41 default:
42 goto einval;
43 }
44 }
45
46 switch (mode[0]) {
47 case 'a':
48 flags |= O_APPEND | O_CREAT;
49 goto wrflags;
50 case 'w':
51 flags |= O_TRUNC | O_CREAT;
52 wrflags:
53 flags |= (rw) ? O_RDWR : O_WRONLY;
54 break;
55 case 'r':
56 flags |= (rw) ? O_RDWR : O_RDONLY;
57 break;
58 default:
59 einval:
60 errno = EINVAL;
61 return NULL;
62 }
63
64 if ((fd = _open(fname, flags, rights)) < 0)
65 return NULL;
66
67 memset(&fp->mbs, 0, sizeof(mbstate_t));
68 fp->buf = NULL;
69 fp->fd = fd;
70
71 if (!bin)
72 fp->flags |= _IOTXT;
73
74 switch (flags & O_ACCMODE) {
75 case O_RDWR:
76 fp->flags |= _IORW;
77 break;
78 case O_RDONLY:
79 fp->flags |= _IOREAD;
80 break;
81 case O_WRONLY:
82 fp->flags |= _IOWRITE;
83 break;
84 }
85
86 fp->lp = fp->rp = fp->wp = NULL;
87
88 return fp;
89 }