home *** CD-ROM | disk | FTP | other *** search
- /* ==( bench/relio.c )== */
- /* ----------------------------------------------- */
- /* Pro-C Copyright (C) 1984 - 1990 Vestronix Inc. */
- /* Modification to this source is not supported */
- /* by Vestronix Inc. */
- /* All Rights Reserved */
- /* ----------------------------------------------- */
- /* Written RJZ 24-Sep-84 */
- /* Modified Geo 10-May-90 See comments below */
- /* ----------------------------------------------- */
- /* %W% (%H% %T%) */
-
- /*
- * Modifications
- *
- * 10-May-90 Geo - Debug section with FDEBUG & I,
- * also code crunching, will use STREAMS with fdopen()
- * 5-May-90 Nig - Access checks for Xenix and 386ix
- * 11-Dec-89 Geo - V2 version
- * 25-Oct-89 Geo - 1.32 Merge
- * ...
- */
-
- # include <stdio.h>
- # include <bench.h>
- # include <fileio.h>
-
- #include <errno.h>
-
- #ifdef UNIX
- #include <setjmp.h>
- #include <signal.h>
-
- #define OPN_FILE(fname, mode) open(fname, mode);
- #define CRT_FILE(fname) open(fname, O_EXCL | O_CREAT | O_RDWR, 00644);
- #endif
-
- #ifdef MSC
- #define OPN_FILE(fname, mode) open(fname, O_BINARY | O_RDWR )
- #define CRT_FILE(fname) open(fname, O_CREAT | O_BINARY | O_RDWR, S_IREAD | S_IWRITE)
- #endif
-
- #ifdef __TURBOC__
- #define OPN_FILE(fname, mode) open(fname, O_BINARY | O_RDWR)
- #define CRT_FILE(fname) open(fname, O_CREAT | O_BINARY | O_RDWR, S_IREAD | S_IWRITE)
- #endif
-
- #ifdef LC
- #define OPN_FILE(fname, mode) open(fname, O_RAW | O_RDWR)
- #define CRT_FILE(fname) open(fname, O_CREAT | O_RAW | O_RDWR)
- #endif
-
- #ifdef __WATCOMC__
- #define OPN_FILE(fname, mode) open(fname, O_BINARY | O_RDWR , S_IREAD | S_IWRITE)
- #define CRT_FILE(fname) open(fname, O_CREAT | O_BINARY | O_RDWR, S_IREAD | S_IWRITE)
- #endif
-
- #ifdef __ZTC__
- #define OPN_FILE(fname, mode) open(fname, O_RDWR)
- #define CRT_FILE(fname) creat(fname, O_RDWR)
- #endif
-
- /* DEFINEs */
- # define MAX_FILES 16
- /* # define FDEBUG */
- /* # define FDEBUGI */
-
- # ifdef ANSI
- void ptab(char *);
- static struct frec *get_ftab(int, char *);
- static void dump_tabentry(int);
- # else
- void ptab();
- static struct frec *get_ftab();
- static void dump_tabentry();
- # endif
-
- /* Global local variables */
- static struct frec
- {
- char *name;
- int fdesc;
- int len;
- int mode;
- # ifdef FDEBUGI
- int nreads;
- int nwrites;
- # endif
- } ftable[MAX_FILES];
-
- static int file_init = -1;
-
- extern long int lseek();
-
- /*
- * open an existing file, or create and open a file
- */
- openf(fname, mode, len, fd)
- char *fname;
- int mode, len, *fd;
- {
- int i;
- char *routine = "openf";
-
- if (file_init == -1) {
- file_init = 0;
- for (i = 0; i < MAX_FILES; i++)
- ftable[i].fdesc = -1;
- }
-
- for (i = 0; i < MAX_FILES && ftable[i].fdesc != -1; i++)
- ;
-
- # ifdef FDEBUG
- /* Check for duplicate open */
- {
- int j;
-
- for (j = 0; j < i; j++)
- if (strcmp(ftable[j].name, fname) == 0)
- {
- ptab(routine);
- abort_mess("%s(): Duplicate open of (%s)", routine, fname);
- }
- }
- # endif
-
- if (i == MAX_FILES)
- {
- # ifdef FDEBUG
- ptab(routine);
- # endif
- abort_mess("%s(): Too many open files", routine);
- }
-
- switch (mode)
- {
- case OPENRWNC :
- case SH_OPENRWNC :
- *fd = OPN_FILE(fname, O_RDWR);
- break;
-
- case OPENRWC :
- case SH_OPENRWC :
- *fd = CRT_FILE(fname);
- break;
-
- default :
- mode = OPENRNC; /* Incase it's not set */
- /* FALL THRU */
-
- case OPENRNC :
- case SH_OPENRNC :
- *fd = OPN_FILE(fname, O_RDONLY);
- break;
- }
-
- if (*fd >= 0)
- {
- # ifdef UNIX
- /* lock the file */
- if (mode != SH_OPENRWC && mode != SH_OPENRWNC && mode != SH_OPENRNC)
- {
- if (mode == OPENRNC)
- {
- if (readlock(fd, fname))
- return(*fd);
- }
- else
- {
- if (trylock(fd, fname))
- return(*fd);
- }
- }
- # endif
- ftable[i].fdesc = *fd;
- ftable[i].len = len;
- ftable[i].mode = mode;
- ftable[i].name = strsave(fname);
-
- # ifdef FDEBUGI
- ftable[i].nreads = ftable[i].nwrites = 0;
-
- fprintf(stderr, "Opening %s\n", fname);
- # endif
-
- }
- else /* Safe ??? NIG */
- {
- if (errno == EACCES || ((mode == OPENRWC || mode == SH_OPENRWC) && errno == ENOENT))
- no_access(fname);
- }
-
- return (*fd);
- }
-
- static struct frec *get_ftab(fd, str)
- int fd;
- char *str;
- {
- int i;
-
- if (file_init == -1)
- abort_mess("%s(): File table not set", str);
-
- if (fd < 0)
- abort_mess("%s(): File descriptor negative (%d)", str, fd);
-
- for (i = 0; i < MAX_FILES; i++) {
- if (fd == ftable[i].fdesc)
- break;
- }
-
- if (i == MAX_FILES)
- abort_mess("%s(): File descriptor not found (%d)", str, fd);
-
- return(&ftable[i]);
- }
-
- # ifdef UNIX
- static jmp_buf alarmjmp;
- void (*oldalarmfunc)();
-
- static void alarmsigstub()
- {
- longjmp(alarmjmp, -1);
- }
-
-
- lok_rec(fd, recno, loktyp)
- int fd, recno, loktyp;
- {
- int ret;
- struct flock ldesc; /* fcntl(2) */
- char *routine = "loc_rec";
- struct frec *fptr = get_ftab(fd, routine);
-
- /* Change our lock type to X/OPEN type Geo says */
- switch (loktyp)
- {
- case ULOK:
- ldesc.l_type = F_UNLCK;
- break;
- case RLOK:
- ldesc.l_type = F_RDLCK;
- break;
- case WLOK:
- ldesc.l_type = F_WRLCK;
- break;
- default:
- errmsg("lok_rec(): Bad lock type.");
- break;
- }
-
- ldesc.l_whence = 0;
- ldesc.l_start = (long) recno * (long) fptr->len;
- ldesc.l_len = (long) fptr->len;
-
- if ((ret = setjmp(alarmjmp)) == 0)
- {
- oldalarmfunc = signal(SIGALRM, alarmsigstub);
- alarm(5);
-
- ret = fcntl(fptr->fdesc, F_SETLKW, &ldesc);
- }
- alarm(0);
- signal(SIGALRM, oldalarmfunc);
- return(ret);
- }
-
- /*
- * Try and lock a file. Close it and issue a message on failure
- * returns 0 for locked ok or not open, 1 if lock failed
- */
- trylock(fd, fname)
- int *fd;
- char *fname;
- {
- struct flock ldesc; /* fcntl(2) */
-
- ldesc.l_type = F_WRLCK;
- ldesc.l_whence = 0;
- ldesc.l_start = ldesc.l_len = 0L;
-
- if (*fd >= 0) /* lock the whole file */
- {
- if (fcntl(*fd, F_SETLK, &ldesc) == -1)
- {
- close(*fd);
- locked_file(fname, 1);
- *fd = -2;
- return(1);
- }
- }
- return (0);
- }
-
- /*
- * Try and read lock a file. Close it and issue a message on failure
- * returns 0 for locked ok or not open, 1 if lock failed
- */
- readlock(fd, fname)
- int *fd;
- char *fname;
- {
- struct flock ldesc; /* fcntl(2) */
-
- ldesc.l_type = F_RDLCK;
- ldesc.l_whence = 0;
- ldesc.l_start = ldesc.l_len = 0L;
-
- if (*fd >= 0) /* lock the whole file */
- {
- if (fcntl(*fd, F_SETLK, &ldesc) == -1)
- {
- close(*fd);
- locked_file(fname, 1);
- *fd = -2;
- return(1);
- }
- }
- return (0);
- }
-
- /*
- * Issue an error message about a locked file.
- */
- void locked_file(paramfile, helpnum)
- char *paramfile;
- int helpnum;
- {
- errmsg("^%s^ is in use elsewhere\nPlease try again later.", paramfile);
- }
-
- #else
- lok_rec(fd, recno, loktyp)
- int fd, recno, loktyp;
- {
- return(0);
- }
- #endif
-
- /*
- * Issue an error message about an uncreatable file.
- */
- void no_access(paramfile)
- char *paramfile;
- {
- errmsg("^%s^ could not be accessed.\nPlease check your path and/or permissions.", paramfile);
- }
-
- /*
- * Read a record from a relative (sequential) file
- */
- void get_rec(fd, recno, record)
- int fd, recno;
- char *record;
- {
- int count;
- long int offset;
- char *routine = "get_rec";
- struct frec *fptr = get_ftab(fd, routine);
-
- offset = (long) recno * (long) fptr->len;
- if (lseek(fptr->fdesc, offset, SEEK_SET) == -1)
- {
- # ifdef FDEBUG
- ptab(routine);
- # endif
- abort_mess("%s(): Seek failed on %s", routine, fptr->name);
- }
-
- count = read(fptr->fdesc, record, fptr->len);
- if (count != fptr->len)
- {
- # ifdef FDEBUG
- ptab(routine);
- # endif
- abort_mess("%s(): Read %d bytes from %s, expected %d",
- routine, count, fptr->name, fptr->len);
- }
-
- # ifdef FDEBUGI
- fptr->nreads++;
- # endif
- }
-
- /*
- * Write a record to a relative (sequential) file
- */
- void put_rec(fd, recno, record)
- int fd, recno;
- char *record;
- {
- long int offset;
- int count;
- char *routine = "put_rec";
- struct frec *fptr = get_ftab(fd, routine);
-
- offset = (long) recno * (long) fptr->len;
- if (lseek(fptr->fdesc, offset, SEEK_SET) == -1)
- {
- # ifdef FDEBUG
- ptab(routine);
- # endif
- abort_mess("%s(): Seek failed on %s", routine, fptr->name);
- }
-
- count = write(fptr->fdesc, record, fptr->len);
- if (count != fptr->len)
- {
- # ifdef FDEBUG
- ptab(routine);
- # endif
- abort_mess("%s(): Wrote %d bytes to %s, expected %d",
- routine, count, fptr->name, fptr->len);
- }
-
- # ifdef FDEBUGI
- fptr->nwrites++;
- # endif
- }
-
- /*
- * close a file and remove it from ftable
- */
- void closef(fd)
- int fd;
- {
- int i;
-
- for (i = 0; i < MAX_FILES; i++)
- if (fd == ftable[i].fdesc)
- if (fd != -1)
- {
- # ifdef FDEBUGI
- fprintf(stderr, "Closing %s\n", ftable[i].name);
- dump_tabentry(i);
- # endif
- close(fd);
- ftable[i].fdesc = -1;
- free(ftable[i].name);
- }
- }
-
- /*
- * Close all open files when EXECing another process
- */
- void closefall()
- {
- int i;
-
- /* Skip if not set */
- if (file_init == -1)
- return;
- for (i = 0; i < MAX_FILES; i++)
- closef(ftable[i].fdesc);
- }
-
- /* Returns size of file */
- long sizef(fd)
- int fd;
- {
- return(lseek( get_ftab(fd, "sizef")->fdesc, 0L, SEEK_END));
- }
-
- /*
- * Read a record from a relative (sequential) file
- * using absolute positioning
- */
- void abs_get_rec(fd, offset, record_length, record)
- int fd,record_length;
- long offset;
- char *record;
- {
- int count;
- char *routine = "abs_get_rec";
- struct frec *fptr = get_ftab(fd, routine);
-
- /*
- statmsg("%s\nfd %d offset %ld\nrecord_length %d",
- routine, fd, offset, record_length);
- */
-
- if (lseek(fptr->fdesc, offset, SEEK_SET) == -1)
- {
- # ifdef FDEBUG
- ptab(routine);
- # endif
- abort_mess("%s(): Seek failed on %s", routine, fptr->name);
- }
-
- count = read(fptr->fdesc, record, record_length);
- if (count != record_length)
- {
- # ifdef FDEBUG
- ptab(routine);
- # endif
- abort_mess("%s(): Read %d bytes from %s, expected %d",
- routine, count, fptr->name, record_length);
- }
-
- # ifdef FDEBUGI
- fptr->nreads++;
- # endif
- }
-
- /*
- * Write a record to a relative (sequential) file
- * using absolute positioning
- */
- void abs_put_rec(fd, offset, record_length, record)
- int fd, record_length;
- long offset;
- char *record;
- {
- int count;
- char *routine = "abs_put_rec";
- struct frec *fptr = get_ftab(fd, routine);
-
- /*
- statmsg("%s\nfd %d offset %ld\nrecord_length %d",
- routine, fd, offset, record_length);
- */
-
- if (lseek(fptr->fdesc, offset, SEEK_SET) == -1)
- {
- # ifdef FDEBUG
- ptab(routine);
- # endif
- abort_mess("%s(): Seek failed on %s", routine, fptr->name);
- }
-
- count = write(fptr->fdesc, record, record_length);
- if (count != record_length)
- {
- # ifdef FDEBUG
- ptab(routine);
- # endif
- abort_mess("%s(): Wrote %d bytes to %s, expected %d",
- routine, count, fptr->name, record_length);
- }
-
- # ifdef FDEBUGI
- fptr->nwrites++;
- # endif
- }
-
- # ifdef FDEBUG
- void ptab(s)
- char *s;
- {
- int i;
-
- fprintf(stderr, "\n%s\n", s);
- for (i = 0; i < MAX_FILES; i++)
- dump_tabentry(i);
- fflush(stderr);
- }
-
- static void dump_tabentry(n)
- int n;
- {
- # ifndef FDEBUGI
- if (ftable[n].fdesc == -1)
- return;
- # endif
- fprintf(stderr, "%02d fd %02d : len %04d : mode %02d :",
- n, ftable[n].fdesc, ftable[n].len, ftable[n].mode);
- # ifdef FDEBUGI
- fprintf(stderr, " r%04d w%04d", ftable[n].nreads, ftable[n].nwrites);
- # endif
- /* Should put a check in this for NULL names */
- fprintf(stderr, " (%s)\n", ftable[n].name);
- }
- # endif
-
-