scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

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