_fpopen.c - scc - simple c99 compiler
 (HTM) git clone git://git.simple-cc.org/scc
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
 (DIR) README
 (DIR) 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 }