Project

General

Profile

Bug #6016 ยป lock.c

Marcel Telka, 2015-06-18 09:45 PM

 
1
#include <sys/types.h>
2
#include <sys/stat.h>
3
#include <fcntl.h>
4
#include <stdio.h>
5
#include <unistd.h>
6
#include <string.h>
7
#include <stdlib.h>
8
#include <ctype.h>
9
#include <limits.h>
10

    
11
static int
12
convert_int(int *val, char *str)
13
{
14
	long lval;
15

    
16
	if (str == NULL || !isdigit(*str))
17
		return (-1);
18

    
19
	lval = strtol(str, &str, 10);
20
	if (*str != '\0' || lval > INT_MAX)
21
		return (-2);
22

    
23
	*val = (int)lval;
24
	return (0);
25
}
26

    
27
void
28
lock_cmd_usage(void) {
29
	printf("Usage: lock r|R|w|W|u|U start len filename\n");
30
}
31

    
32
void
33
test_cmd_usage(void) {
34
	printf("Usage: test r|w|u start len filename\n");
35
}
36

    
37
int
38
locktest_cmd(int argc, char *argv[])
39
{
40
	int f;
41
	struct flock fl;
42
	int cmd;
43
	int t;
44
	void (*usage_fnc)(void);
45

    
46
	if (argc < 1)
47
		return -1;
48

    
49
	if (strcmp(argv[0], "lock") == 0) {
50
		usage_fnc = lock_cmd_usage;
51
		cmd = F_SETLK;
52
	} else if (strcmp(argv[0], "test") == 0) {
53
		usage_fnc = test_cmd_usage;
54
		cmd = F_GETLK;
55
	} else {
56
		return -1;
57
	}
58

    
59
	if (argc != 5 || strlen(argv[1]) != 1) {
60
		usage_fnc();
61
		return -1;
62
	}
63

    
64
	f = open(argv[4], O_RDWR | O_CREAT, 0777);
65
	if (f == -1) {
66
		printf("open failed\n");
67
		return -1;
68
	}
69

    
70
	switch (argv[1][0]) {
71
	case 'r':
72
	case 'w':
73
	case 'u': break;
74
	case 'R':
75
	case 'W':
76
	case 'U':
77
		if (cmd == F_SETLK) {
78
			cmd = F_SETLKW;
79
			break;
80
		}
81
	default: usage_fnc(); return -1;
82
	}
83

    
84
	switch (argv[1][0]) {
85
	case 'r':
86
	case 'R': fl.l_type = F_RDLCK; break;
87
	case 'w':
88
	case 'W': fl.l_type = F_WRLCK; break;
89
	case 'u':
90
	case 'U': fl.l_type = F_UNLCK; break;
91
	default: usage_fnc(); return -1;
92
	}
93

    
94
	fl.l_whence = SEEK_SET;
95

    
96
	if (convert_int(&t, argv[2]) != 0) {
97
		usage_fnc(); return -1;
98
	}
99
	fl.l_start = t;
100
	if (convert_int(&t, argv[3]) != 0) {
101
		usage_fnc(); return -1;
102
	}
103
	fl.l_len = t;
104

    
105
	if (fcntl(f, cmd, &fl) == -1) {
106
		printf("fcntl failed\n");
107
		return 0;
108
	}
109

    
110
	if (cmd == F_GETLK) {
111
		char *s;
112

    
113
		switch (fl.l_type) {
114
		case F_WRLCK: s = "F_WRLCK"; break;
115
		case F_RDLCK: s = "F_RDLCK"; break;
116
		case F_UNLCK: s = "F_UNLCK"; break;
117
		default: s = "unknown"; break;
118
		}
119

    
120
		printf("F_GETLK: %s %ld %ld\n", s, fl.l_start, fl.l_len);
121
	}
122

    
123
	return 0;
124
}
125

    
126
int
127
sleep_cmd(int argc, char *argv[])
128
{
129
	int sec;
130

    
131
	if (argc != 2 || convert_int(&sec, argv[1]) != 0)
132
		return -1;
133

    
134
	(void) sleep(sec);
135

    
136
	return 0;
137
}
138

    
139
void
140
parse_cmd(char *s)
141
{
142
	char *argv[5];
143
	int argc = 0;
144
	int r = -1;
145

    
146
	for (;;) {
147
		while (*s != '\0' && !isgraph(*s))
148
			*s++ = '\0';
149

    
150
		if (*s == '\0')
151
			break;
152

    
153
		argv[argc++] = s;
154

    
155
		while (*s != '\0' && isgraph(*s))
156
			s++;
157
	}
158

    
159
	if (argv == 0)
160
		return;
161

    
162
	if (strcmp(argv[0], "lock") == 0)
163
		r = locktest_cmd(argc, argv);
164
	else if (strcmp(argv[0], "test") == 0)
165
		r = locktest_cmd(argc, argv);
166
	else if (strcmp(argv[0], "sleep") == 0)
167
		r = sleep_cmd(argc, argv);
168

    
169
	if (r != 0)
170
		printf("syntax error\n");
171
}
172

    
173
int
174
main(int argc, char *argv[])
175
{
176
	char *line;
177
	size_t len;
178

    
179
	for (;;) {
180
		line = NULL;
181
		len = 0;
182
		printf("> ");
183
		fflush(stdout);
184
		if (getline(&line, &len, stdin) == -1)
185
			break;
186

    
187
		parse_cmd(line);
188
		free(line);
189
	}
190

    
191
	return 0;
192
}
    (1-1/1)