13e12c5d1SDavid du Colombier #include "lib.h"
23e12c5d1SDavid du Colombier #include <unistd.h>
33e12c5d1SDavid du Colombier #include <errno.h>
43e12c5d1SDavid du Colombier #include <stdarg.h>
53e12c5d1SDavid du Colombier #include "sys9.h"
63e12c5d1SDavid du Colombier
73e12c5d1SDavid du Colombier /*
83e12c5d1SDavid du Colombier * BUG: advisory locking not implemented
93e12c5d1SDavid du Colombier */
103e12c5d1SDavid du Colombier
113e12c5d1SDavid du Colombier #define OFL (O_ACCMODE|O_NONBLOCK|O_APPEND)
123e12c5d1SDavid du Colombier
133e12c5d1SDavid du Colombier int
fcntl(int fd,int cmd,...)143e12c5d1SDavid du Colombier fcntl(int fd, int cmd, ...)
153e12c5d1SDavid du Colombier {
163e12c5d1SDavid du Colombier int arg, i, ans, err;
17*219b2ee8SDavid du Colombier Fdinfo *fi, *fans;
183e12c5d1SDavid du Colombier va_list va;
193e12c5d1SDavid du Colombier unsigned long oflags;
203e12c5d1SDavid du Colombier
213e12c5d1SDavid du Colombier err = 0;
223e12c5d1SDavid du Colombier ans = 0;
233e12c5d1SDavid du Colombier va_start(va, cmd);
243e12c5d1SDavid du Colombier arg = va_arg(va, int);
253e12c5d1SDavid du Colombier va_end(va);
263e12c5d1SDavid du Colombier fi = &_fdinfo[fd];
273e12c5d1SDavid du Colombier if(fd<0 || fd>=OPEN_MAX || !(fi->flags&FD_ISOPEN))
283e12c5d1SDavid du Colombier err = EBADF;
293e12c5d1SDavid du Colombier else switch(cmd){
303e12c5d1SDavid du Colombier case F_DUPFD:
31*219b2ee8SDavid du Colombier if(fi->flags&(FD_BUFFERED|FD_BUFFEREDX)){
32*219b2ee8SDavid du Colombier err = EGREG; /* dup of buffered fd not implemented */
33*219b2ee8SDavid du Colombier break;
34*219b2ee8SDavid du Colombier }
353e12c5d1SDavid du Colombier oflags = fi->oflags;
363e12c5d1SDavid du Colombier for(i = (arg>0)? arg : 0; i<OPEN_MAX; i++)
373e12c5d1SDavid du Colombier if(!(_fdinfo[i].flags&FD_ISOPEN))
383e12c5d1SDavid du Colombier break;
393e12c5d1SDavid du Colombier if(i == OPEN_MAX)
403e12c5d1SDavid du Colombier err = EMFILE;
413e12c5d1SDavid du Colombier else {
423e12c5d1SDavid du Colombier ans = _DUP(fd, i);
433e12c5d1SDavid du Colombier if(ans != i){
443e12c5d1SDavid du Colombier if(ans < 0){
453e12c5d1SDavid du Colombier _syserrno();
463e12c5d1SDavid du Colombier err = errno;
473e12c5d1SDavid du Colombier }else
483e12c5d1SDavid du Colombier err = EBADF;
493e12c5d1SDavid du Colombier }else{
50*219b2ee8SDavid du Colombier fans = &_fdinfo[ans];
51*219b2ee8SDavid du Colombier fans->flags = fi->flags&~FD_CLOEXEC;
52*219b2ee8SDavid du Colombier fans->oflags = oflags;
53*219b2ee8SDavid du Colombier fans->uid = fi->uid;
54*219b2ee8SDavid du Colombier fans->gid = fi->gid;
553e12c5d1SDavid du Colombier }
563e12c5d1SDavid du Colombier }
573e12c5d1SDavid du Colombier break;
583e12c5d1SDavid du Colombier case F_GETFD:
593e12c5d1SDavid du Colombier ans = fi->flags&FD_CLOEXEC;
603e12c5d1SDavid du Colombier break;
613e12c5d1SDavid du Colombier case F_SETFD:
623e12c5d1SDavid du Colombier fi->flags = (fi->flags&~FD_CLOEXEC)|(arg&FD_CLOEXEC);
633e12c5d1SDavid du Colombier break;
643e12c5d1SDavid du Colombier case F_GETFL:
653e12c5d1SDavid du Colombier ans = fi->oflags&OFL;
663e12c5d1SDavid du Colombier break;
673e12c5d1SDavid du Colombier case F_SETFL:
683e12c5d1SDavid du Colombier fi->oflags = (fi->oflags&~OFL)|(arg&OFL);
693e12c5d1SDavid du Colombier break;
703e12c5d1SDavid du Colombier case F_GETLK:
713e12c5d1SDavid du Colombier case F_SETLK:
723e12c5d1SDavid du Colombier case F_SETLKW:
733e12c5d1SDavid du Colombier err = EINVAL;
743e12c5d1SDavid du Colombier break;
753e12c5d1SDavid du Colombier }
763e12c5d1SDavid du Colombier if(err){
773e12c5d1SDavid du Colombier errno = err;
783e12c5d1SDavid du Colombier ans = -1;
793e12c5d1SDavid du Colombier }
803e12c5d1SDavid du Colombier return ans;
813e12c5d1SDavid du Colombier }
82