scc

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

_fpopen.c (1120B)


      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;
     16 
     17 	flags = rw = bin = 0;
     18 
     19 	if (mode[0] == '\0')
     20 		goto einval;
     21 
     22 	for (i = 1; mode[i]; ++i) {
     23 		switch (mode[i]) {
     24 		case '+':
     25 			if (rw)
     26 				goto einval;
     27 			rw = 1;
     28 			break;
     29 		case 'b':
     30 			if (bin)
     31 				goto einval;
     32 			bin = 1;
     33 			break;
     34 		default:
     35 			goto einval;
     36 		}
     37 	}
     38 
     39 	switch (mode[0]) {
     40 	case 'a':
     41 		flags |= O_APPEND | O_CREAT;
     42 		goto wrflags;
     43 	case 'w':
     44 		flags |= O_TRUNC | O_CREAT;
     45 	wrflags:
     46 		flags |= (rw) ? O_RDWR : O_WRONLY;
     47 		break;
     48 	case 'r':
     49 		flags = (rw) ? O_RDWR : O_RDONLY;
     50 		break;
     51 	default:
     52 	einval:
     53 		errno = EINVAL;
     54 		return NULL;
     55 	}
     56 
     57 	if ((fd = _open(fname, flags, 0666)) < 0)
     58 		return NULL;
     59 
     60 	fp->buf = NULL;
     61 	fp->fd = fd;
     62 
     63 	if (!bin)
     64 		fp->flags |= _IOTXT;
     65 
     66 	if (flags & O_RDWR)
     67 		fp->flags |= _IORW;
     68 	else if (flags & O_RDONLY)
     69 		fp->flags |= _IOREAD;
     70 	else
     71 		fp->flags |= _IOWRITE;
     72 
     73 	fp->lp = fp->rp = fp->wp = NULL;
     74 
     75 	return fp;
     76 }