scc

A fork of https://git.simple-cc.org/scc/ for Qute

git clone https://git.8pit.net/scc.git

 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
12FILE *
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}