home *** CD-ROM | disk | FTP | other *** search
- /* @(#)test-lock.c 1.2 91/01/24 */
- /* copyright 1991, Mike Howard & Miller/Howard Investments, Inc.
- all rights reserved */
-
- #include <stdio.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <sys/stat.h>
- #include "lock-file.h"
-
- #ifdef FCNTL_STYLE
- extern char *locking_style;
- extern int lock_errno;
- #endif
-
- #ifdef FLOCK_STYLE
- extern char *locking_style;
- extern int lock_errno;
- #endif
-
- #ifdef LOCKF_STYLE
- extern char *locking_style;
- extern int lock_errno;
- #endif
-
- #ifndef FCNTL_STYLE
- #ifndef FLOCK_STYLE
- #ifndef LOCKF_STYLE
- # define lock_record_shared_wait(fd, offset, len) 0
- # define lock_record_exclusive_wait(fd, offset, len) 0
- # define lock_record_shared_nowait(fd, offset, len) 0
- # define lock_record_exclusive_nowait(fd, offset, len) 0
- # define unlock_record(fd, offset, len) 0
- # define lock_file_shared_wait(fd) 0
- # define lock_file_exclusive_wait(fd) 0
- # define lock_file_shared_nowait(fd) 0
- # define lock_file_exclusive_nowait(fd) 0
- # define unlock_file(fd) 0
- char *locking_style = "no locking";
- int lock_support;
- int lock_errno;
- #endif
- #endif
- #endif
-
- /* #define USE_BUFFERED /* */
- #ifdef USE_BUFFERED
- char *io_style = "buffered i/o with fflush()ing";
- FILE *file;
- #else
- char *io_style = "raw i/o";
- #endif
-
- int fd;
- int reps = 50;
- int child_pid;
- int parent_pid;
- int corruptions;
- char *parent_fmt = "parent[%d]: ";
- char *child_fmt = "child[%d]: ";
- char parent_text[80];
- char child_text[80];
- int exit_code;
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- fprintf(stdout, "%s %s - pid: %d\n", argv[0], argc > 1 ? argv[1] : "",
- getpid());
- sprintf(parent_text, parent_fmt, parent_pid = getpid());
- fprintf(stdout, "%s%s - %s\n", parent_text, locking_style, io_style);
- fprintf(stdout, "%s lock_support: 0x%0x\n", parent_text, lock_support);
- fflush(stdout);
-
- if (argc > 1) {
- if ((reps = atoi(argv[1])) < 1) {
- fprintf(stderr, "%s [reps (>= 1)]\n", argv[0]);
- exit(1);
- }
- }
- if ((fd = open("test-tmp", O_RDWR | O_CREAT | O_TRUNC, 0666)) < 0) {
- fprintf(stderr, "cannot open test-tmp file\n");
- exit(1);
- }
- #ifdef USE_BUFFERED
- file = fdopen(fd, "r+");
- #endif
-
- /* exclusive file lock test */
- if (child_pid = fork())
- do_parent_append_test();
- else {
- do_child_append_test();
- exit(0);
- }
- wait_for_child(child_pid);
-
- /* record lock test */
- if (child_pid = fork())
- do_parent_record_lock_test();
- else {
- do_child_record_lock_test();
- exit(0);
- }
- wait_for_child(child_pid);
-
- #ifdef USE_BUFFERED
- fclose(file);
- #endif
- close(fd);
- exit(exit_code);
- }
-
- wait_for_child(child_pid)
- int child_pid;
- {
- int i;
- int status;
-
- while ((i = wait(&status)) != child_pid && i != -1)
- ;
- }
-
- /* exclusive file lock test */
-
- do_parent_append_test()
- {
- int i;
- int count = 0;
- int status;
- int parent_reps;
- int child_reps;
-
- if ((parent_reps = reps / 2 > 50 ? 50 : reps / 2) < 1)
- parent_reps = 1;
- if ((child_reps = reps / 5 > 20 ? 20 : reps / 5) < 1)
- child_reps = 1;
-
- sprintf(child_text, child_fmt, child_pid);
-
- fprintf(stdout, "%sreps: %d, parent_reps: %d, child_reps: %d\n",
- parent_text, reps, parent_reps, child_reps);
- fflush(stdout);
- for (i=0;i<reps;i+=parent_reps) {
- write_a_line("%s%d\n", parent_text, count++, parent_reps);
- printf("%s%d corrupt sequences found\n", parent_text,
- corruptions += read_the_file(parent_text));
- }
-
- exit_code = corruptions;
- }
-
- do_child_append_test()
- {
- int i;
- int count = 0;
- int child_reps;
-
- sprintf(child_text, child_fmt, getpid());
- close(fd);
- if ((fd = open("test-tmp", O_RDWR)) < 0) {
- fprintf(stderr, "child: cannot open test-tmp\n");
- exit(1);
- }
- if ((child_reps = reps / 5 > 20 ? 20 : reps / 5) < 1)
- child_reps = 1;
- child_pid = getpid();
- for (i=0;i<reps;i+=child_reps)
- write_a_line("%s%d\n", child_text, count++, child_reps);
- }
-
- write_a_line(fmt, text, msg, reps)
- char *fmt;
- char *text;
- int msg;
- int reps;
- {
- char buf[256];
- int i;
-
- if (i = lock_file_exclusive_wait(fd)) {
- fprintf(stdout, "%slock_file_exclusive_wait() failed: %d, lock_errno: %d\n",
- text, i, lock_errno);
- return;
- }
- sprintf(buf, fmt, text, msg);
- fprintf(stdout, fmt, text, msg);
- fflush(stdout);
- #ifdef USE_BUFFERED
- fseek(file, 0L, 2);
- for (i=0;i<reps;i++) {
- fprintf(file, fmt, text, msg);
- fflush(file);
- sleep(1);
- }
- #else /* USE_BUFFERED */
- lseek(fd, 0L, 2);
- sprintf(buf, fmt, text, msg);
- for (i=0;i<reps;i++) {
- write(fd, buf, strlen(buf));
- sleep(1);
- }
- #endif /* USE_BUFFERED */
- unlock_file(fd);
- }
-
- read_the_file(s)
- char *s;
- {
- char buf[256];
- int i;
- int corruptions = 0;
-
- if (i = lock_file_shared_wait(fd)) {
- fprintf(stdout, "lock_file_shared_wait() failed: %d, lock_errno: %d\n",
- i, lock_errno);
- return;
- }
- fprintf(stdout, "%s starting to read file\n", s);
- fflush(stdout);
- #ifdef USE_BUFFERED
- fseek(file, 0L, 0);
- while (fgets(buf, 256, file) && !feof(file))
- corruptions += count_corruptions(buf, strlen(buf));
- #else /* USE_BUFFERED */
- lseek(fd, 0L, 0);
- while ((i = read(fd, buf, 256)) > 0)
- corruptions += count_corruptions(buf, i);
- #endif /* USE_BUFFERED */
- fprintf(stdout, "%s finished reading file\n", s);
- fflush(stdout);
- unlock_file(fd);
-
- return corruptions;
- }
-
- #define START 0
- #define PARENT 1
- #define CHILD 2
- #define NUM 3
-
- count_corruptions(s, len)
- char *s;
- int len;
- {
- static int state = START;
- static int idx = 0;
- int count = 0;
- char c;
-
- while (len-- > 0) {
- c = *s++;
- switch (state) {
- case START:
- switch (c) {
- case 'p':
- state = PARENT;
- idx = 1;
- break;
- case 'c':
- state = CHILD;
- idx = 1;
- break;
- default:
- break;
- }
- break;
- case PARENT:
- if (c != parent_text[idx++]) {
- count++;
- state = START;
- }
- else {
- if (idx == strlen(parent_text))
- state = NUM;
- }
- break;
- case CHILD:
- if (c != child_text[idx++]) {
- count++;
- state = START;
- }
- else {
- if (idx == strlen(child_text))
- state = NUM;
- }
- break;
- case NUM:
- if (c == '\n')
- state = START;
- else if (c < '0' || c > '9') {
- count++;
- state = START;
- }
- break;
- }
- }
-
- return count;
- }
-
- /* record lock test - child locks the middle third of the file
- and then sleeps for 5 seconds; the parent sleeps for 2 seconds
- and then tests for a shared lock on the middle third */
-
- do_parent_record_lock_test()
- {
- int i;
- struct stat stat_buf;
- off_t offset;
-
- sprintf(parent_text, parent_fmt, parent_pid = getpid());
-
- fprintf(stdout, "%srecord lock test: %s - %s\n",
- parent_text, locking_style, io_style);
- fflush(stdout);
- fstat(fd, &stat_buf);
- offset = stat_buf.st_size / 3;
- sleep(2);
- printf("%s lock_record_shared_nowait(%d, %ld, %ld): %d\n",
- parent_text, fd, offset, offset,
- i = lock_record_shared_nowait(fd, offset, offset));
- printf("%s record lock test %s lock_errno: %d (should be %d)\n",
- parent_text, i ? "passed" : "failed", lock_errno,
- LCK_BLOCK);
- if (!i) {
- unlock_record(fd, offset, offset);
- exit_code++;
- }
- }
-
- do_child_record_lock_test()
- {
- struct stat stat_buf;
- off_t offset;
-
- sprintf(child_text, child_fmt, getpid());
- close(fd);
- if ((fd = open("test-tmp", O_RDWR)) < 0) {
- fprintf(stderr, "%s cannot open test-tmp\n", child_text);
- exit(1);
- }
- fstat(fd, &stat_buf);
- offset = stat_buf.st_size/3;
-
- if (lock_record_exclusive_nowait(fd, offset, offset)) {
- printf("%s lock_record_exclusive_nowait(%d, %ld, %ld) failed: lock_errno: %d\n",
- child_text, fd, offset, offset, lock_errno);
- return(2);
- }
- sleep(5);
- unlock_record(fd, offset, offset);
-
- return 0;
- }
-