1 #include "lib.h" 2 #include <unistd.h> 3 #include <errno.h> 4 #include <stdarg.h> 5 #include "sys9.h" 6 7 /* 8 * BUG: advisory locking not implemented 9 */ 10 11 #define OFL (O_ACCMODE|O_NONBLOCK|O_APPEND) 12 13 int 14 fcntl(int fd, int cmd, ...) 15 { 16 int arg, i, ans, err; 17 Fdinfo *fi, *fans; 18 va_list va; 19 unsigned long oflags; 20 21 err = 0; 22 ans = 0; 23 va_start(va, cmd); 24 arg = va_arg(va, int); 25 va_end(va); 26 fi = &_fdinfo[fd]; 27 if(fd<0 || fd>=OPEN_MAX || !(fi->flags&FD_ISOPEN)) 28 err = EBADF; 29 else switch(cmd){ 30 case F_DUPFD: 31 if(fi->flags&(FD_BUFFERED|FD_BUFFEREDX)){ 32 err = EGREG; /* dup of buffered fd not implemented */ 33 break; 34 } 35 oflags = fi->oflags; 36 for(i = (arg>0)? arg : 0; i<OPEN_MAX; i++) 37 if(!(_fdinfo[i].flags&FD_ISOPEN)) 38 break; 39 if(i == OPEN_MAX) 40 err = EMFILE; 41 else { 42 ans = _DUP(fd, i); 43 if(ans != i){ 44 if(ans < 0){ 45 _syserrno(); 46 err = errno; 47 }else 48 err = EBADF; 49 }else{ 50 fans = &_fdinfo[ans]; 51 fans->flags = fi->flags&~FD_CLOEXEC; 52 fans->oflags = oflags; 53 fans->uid = fi->uid; 54 fans->gid = fi->gid; 55 } 56 } 57 break; 58 case F_GETFD: 59 ans = fi->flags&FD_CLOEXEC; 60 break; 61 case F_SETFD: 62 fi->flags = (fi->flags&~FD_CLOEXEC)|(arg&FD_CLOEXEC); 63 break; 64 case F_GETFL: 65 ans = fi->oflags&OFL; 66 break; 67 case F_SETFL: 68 fi->oflags = (fi->oflags&~OFL)|(arg&OFL); 69 break; 70 case F_GETLK: 71 case F_SETLK: 72 case F_SETLKW: 73 err = EINVAL; 74 break; 75 } 76 if(err){ 77 errno = err; 78 ans = -1; 79 } 80 return ans; 81 } 82