home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0010 - 0019 / ibm0010-0019 / ibm0010.tar / ibm0010 / PROCWRKB.ZIP / BENCH1.ZIP / BENCH / RELIO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-23  |  11.7 KB  |  584 lines

  1. /* ==( bench/relio.c )== */
  2. /* ----------------------------------------------- */
  3. /* Pro-C  Copyright (C) 1984 - 1990 Vestronix Inc. */
  4. /* Modification to this source is not supported    */
  5. /* by Vestronix Inc.                               */
  6. /*            All Rights Reserved                  */
  7. /* ----------------------------------------------- */
  8. /* Written   RJZ  24-Sep-84                        */
  9. /* Modified  Nig  18-Jun-90  See comments below    */
  10. /* ----------------------------------------------- */
  11. /* %W%  (%H% %T%) */
  12.  
  13. /*
  14.  *  Modifications
  15.  *
  16.  *  18-Jun-90  Nig - Allow Group R&W on create
  17.  *  10-May-90  Geo - Debug section with FDEBUG & I,
  18.  *   also code crunching, will use STREAMS with fdopen()
  19.  *   5-May-90  Nig - Access checks for Xenix and 386ix
  20.  *  11-Dec-89  Geo - V2 version
  21.  *  25-Oct-89  Geo - 1.32 Merge
  22.  *  ...
  23. */
  24.  
  25. # include <stdio.h>
  26. # include <bench.h>
  27. # include <fileio.h>
  28.  
  29. #include <errno.h>
  30.  
  31. #ifdef UNIX
  32. #include <setjmp.h>
  33. #include <signal.h>
  34.  
  35. /*
  36.  * Enable Group R&W as well
  37. */
  38. #define OPN_FILE(fname, mode)    open(fname, mode);
  39. #define CRT_FILE(fname)          open(fname, O_EXCL | O_CREAT | O_RDWR, 00664);
  40. #endif
  41.  
  42. #ifdef MSC
  43. #define  OPN_FILE(fname, mode)    open(fname, O_BINARY | O_RDWR )
  44. #define  CRT_FILE(fname)          open(fname, O_CREAT  | O_BINARY | O_RDWR, S_IREAD | S_IWRITE)
  45. #endif
  46.  
  47. #ifdef __TURBOC__
  48. #define  OPN_FILE(fname, mode)    open(fname, O_BINARY | O_RDWR)
  49. #define  CRT_FILE(fname)          open(fname, O_CREAT  | O_BINARY | O_RDWR, S_IREAD | S_IWRITE)
  50. #endif
  51.  
  52. #ifdef LC
  53. #define  OPN_FILE(fname, mode)    open(fname, O_RAW | O_RDWR)
  54. #define  CRT_FILE(fname)          open(fname, O_CREAT | O_RAW | O_RDWR)
  55. #endif
  56.  
  57. #ifdef __WATCOMC__
  58. #define  OPN_FILE(fname, mode)    open(fname, O_BINARY | O_RDWR , S_IREAD | S_IWRITE)
  59. #define  CRT_FILE(fname)          open(fname, O_CREAT  | O_BINARY | O_RDWR, S_IREAD | S_IWRITE)
  60. #endif
  61.  
  62. #ifdef __ZTC__
  63. #define  OPN_FILE(fname, mode)    open(fname, O_RDWR)
  64. #define  CRT_FILE(fname)          creat(fname, O_RDWR)
  65. #endif
  66.  
  67. /* DEFINEs */
  68. # define MAX_FILES  16
  69. /* # define FDEBUG */
  70. /* # define FDEBUGI */
  71.  
  72. PROTO (void ptab, (char *));
  73. static PROTO (struct frec *get_ftab, (int, char *));
  74. static PROTO (void dump_tabentry, (int));
  75.  
  76. /* Global local variables */
  77. static struct frec
  78. {
  79.     char  *name;
  80.     int    fdesc;
  81.     int    len;
  82.     int    mode;
  83. # ifdef FDEBUGI
  84.     int nreads;
  85.     int nwrites;
  86. # endif
  87. } ftable[MAX_FILES];
  88.  
  89. static int file_init = -1;
  90.  
  91. extern long int lseek();
  92.  
  93. char FileNoAccess_s[] = "^%s^ could not be accessed.\nPlease check your path and/or permissions.";
  94. char FileInUse_s[]    = "^%s^ is in use elsewhere\nPlease try again later.";
  95.  
  96. char DupOpen_s[]           = "%s(): Duplicate open of (%s)";
  97. char TooManyFiles_s[]      = "%s(): Too many open files";
  98. char FilTabNotSet_s[]      = "%s(): File table not set";
  99. char FilDescNeg_s_d[]      = "%s(): File descriptor negative (%d)";
  100. char FilDescNotFound_s_d[] = "%s(): File descriptor not found (%d)";
  101. char SeekFailed_s_s[]      = "%s(): Seek failed on %s";
  102. char ReadFailed_s_d_s_d[]  = "%s(): Read %d bytes from %s, expected %d";
  103. char WriteFailed_s_d_s_d[] = "%s(): Wrote %d bytes to %s, expected %d";
  104.  
  105. /*
  106.  * open an existing file, or create and open a file
  107. */
  108. openf(fname, mode, len, fd)
  109. char    *fname;
  110. int    mode, len, *fd;
  111. {
  112.     int    i;
  113.     char *routine = "openf";
  114.  
  115.     if (file_init == -1) {
  116.         file_init = 0;
  117.         for (i = 0; i < MAX_FILES; i++)
  118.             ftable[i].fdesc = -1;
  119.     }
  120.  
  121.     for (i = 0; i < MAX_FILES && ftable[i].fdesc != -1; i++)
  122.         ;
  123.  
  124. # ifdef FDEBUG
  125.     /* Check for duplicate open */
  126.     {
  127.     int j;
  128.  
  129.         for (j = 0; j < i; j++)
  130.             if (strcmp(ftable[j].name, fname) == 0)
  131.             {
  132.                 ptab(routine);
  133.                 abort_mess(DupOpen_s, fname);
  134.             }
  135.     }
  136. # endif
  137.  
  138.     if (i == MAX_FILES)
  139.     {
  140. # ifdef FDEBUG
  141.         ptab(routine);
  142. # endif
  143.         abort_mess(TooManyFiles_s, routine);
  144.     }
  145.  
  146.     switch (mode)
  147.     {
  148.     case OPENRWNC :
  149.     case SH_OPENRWNC :
  150.         *fd = OPN_FILE(fname, O_RDWR);
  151.         break;
  152.  
  153.     case OPENRWC :
  154.     case SH_OPENRWC :
  155.         *fd = CRT_FILE(fname);
  156.         break;
  157.  
  158.     default :
  159.         mode = OPENRNC; /* Incase it's not set */
  160.         /* FALL THRU */
  161.  
  162.     case OPENRNC :
  163.     case SH_OPENRNC :
  164.         *fd = OPN_FILE(fname, O_RDONLY);
  165.         break;
  166.     }
  167.  
  168.     if (*fd >= 0)
  169.     {
  170. # ifdef UNIX
  171. /* lock the file */
  172.         if (mode != SH_OPENRWC && mode != SH_OPENRWNC && mode != SH_OPENRNC)
  173.         {
  174.             if (mode == OPENRNC)
  175.             {
  176.                 if (readlock(fd, fname))
  177.                     return(*fd);
  178.             }
  179.             else
  180.             {
  181.                 if (trylock(fd, fname))
  182.                     return(*fd);
  183.             }
  184.         }
  185. # endif
  186.         ftable[i].fdesc = *fd;
  187.         ftable[i].len   = len;
  188.         ftable[i].mode  = mode;
  189.         ftable[i].name  = strsave(fname);
  190.  
  191. # ifdef FDEBUGI
  192.         ftable[i].nreads = ftable[i].nwrites = 0;
  193.  
  194.         fprintf(stderr, "Opening %s\n", fname);
  195. # endif
  196.  
  197.     }
  198.     else
  199.     {
  200.         if (errno == EACCES || ((mode == OPENRWC || mode == SH_OPENRWC) && errno == ENOENT))
  201.             no_access(fname);
  202.     }
  203.  
  204.     return (*fd);
  205. }
  206.  
  207. static struct frec *get_ftab(fd, str)
  208. int fd;
  209. char *str;
  210. {
  211. int i;
  212.  
  213.     if (file_init == -1)
  214.         abort_mess(FilTabNotSet_s, str);
  215.  
  216.     if (fd < 0)
  217.         abort_mess(FilDescNeg_s_d, str, fd);
  218.  
  219.     for (i = 0; i < MAX_FILES; i++) {
  220.         if (fd == ftable[i].fdesc)
  221.             break;
  222.     }
  223.  
  224.     if (i == MAX_FILES)
  225.         abort_mess(FilDescNotFound_s_d, str, fd);
  226.  
  227.     return(&ftable[i]);
  228. }
  229.  
  230. # ifdef UNIX
  231. static jmp_buf alarmjmp;
  232. void (*oldalarmfunc)();
  233.  
  234. static void alarmsigstub()
  235. {
  236.     longjmp(alarmjmp, -1);
  237. }
  238.  
  239.  
  240. lok_rec(fd, recno, loktyp)
  241. int fd, recno, loktyp;
  242. {
  243.     int ret;
  244.     struct flock ldesc; /* fcntl(2) */
  245.     char *routine = "loc_rec";
  246.     struct frec *fptr = get_ftab(fd, routine);
  247.  
  248.     /* Change our lock type to X/OPEN type Geo says */
  249.     switch (loktyp)
  250.     {
  251.         case ULOK:
  252.             ldesc.l_type = F_UNLCK;
  253.             break;
  254.         case RLOK:
  255.             ldesc.l_type = F_RDLCK;
  256.             break;
  257.         case WLOK:
  258.             ldesc.l_type = F_WRLCK;
  259.             break;
  260.         default:
  261.             errmsg("lok_rec(): Bad lock type.");
  262.             break;
  263.     }
  264.  
  265.     ldesc.l_whence = 0;
  266.     ldesc.l_start = (long) recno * (long) fptr->len;
  267.     ldesc.l_len = (long) fptr->len;
  268.  
  269.     if ((ret = setjmp(alarmjmp)) == 0)
  270.     {
  271.         oldalarmfunc = signal(SIGALRM, alarmsigstub);
  272.         alarm(5);
  273.  
  274.         ret = fcntl(fptr->fdesc, F_SETLKW, &ldesc);
  275.     }
  276.     alarm(0);
  277.     signal(SIGALRM, oldalarmfunc);
  278.     return(ret);
  279. }
  280.  
  281. /* 
  282.  * Try and lock a file.  Close it and issue a message on failure 
  283.  * returns 0 for locked ok or not open, 1 if lock failed 
  284. */
  285. trylock(fd, fname)
  286. int    *fd;
  287. char    *fname;
  288. {
  289.     struct flock ldesc; /* fcntl(2) */
  290.  
  291.     ldesc.l_type = F_WRLCK;
  292.     ldesc.l_whence = 0;
  293.     ldesc.l_start = ldesc.l_len = 0L;
  294.  
  295.     if (*fd >= 0)  /* lock the whole file */
  296.     {
  297.         if (fcntl(*fd, F_SETLK, &ldesc) == -1) 
  298.         {
  299.             close(*fd);
  300.             locked_file(fname, 1);
  301.             *fd = -2;
  302.             return(1);
  303.         }
  304.     }
  305.     return (0);
  306. }
  307.  
  308. /* 
  309.  * Try and read lock a file.  Close it and issue a message on failure 
  310.  * returns 0 for locked ok or not open, 1 if lock failed
  311. */
  312. readlock(fd, fname)
  313. int    *fd;
  314. char    *fname;
  315. {
  316.     struct flock ldesc; /* fcntl(2) */
  317.  
  318.     ldesc.l_type = F_RDLCK;
  319.     ldesc.l_whence = 0;
  320.     ldesc.l_start = ldesc.l_len = 0L;
  321.  
  322.     if (*fd >= 0)  /* lock the whole file */
  323.     {
  324.         if (fcntl(*fd, F_SETLK, &ldesc) == -1) 
  325.         {
  326.             close(*fd);
  327.             locked_file(fname, 1);
  328.             *fd = -2;
  329.             return(1);
  330.         }
  331.     }
  332.     return (0);
  333. }
  334.  
  335. /*
  336.  *  Issue an error message about a locked file.  
  337. */
  338. void locked_file(paramfile, helpnum)
  339. char    *paramfile;
  340. int    helpnum;
  341. {
  342.     errmsg(FileInUse_s, paramfile);
  343. }
  344.  
  345. #else
  346. lok_rec(fd, recno, loktyp)
  347. int    fd, recno, loktyp;
  348. {
  349.     return(0);
  350. }
  351. #endif
  352.  
  353. /*
  354.  *  Issue an error message about an uncreatable file.  
  355. */
  356. void no_access(paramfile)
  357. char    *paramfile;
  358. {
  359.     errmsg(FileNoAccess_s, paramfile);
  360. }
  361.  
  362. /*
  363.  * Read a record from a relative (sequential) file
  364. */
  365. void get_rec(fd, recno, record)
  366. int    fd, recno;
  367. char    *record;
  368. {
  369.     int count;
  370.     long int    offset;
  371.     char *routine = "get_rec";
  372.     struct frec *fptr = get_ftab(fd, routine);
  373.  
  374.     offset = (long) recno * (long) fptr->len;
  375.     if (lseek(fptr->fdesc, offset, SEEK_SET) == -1)
  376.     {
  377. # ifdef FDEBUG
  378.         ptab(routine);
  379. # endif
  380.         abort_mess(SeekFailed_s_s, routine, fptr->name);
  381.     }
  382.     
  383.     count = read(fptr->fdesc, record, fptr->len);
  384.     if (count != fptr->len)
  385.     {
  386. # ifdef FDEBUG
  387.         ptab(routine);
  388. # endif
  389.         abort_mess(ReadFailed_s_d_s_d, routine, count, fptr->name, fptr->len);
  390.     }
  391.  
  392. # ifdef FDEBUGI
  393.         fptr->nreads++;
  394. # endif
  395. }
  396.  
  397. /*
  398.  * Write a record to a relative (sequential) file
  399. */
  400. void put_rec(fd, recno, record)
  401. int    fd, recno;
  402. char    *record;
  403. {
  404.     long int    offset;
  405.     int count;
  406.     char *routine = "put_rec";
  407.     struct frec *fptr = get_ftab(fd, routine);
  408.  
  409.     offset = (long) recno * (long) fptr->len;
  410.     if (lseek(fptr->fdesc, offset, SEEK_SET) == -1)
  411.     {
  412. # ifdef FDEBUG
  413.         ptab(routine);
  414. # endif
  415.         abort_mess(SeekFailed_s_s, routine, fptr->name);
  416.     }
  417.  
  418.     count = write(fptr->fdesc, record, fptr->len);
  419.     if (count != fptr->len)
  420.     {
  421. # ifdef FDEBUG
  422.         ptab(routine);
  423. # endif
  424.         abort_mess(WriteFailed_s_d_s_d, routine, count, fptr->name, fptr->len);
  425.     }
  426.  
  427. # ifdef FDEBUGI
  428.         fptr->nwrites++;
  429. # endif
  430. }
  431.  
  432. /*
  433.  * close a file and remove it from ftable
  434. */
  435. void closef(fd)
  436. int    fd;
  437. {
  438.     int    i;
  439.  
  440.     for (i = 0; i < MAX_FILES; i++)
  441.         if (fd == ftable[i].fdesc)
  442.             if (fd != -1) 
  443.             {
  444. # ifdef FDEBUGI
  445.                 fprintf(stderr, "Closing %s\n", ftable[i].name);
  446.                 dump_tabentry(i);
  447. # endif
  448.                 close(fd);
  449.                 ftable[i].fdesc = -1;
  450.                 free(ftable[i].name);
  451.             }
  452. }
  453.  
  454. /*
  455.  * Close all open files when EXECing another process
  456. */
  457. void closefall()
  458. {
  459.     int    i;
  460.  
  461.     /* Skip if not set */
  462.     if (file_init == -1)
  463.         return;
  464.     for (i = 0; i < MAX_FILES; i++)
  465.         closef(ftable[i].fdesc);
  466. }
  467.  
  468. /* Returns size of file */
  469. long  sizef(fd)
  470. int    fd;
  471. {
  472.     return(lseek( get_ftab(fd, "sizef")->fdesc, 0L, SEEK_END));
  473. }
  474.  
  475. /*
  476.  * Read a record from a relative (sequential) file
  477.  * using absolute positioning
  478. */
  479. void abs_get_rec(fd, offset, record_length, record)
  480. int    fd,record_length;
  481. long  offset;
  482. char    *record;
  483. {
  484.     int count;
  485.     char *routine = "abs_get_rec";
  486.     struct frec *fptr = get_ftab(fd, routine);
  487.  
  488. /*
  489. statmsg("%s\nfd %d offset %ld\nrecord_length %d",
  490.     routine, fd, offset, record_length);
  491. */
  492.  
  493.     if (lseek(fptr->fdesc, offset, SEEK_SET) == -1)
  494.     {
  495. # ifdef FDEBUG
  496.         ptab(routine);
  497. # endif
  498.         abort_mess(SeekFailed_s_s, routine, fptr->name);
  499.     }
  500.     
  501.     count = read(fptr->fdesc, record, record_length);
  502.     if (count != record_length)
  503.     {
  504. # ifdef FDEBUG
  505.         ptab(routine);
  506. # endif
  507.         abort_mess(ReadFailed_s_d_s_d, routine, count, fptr->name, fptr->len);
  508.     }
  509.  
  510. # ifdef FDEBUGI
  511.     fptr->nreads++;
  512. # endif
  513. }
  514.  
  515. /*
  516.  * Write a record to a relative (sequential) file
  517.  * using absolute positioning
  518. */
  519. void abs_put_rec(fd, offset, record_length, record)
  520. int    fd, record_length;
  521. long offset;
  522. char    *record;
  523. {
  524.     int count;
  525.     char *routine = "abs_put_rec";
  526.     struct frec *fptr = get_ftab(fd, routine);
  527.  
  528. /*
  529. statmsg("%s\nfd %d offset %ld\nrecord_length %d",
  530.     routine, fd, offset, record_length);
  531. */
  532.  
  533.     if (lseek(fptr->fdesc, offset, SEEK_SET) == -1)
  534.     {
  535. # ifdef FDEBUG
  536.         ptab(routine);
  537. # endif
  538.         abort_mess(SeekFailed_s_s, routine, fptr->name);
  539.     }
  540.  
  541.     count = write(fptr->fdesc, record, record_length);
  542.     if (count != record_length)
  543.     {
  544. # ifdef FDEBUG
  545.         ptab(routine);
  546. # endif
  547.         abort_mess(WriteFailed_s_d_s_d, routine, count, fptr->name, fptr->len);
  548.     }
  549.  
  550. # ifdef FDEBUGI
  551.         fptr->nwrites++;
  552. # endif
  553. }
  554.  
  555. # ifdef FDEBUG
  556. void ptab(s)
  557. char *s;
  558. {
  559.     int i;
  560.  
  561.     fprintf(stderr, "\n%s\n", s);
  562.     for (i = 0; i < MAX_FILES; i++)
  563.         dump_tabentry(i);
  564.     fflush(stderr);
  565. }
  566.  
  567. static void dump_tabentry(n)
  568. int n;
  569. {
  570. # ifndef FDEBUGI
  571.     if (ftable[n].fdesc == -1)
  572.         return;
  573. # endif
  574.     fprintf(stderr, "%02d fd %02d : len %04d : mode %02d :",
  575.         n, ftable[n].fdesc, ftable[n].len, ftable[n].mode);
  576. # ifdef FDEBUGI
  577.     fprintf(stderr, " r%04d w%04d", ftable[n].nreads, ftable[n].nwrites);
  578. # endif
  579.     /* Should put a check in this for NULL names */
  580.     fprintf(stderr, " (%s)\n", ftable[n].name);
  581. }
  582. # endif
  583.  
  584.