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