File: fcntl.c

package info (click to toggle)
trinity 1.3-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 3,252 kB
  • ctags: 2,738
  • sloc: ansic: 24,011; sh: 322; makefile: 141
file content (150 lines) | stat: -rw-r--r-- 3,266 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*
 * SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
 *
 * For a successful call, the return value depends on the operation:
 *
 *     F_DUPFD The new descriptor.
 *     F_GETFD Value of file descriptor flags.
 *     F_GETFL Value of file status flags.
 *     F_GETLEASE Type of lease held on file descriptor.
 *     F_GETOWN Value of descriptor owner.
 *     F_GETSIG Value of signal sent when read or write becomes possible, or zero for traditional SIGIO behavior.
 *     F_GETPIPE_SZ The pipe capacity.
 *
 *     All other commands
 *              Zero.
 *
 *     On error, -1 is returned, and errno is set appropriately.
 */

#include <fcntl.h>
#include <signal.h>
#include "random.h"
#include "sanitise.h"
#include "shm.h"
#include "compat.h"

#if F_GETLK64 != F_GETLK
#define HAVE_LK64
#endif

static void sanitise_fcntl(int childno)
{
	switch (shm->a2[childno]) {
	/* arg = fd */
	case F_DUPFD:
	case F_DUPFD_CLOEXEC:
	case F_SETLEASE:
		shm->a3[childno] = (unsigned long) get_random_fd();
		break;

	/* no arg */
	case F_GETFD:
	case F_GETFL:
	case F_GETOWN:
	case F_GETSIG:
	case F_GETLEASE:
	case F_GETPIPE_SZ:
	case F_GETOWNER_UIDS:
		break;

	case F_SETFD:	/* arg = flags */
		shm->a3[childno] = (unsigned int) rand32();
		break;

	case F_SETFL:
		shm->a3[childno] = 0L;
		if (rand_bool())
			shm->a3[childno] |= O_APPEND;
		if (rand_bool())
			shm->a3[childno] |= O_ASYNC;
		if (rand_bool())
			shm->a3[childno] |= O_DIRECT;
		if (rand_bool())
			shm->a3[childno] |= O_NOATIME;
		if (rand_bool())
			shm->a3[childno] |= O_NONBLOCK;
		break;

	/* arg = (struct flock *) */
	case F_GETLK:
	case F_SETLK:
	case F_SETLKW:
		break;
#ifdef HAVE_LK64
	case F_GETLK64:
		break;
	case F_SETLK64:
		break;
	case F_SETLKW64:
		break;
#endif

	case F_SETOWN:
		shm->a3[childno] = (unsigned long) get_pid();
		break;

	/* arg = struct f_owner_ex *) */
	case F_GETOWN_EX:
	case F_SETOWN_EX:
		break;

	case F_SETSIG:
		shm->a3[childno] = (unsigned long) rand32();
		if (shm->a3[childno] == SIGINT)
			shm->a3[childno] = 0; /* restore default (SIGIO) */
		break;

	case F_NOTIFY:
		shm->a3[childno] = 0L;
		if (rand_bool())
			shm->a3[childno] |= DN_ACCESS;
		if (rand_bool())
			shm->a3[childno] |= DN_MODIFY;
		if (rand_bool())
			shm->a3[childno] |= DN_CREATE;
		if (rand_bool())
			shm->a3[childno] |= DN_DELETE;
		if (rand_bool())
			shm->a3[childno] |= DN_RENAME;
		if (rand_bool())
			shm->a3[childno] |= DN_ATTRIB;
		break;

	case F_SETPIPE_SZ:
		shm->a3[childno] = rand32();
		break;

	default:
		break;
	}

}

struct syscall syscall_fcntl = {
	.name = "fcntl",
	.num_args = 3,
	.arg1name = "fd",
	.arg1type = ARG_FD,
	.arg2name = "cmd",
	.arg2type = ARG_OP,
	.arg2list = {
#ifndef HAVE_LK64
		.num = 21,
#else
		.num = 24,
#endif
		.values = { F_DUPFD, F_DUPFD_CLOEXEC, F_GETFD, F_SETFD, F_GETFL, F_SETFL, F_GETLK, F_SETLK,
		  F_SETLKW, F_GETOWN, F_SETOWN, F_GETOWN_EX, F_SETOWN_EX, F_GETSIG, F_SETSIG, F_GETLEASE,
		  F_SETLEASE, F_NOTIFY, F_SETPIPE_SZ, F_GETPIPE_SZ, F_GETOWNER_UIDS,
#ifdef HAVE_LK64
		  F_GETLK64, F_SETLK64, F_SETLKW64,
#endif
		},
	},
	.arg3name = "arg",
	.rettype = RET_FD,	//FIXME: Needs to mutate somehow depending on 'cmd'
	.flags = NEED_ALARM,
	.group = GROUP_VFS,
	.sanitise = sanitise_fcntl,
};