]> git.lizzy.rs Git - plan9front.git/blob - sys/src/ape/lib/ap/plan9/fcntl.c
Import sources from 2011-03-30 iso image
[plan9front.git] / sys / src / ape / lib / ap / plan9 / fcntl.c
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 }