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