1#include <errno.h>2#include <stdio.h>3#include <stdlib.h>4#include <string.h>5#include <wchar.h>67#include <sys.h>89#include "../syscall.h"10#include "../libc.h"1112FILE *13_fpopen(const char *restrict fname,14 const char *restrict mode,15 FILE * restrict fp)16{17 int i, flags, fd, rw, bin, rights;1819 flags = rw = bin = 0;20 rights = 0666;2122 if (mode[0] == '\0')23 goto einval;2425 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 }4546 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 }6364 if ((fd = _open(fname, flags, rights)) < 0)65 return NULL;6667 memset(&fp->mbs, 0, sizeof(mbstate_t));68 fp->buf = NULL;69 fp->fd = fd;7071 if (!bin)72 fp->flags |= _IOTXT;7374 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 }8586 fp->lp = fp->rp = fp->wp = NULL;8788 return fp;89}