scc

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

_fpopen.c (1350B)


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