scc

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

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