diff --git a/test/open-cd-excl.c b/test/open-cd-excl.c new file mode 100644 index 0000000..34404e2 --- /dev/null +++ b/test/open-cd-excl.c @@ -0,0 +1,137 @@ +/* + * open-cd-excl.c --- This program tries to open a block device + * by various exclusive and non-exclusive gestures in order to explore + * their impact on running CD/DVD recordings. + * + * Copyright 2007, by Theodore Ts'o. + * + * Detail modifications 2007, by Thomas Schmitt. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +#define _GNU_SOURCE /* for O_LARGEFILE *//*ts A70417: or _LARGEFILE64_SOURCE */ + +#include +#include +#include +#include +#include +#include + +const char *progname; + +static void usage(void) +{ + fprintf(stderr, "Usage: %s [-feirw] device\n", progname); + exit(1); +} + +/* ts A70417: added parameter do_rdwr */ +static void init_flock(struct flock *fl, int do_rdwr) +{ + memset(fl, 0, sizeof(struct flock)); + if (do_rdwr) + fl->l_type = F_WRLCK; + else + fl->l_type = F_RDLCK; + fl->l_whence = SEEK_SET; + fl->l_start = 0; + fl->l_len = 0; +} + +int main(int argc, char **argv) +{ + struct flock fl; + char *device_name; + int fd, c, f_opt = 0, do_rdwr = 0, end_immediately = 0; + int flags = O_NONBLOCK|O_LARGEFILE; + + progname = argv[0]; + + /* ts A70417: added -w and -r */ + while ((c = getopt (argc, argv, "feirw")) != EOF) { + switch (c) { + case 'e': + flags |= O_EXCL; + break; + case 'f': + f_opt++; + break; + case 'i': + end_immediately = 1; + break; + case 'r': + do_rdwr = 0; + break; + case 'w': + do_rdwr = 1; + break; + case '?': + usage(); + exit(1); + } + } + + if (optind == argc) + usage(); + device_name = argv[optind++]; + + /* ts A70417 : made read-write adjustable independently of f_opt */ + if (do_rdwr) { + flags |= O_RDWR; + printf("Using O_RDWR\n"); + } else { + flags |= O_RDONLY; + printf("Using O_RDONLY\n"); + } + + if (flags & O_EXCL) + printf("Trying to open %s with O_EXCL ...\n", device_name); + fd = open(device_name, flags, 0); + if (fd < 0) { + perror("open"); + printf("failed\n"); + exit(1); + } + if (flags & O_EXCL) + printf("succeeded\n"); + + if (f_opt) { + init_flock(&fl, do_rdwr); + if (fcntl(fd, F_GETLK, &fl) < 0) { + perror("fcntl: F_GETLK: "); + exit(1); + } + printf("fcntl lock apparently %sLOCKED\n", + (fl.l_type == F_UNLCK) ? "NOT " : ""); + + /* ts A70418: do not try to lock if it is already locked */ + if (fl.l_type != F_UNLCK) { + printf("failed\n"); + exit(1); + } + + init_flock(&fl, do_rdwr); + printf("Trying to grab fcntl lock...\n"); + if (fcntl(fd, F_SETLKW, &fl) < 0) { + perror("fcntl: F_SETLKW: "); + exit(1); + } + printf("succeeded\n"); + } + + /* ts A70417: added end_immediately */ + printf("Holding %s open.\n", device_name); + if (end_immediately) + exit(0); + printf("Press ^C to exit.\n"); + while (1) { + sleep(300); + } + /* NOTREACHED */ + return 0; +}