merge newfstat variants
[trinity.git] / syscalls / fcntl.c
blobd0cff73335f7c2d1c4c9363e7633a110e49d09db
1 /*
2 * SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
4 * For a successful call, the return value depends on the operation:
6 * F_DUPFD The new descriptor.
7 * F_GETFD Value of file descriptor flags.
8 * F_GETFL Value of file status flags.
9 * F_GETLEASE Type of lease held on file descriptor.
10 * F_GETOWN Value of descriptor owner.
11 * F_GETSIG Value of signal sent when read or write becomes possible, or zero for traditional SIGIO behavior.
12 * F_GETPIPE_SZ The pipe capacity.
14 * All other commands
15 * Zero.
17 * On error, -1 is returned, and errno is set appropriately.
20 #include <fcntl.h>
21 #include <signal.h>
22 #include "random.h"
23 #include "sanitise.h"
24 #include "shm.h"
25 #include "compat.h"
27 #if F_GETLK64 != F_GETLK
28 #define HAVE_LK64
29 #endif
31 static void sanitise_fcntl(int childno)
33 switch (shm->a2[childno]) {
34 /* arg = fd */
35 case F_DUPFD:
36 case F_DUPFD_CLOEXEC:
37 case F_SETLEASE:
38 shm->a3[childno] = (unsigned long) get_random_fd();
39 break;
41 /* no arg */
42 case F_GETFD:
43 case F_GETFL:
44 case F_GETOWN:
45 case F_GETSIG:
46 case F_GETLEASE:
47 case F_GETPIPE_SZ:
48 case F_GETOWNER_UIDS:
49 break;
51 case F_SETFD: /* arg = flags */
52 shm->a3[childno] = (unsigned int) rand32();
53 break;
55 case F_SETFL:
56 shm->a3[childno] = 0L;
57 if (rand_bool())
58 shm->a3[childno] |= O_APPEND;
59 if (rand_bool())
60 shm->a3[childno] |= O_ASYNC;
61 if (rand_bool())
62 shm->a3[childno] |= O_DIRECT;
63 if (rand_bool())
64 shm->a3[childno] |= O_NOATIME;
65 if (rand_bool())
66 shm->a3[childno] |= O_NONBLOCK;
67 break;
69 /* arg = (struct flock *) */
70 case F_GETLK:
71 case F_SETLK:
72 case F_SETLKW:
73 break;
74 #ifdef HAVE_LK64
75 case F_GETLK64:
76 break;
77 case F_SETLK64:
78 break;
79 case F_SETLKW64:
80 break;
81 #endif
83 case F_SETOWN:
84 shm->a3[childno] = (unsigned long) get_pid();
85 break;
87 /* arg = struct f_owner_ex *) */
88 case F_GETOWN_EX:
89 case F_SETOWN_EX:
90 break;
92 case F_SETSIG:
93 shm->a3[childno] = (unsigned long) rand32();
94 if (shm->a3[childno] == SIGINT)
95 shm->a3[childno] = 0; /* restore default (SIGIO) */
96 break;
98 case F_NOTIFY:
99 shm->a3[childno] = 0L;
100 if (rand_bool())
101 shm->a3[childno] |= DN_ACCESS;
102 if (rand_bool())
103 shm->a3[childno] |= DN_MODIFY;
104 if (rand_bool())
105 shm->a3[childno] |= DN_CREATE;
106 if (rand_bool())
107 shm->a3[childno] |= DN_DELETE;
108 if (rand_bool())
109 shm->a3[childno] |= DN_RENAME;
110 if (rand_bool())
111 shm->a3[childno] |= DN_ATTRIB;
112 break;
114 case F_SETPIPE_SZ:
115 shm->a3[childno] = rand32();
116 break;
118 default:
119 break;
124 struct syscallentry syscall_fcntl = {
125 .name = "fcntl",
126 .num_args = 3,
127 .arg1name = "fd",
128 .arg1type = ARG_FD,
129 .arg2name = "cmd",
130 .arg2type = ARG_OP,
131 .arg2list = {
132 #ifndef HAVE_LK64
133 .num = 21,
134 #else
135 .num = 24,
136 #endif
137 .values = { F_DUPFD, F_DUPFD_CLOEXEC, F_GETFD, F_SETFD, F_GETFL, F_SETFL, F_GETLK, F_SETLK,
138 F_SETLKW, F_GETOWN, F_SETOWN, F_GETOWN_EX, F_SETOWN_EX, F_GETSIG, F_SETSIG, F_GETLEASE,
139 F_SETLEASE, F_NOTIFY, F_SETPIPE_SZ, F_GETPIPE_SZ, F_GETOWNER_UIDS,
140 #ifdef HAVE_LK64
141 F_GETLK64, F_SETLK64, F_SETLKW64,
142 #endif
145 .arg3name = "arg",
146 .rettype = RET_FD, //FIXME: Needs to mutate somehow depending on 'cmd'
147 .flags = NEED_ALARM,
148 .group = GROUP_VFS,
149 .sanitise = sanitise_fcntl,