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