Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}