home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2610 / test-lock.c < prev   
Encoding:
C/C++ Source or Header  |  1991-01-25  |  7.5 KB  |  359 lines

  1. /* @(#)test-lock.c    1.2 91/01/24 */
  2. /* copyright 1991, Mike Howard & Miller/Howard Investments, Inc.
  3.    all rights reserved */
  4.  
  5. #include <stdio.h>
  6. #include <fcntl.h>
  7. #include <errno.h>
  8. #include <sys/types.h>
  9. #include <sys/wait.h>
  10. #include <sys/stat.h>
  11. #include "lock-file.h"
  12.  
  13. #ifdef FCNTL_STYLE
  14. extern char *locking_style;
  15. extern int lock_errno;
  16. #endif
  17.  
  18. #ifdef FLOCK_STYLE
  19. extern char *locking_style;
  20. extern int lock_errno;
  21. #endif
  22.  
  23. #ifdef LOCKF_STYLE
  24. extern char *locking_style;
  25. extern int lock_errno;
  26. #endif
  27.  
  28. #ifndef FCNTL_STYLE
  29. #ifndef FLOCK_STYLE
  30. #ifndef LOCKF_STYLE
  31. # define lock_record_shared_wait(fd, offset, len) 0
  32. # define lock_record_exclusive_wait(fd, offset, len) 0
  33. # define lock_record_shared_nowait(fd, offset, len) 0
  34. # define lock_record_exclusive_nowait(fd, offset, len) 0
  35. # define unlock_record(fd, offset, len) 0
  36. # define lock_file_shared_wait(fd) 0
  37. # define lock_file_exclusive_wait(fd) 0
  38. # define lock_file_shared_nowait(fd) 0
  39. # define lock_file_exclusive_nowait(fd) 0
  40. # define unlock_file(fd) 0
  41. char *locking_style = "no locking";
  42. int lock_support;
  43. int lock_errno;
  44. #endif
  45. #endif
  46. #endif
  47.  
  48. /* #define USE_BUFFERED /* */
  49. #ifdef USE_BUFFERED
  50. char *io_style = "buffered i/o with fflush()ing";
  51. FILE *file;
  52. #else
  53. char *io_style = "raw i/o";
  54. #endif
  55.  
  56. int fd;
  57. int reps = 50;
  58. int child_pid;
  59. int parent_pid;
  60. int corruptions;
  61. char *parent_fmt = "parent[%d]: ";
  62. char *child_fmt = "child[%d]: ";
  63. char parent_text[80];
  64. char child_text[80];
  65. int exit_code;
  66.  
  67. main(argc, argv)
  68. int argc;
  69. char **argv;
  70. {
  71.   fprintf(stdout, "%s %s - pid: %d\n", argv[0], argc > 1 ? argv[1] : "",
  72.       getpid());
  73.   sprintf(parent_text, parent_fmt, parent_pid = getpid());
  74.   fprintf(stdout, "%s%s - %s\n", parent_text, locking_style, io_style);
  75.   fprintf(stdout, "%s lock_support: 0x%0x\n", parent_text, lock_support);
  76.   fflush(stdout);
  77.  
  78.   if (argc > 1) {
  79.     if ((reps = atoi(argv[1])) < 1) {
  80.       fprintf(stderr, "%s [reps (>= 1)]\n", argv[0]);
  81.       exit(1);
  82.     }
  83.   }
  84.   if ((fd = open("test-tmp", O_RDWR | O_CREAT | O_TRUNC, 0666)) < 0) {
  85.     fprintf(stderr, "cannot open test-tmp file\n");
  86.     exit(1);
  87.   }
  88. #ifdef USE_BUFFERED
  89.   file = fdopen(fd, "r+");
  90. #endif
  91.  
  92.   /* exclusive file lock test */
  93.   if (child_pid = fork())
  94.     do_parent_append_test();
  95.   else {
  96.     do_child_append_test();
  97.     exit(0);
  98.   }
  99.   wait_for_child(child_pid);
  100.  
  101.   /* record lock test */
  102.   if (child_pid = fork())
  103.     do_parent_record_lock_test();
  104.   else {
  105.     do_child_record_lock_test();
  106.     exit(0);
  107.   }
  108.   wait_for_child(child_pid);
  109.  
  110. #ifdef USE_BUFFERED
  111.   fclose(file);
  112. #endif
  113.   close(fd);
  114.   exit(exit_code);
  115. }
  116.  
  117. wait_for_child(child_pid)
  118. int child_pid;
  119. {
  120.   int i;
  121.   int status;
  122.  
  123.   while ((i = wait(&status)) != child_pid && i != -1)
  124.     ;
  125. }
  126.  
  127. /* exclusive file lock test */
  128.  
  129. do_parent_append_test()
  130. {
  131.   int i;
  132.   int count = 0;
  133.   int status;
  134.   int parent_reps;
  135.   int child_reps;
  136.  
  137.   if ((parent_reps = reps / 2 > 50 ? 50 : reps / 2) < 1)
  138.     parent_reps = 1;
  139.   if ((child_reps = reps / 5 > 20 ? 20 : reps / 5) < 1)
  140.     child_reps = 1;
  141.   
  142.   sprintf(child_text, child_fmt, child_pid);
  143.  
  144.   fprintf(stdout, "%sreps: %d, parent_reps: %d, child_reps: %d\n",
  145.       parent_text, reps, parent_reps, child_reps);
  146.   fflush(stdout);
  147.   for (i=0;i<reps;i+=parent_reps) {
  148.     write_a_line("%s%d\n", parent_text, count++, parent_reps);
  149.     printf("%s%d corrupt sequences found\n", parent_text,
  150.        corruptions += read_the_file(parent_text));
  151.   }
  152.  
  153.   exit_code = corruptions;
  154. }
  155.  
  156. do_child_append_test()
  157. {
  158.   int i;
  159.   int count = 0;
  160.   int child_reps;
  161.  
  162.   sprintf(child_text, child_fmt, getpid());
  163.   close(fd);
  164.   if ((fd = open("test-tmp", O_RDWR)) < 0) {
  165.     fprintf(stderr, "child: cannot open test-tmp\n");
  166.     exit(1);
  167.   }
  168.   if ((child_reps = reps / 5 > 20 ? 20 : reps / 5) < 1)
  169.     child_reps = 1;
  170.   child_pid = getpid();
  171.   for (i=0;i<reps;i+=child_reps)
  172.     write_a_line("%s%d\n", child_text, count++, child_reps);
  173. }
  174.  
  175. write_a_line(fmt, text, msg, reps)
  176. char *fmt;
  177. char *text;
  178. int msg;
  179. int reps;
  180. {
  181.   char buf[256];
  182.   int i;
  183.  
  184.   if (i = lock_file_exclusive_wait(fd)) {
  185.     fprintf(stdout, "%slock_file_exclusive_wait() failed: %d, lock_errno: %d\n",
  186.         text, i, lock_errno);
  187.     return;
  188.   }
  189.   sprintf(buf, fmt, text, msg);
  190.   fprintf(stdout, fmt, text, msg);
  191.   fflush(stdout);
  192. #ifdef USE_BUFFERED
  193.   fseek(file, 0L, 2);
  194.   for (i=0;i<reps;i++) {
  195.     fprintf(file, fmt, text, msg);
  196.     fflush(file);
  197.     sleep(1);
  198.   }
  199. #else  /* USE_BUFFERED */
  200.   lseek(fd, 0L, 2);
  201.   sprintf(buf, fmt, text, msg);
  202.   for (i=0;i<reps;i++) {
  203.     write(fd, buf, strlen(buf));
  204.     sleep(1);
  205.   }
  206. #endif /* USE_BUFFERED */
  207.   unlock_file(fd);
  208. }
  209.  
  210. read_the_file(s)
  211. char *s;
  212. {
  213.   char buf[256];
  214.   int i;
  215.   int corruptions = 0;
  216.  
  217.   if (i = lock_file_shared_wait(fd)) {
  218.     fprintf(stdout, "lock_file_shared_wait() failed: %d, lock_errno: %d\n",
  219.         i, lock_errno);
  220.     return;
  221.   }
  222.   fprintf(stdout, "%s starting to read file\n", s);
  223.   fflush(stdout);
  224. #ifdef USE_BUFFERED
  225.   fseek(file, 0L, 0);
  226.   while (fgets(buf, 256, file) && !feof(file))
  227.     corruptions += count_corruptions(buf, strlen(buf));
  228. #else  /* USE_BUFFERED */
  229.   lseek(fd, 0L, 0);
  230.   while ((i = read(fd, buf, 256)) > 0)
  231.     corruptions += count_corruptions(buf, i);
  232. #endif /* USE_BUFFERED */
  233.   fprintf(stdout, "%s finished reading file\n", s);
  234.   fflush(stdout);
  235.   unlock_file(fd);
  236.  
  237.   return corruptions;
  238. }
  239.  
  240. #define START  0
  241. #define PARENT 1
  242. #define CHILD  2
  243. #define NUM    3
  244.  
  245. count_corruptions(s, len)
  246. char *s;
  247. int len;
  248. {
  249.   static int state = START;
  250.   static int idx = 0;
  251.   int count = 0;
  252.   char c;
  253.  
  254.   while (len-- > 0) {
  255.     c = *s++;
  256.     switch (state) {
  257.     case START:
  258.       switch (c) {
  259.       case 'p':
  260.     state = PARENT;
  261.     idx = 1;
  262.     break;
  263.       case 'c':
  264.     state = CHILD;
  265.     idx = 1;
  266.     break;
  267.       default:
  268.     break;
  269.       }
  270.       break;
  271.     case PARENT:
  272.       if (c != parent_text[idx++]) {
  273.     count++;
  274.     state = START;
  275.       }
  276.       else {
  277.     if (idx == strlen(parent_text))
  278.       state = NUM;
  279.       }
  280.       break;
  281.     case CHILD:
  282.       if (c != child_text[idx++]) {
  283.     count++;
  284.     state = START;
  285.       }
  286.       else {
  287.     if (idx == strlen(child_text))
  288.       state = NUM;
  289.       }
  290.       break;
  291.     case NUM:
  292.       if (c == '\n')
  293.     state = START;
  294.       else if (c < '0' || c > '9') {
  295.     count++;
  296.     state = START;
  297.       }
  298.       break;
  299.     }
  300.   }
  301.  
  302.   return count;
  303. }
  304.  
  305. /* record lock test - child locks the middle third of the file
  306.    and then sleeps for 5 seconds; the parent sleeps for 2 seconds
  307.    and then tests for a shared lock on the middle third */
  308.  
  309. do_parent_record_lock_test()
  310. {
  311.   int i;
  312.   struct stat stat_buf;
  313.   off_t offset;
  314.  
  315.   sprintf(parent_text, parent_fmt, parent_pid = getpid());
  316.  
  317.   fprintf(stdout, "%srecord lock test: %s - %s\n",
  318.       parent_text, locking_style, io_style);
  319.   fflush(stdout);
  320.   fstat(fd, &stat_buf);
  321.   offset = stat_buf.st_size / 3;
  322.   sleep(2);
  323.   printf("%s lock_record_shared_nowait(%d, %ld, %ld): %d\n",
  324.      parent_text, fd, offset, offset,
  325.      i = lock_record_shared_nowait(fd, offset, offset));
  326.   printf("%s record lock test %s lock_errno: %d (should be %d)\n",
  327.      parent_text, i ? "passed" : "failed", lock_errno,
  328.      LCK_BLOCK);
  329.   if (!i) {
  330.     unlock_record(fd, offset, offset);
  331.     exit_code++;
  332.   }
  333. }
  334.  
  335. do_child_record_lock_test()
  336. {
  337.   struct stat stat_buf;
  338.   off_t offset;
  339.  
  340.   sprintf(child_text, child_fmt, getpid());
  341.   close(fd);
  342.   if ((fd = open("test-tmp", O_RDWR)) < 0) {
  343.     fprintf(stderr, "%s cannot open test-tmp\n", child_text);
  344.     exit(1);
  345.   }
  346.   fstat(fd, &stat_buf);
  347.   offset = stat_buf.st_size/3;
  348.  
  349.   if (lock_record_exclusive_nowait(fd, offset, offset)) {
  350.     printf("%s lock_record_exclusive_nowait(%d, %ld, %ld) failed: lock_errno: %d\n",
  351.        child_text, fd, offset, offset, lock_errno);
  352.     return(2);
  353.   }
  354.   sleep(5);
  355.   unlock_record(fd, offset, offset);
  356.  
  357.   return 0;
  358. }
  359.