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