#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "util.h"
int verbose = 0;
static int
test1(int fd)
{
struct flock fl;
pid_t pid;
int res;
fl.l_start = 0;
fl.l_len = 16;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_CUR;
res = fcntl(fd, F_SETLK, &fl);
FAIL(res != 0);
pid = fork();
if (pid == -1)
err(1, "fork");
if (pid == 0) {
res = fcntl(fd, F_SETLK, &fl);
FAIL(res != -1);
FAIL(fl.l_type != F_WRLCK);
_exit(0);
}
res = safe_waitpid(pid);
FAIL(res != 0);
SUCCEED;
}
static int
test2(int fd)
{
struct flock fl;
pid_t pid;
off_t len = 16;
int res;
if (lseek(fd, len, SEEK_SET) == -1)
err(1, "lseek");
fl.l_start = 0;
fl.l_len = -len;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_CUR;
res = fcntl(fd, F_SETLK, &fl);
FAIL(res != 0);
pid = fork();
if (pid == -1)
err(1, "fork");
if (pid == 0) {
if (lseek(fd, 0, SEEK_SET) == -1)
err(1, "lseek");
fl.l_start = 0;
fl.l_len = len;
fl.l_whence = SEEK_SET;
res = fcntl(fd, F_GETLK, &fl);
FAIL(res != 0);
FAIL(fl.l_type != F_WRLCK);
_exit(0);
}
res = safe_waitpid(pid);
FAIL(res != 0);
SUCCEED;
}
static struct test tests[] = {
{ test1, 0 },
{ test2, 0 },
};
static int test_count = sizeof(tests) / sizeof(tests[0]);
int
main(int argc, char *argv[])
{
const char *errstr;
int c, error, fd, i;
int testnum = 0;
while ((c = getopt(argc, argv, "v")) != -1)
switch (c) {
case 'v':
verbose = 1;
break;
default:
usage();
}
argc -= optind;
argv += optind;
if (argc > 1)
usage();
if (argc == 1) {
testnum = strtonum(argv[0], 1, test_count, &errstr);
if (testnum == 0)
errx(1, "test number %s", errstr);
}
fd = make_file(1024);
error = 0;
for (i = 0; i < test_count; i++) {
if (testnum == 0 || i + 1 == testnum)
error |= tests[i].testfn(fd);
}
return (error ? 1 : 0);
}