_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 }