1*47943Sbostic /*-
2*47943Sbostic * Copyright (c) 1980 The Regents of the University of California.
3*47943Sbostic * All rights reserved.
42498Sdlw *
5*47943Sbostic * %sccs.include.proprietary.c%
623083Skre */
723083Skre
8*47943Sbostic #ifndef lint
9*47943Sbostic static char sccsid[] = "@(#)open.c 5.4 (Berkeley) 04/12/91";
10*47943Sbostic #endif /* not lint */
11*47943Sbostic
1223083Skre /*
1320984Slibs * open.c - f77 file open and I/O library initialization routines
142498Sdlw */
152498Sdlw
162498Sdlw #include <sys/types.h>
172498Sdlw #include <sys/stat.h>
182498Sdlw #include <errno.h>
192498Sdlw #include "fio.h"
202498Sdlw
212498Sdlw #define SCRATCH (st=='s')
222498Sdlw #define NEW (st=='n')
232498Sdlw #define OLD (st=='o')
242498Sdlw #define OPEN (b->ufd)
2512104Sdlw #define FROM_OPEN "\2" /* for use in f_clos() */
2619962Slibs #define BUF_LEN 256
272498Sdlw
2820984Slibs LOCAL char *tmplate = "tmp.FXXXXXX"; /* scratch file template */
2920984Slibs LOCAL char *fortfile = "fort.%d"; /* default file template */
302498Sdlw
3119962Slibs char *getenv();
3219962Slibs
f_open(a)332498Sdlw f_open(a) olist *a;
342498Sdlw { unit *b;
3536103Sbostic struct stat sbuf;
362498Sdlw int n,exists;
3719962Slibs char buf[BUF_LEN], env_name[BUF_LEN];
3819962Slibs char *env_val, *p1, *p2, ch, st;
392498Sdlw cllist x;
402498Sdlw
412498Sdlw lfname = NULL;
422498Sdlw elist = NO;
432498Sdlw external = YES; /* for err */
442498Sdlw errflag = a->oerr;
452498Sdlw lunit = a->ounit;
462597Sdlw if(not_legal(lunit)) err(errflag,F_ERUNIT,"open")
472498Sdlw b= &units[lunit];
482498Sdlw if(a->osta) st = lcase(*a->osta);
492498Sdlw else st = 'u';
502498Sdlw if(SCRATCH)
512498Sdlw { strcpy(buf,tmplate);
5225768Sjerry /* make a new temp file name, err if mktemp fails */
5325768Sjerry if( strcmp( mktemp(buf), "/" ) == 0 )
5425768Sjerry err(errflag, F_ERSYS, "open")
552498Sdlw }
5619962Slibs else
5719962Slibs {
5819962Slibs if(a->ofnm) g_char(a->ofnm,a->ofnmlen,buf);
5919962Slibs else sprintf(buf,fortfile,lunit);
6019962Slibs /* check if overriding file name via environment variable
6119962Slibs * first copy tail of name - delete periods as Bourne Shell
6219962Slibs * croaks if any periods in name
6319962Slibs */
6419962Slibs p1 = buf;
6519962Slibs p2 = env_name;
6619962Slibs while ((ch = *p1++) != '\0') {
6719962Slibs if(ch == '/') p2 = env_name;
6819962Slibs else if(ch != '.') *p2++ = ch;
6919962Slibs }
7019962Slibs if(p2 != env_name) {
7119962Slibs *p2 = '\0';
7219962Slibs if( (env_val = getenv( env_name )) != NULL ) {
7319962Slibs if(strlen(env_val) >= BUF_LEN-1 )
7419962Slibs err(errflag,F_ERSTAT,"open: file name too long");
7519962Slibs strcpy(buf, env_val);
7619962Slibs }
7719962Slibs }
7819962Slibs }
792498Sdlw lfname = &buf[0];
802498Sdlw if(OPEN)
812498Sdlw {
822498Sdlw if(!a->ofnm || inode(buf)==b->uinode)
832498Sdlw {
842498Sdlw if(a->oblnk) b->ublnk= (lcase(*a->oblnk)== 'z');
852498Sdlw #ifndef KOSHER
862498Sdlw if(a->ofm && b->ufmt) b->uprnt = (lcase(*a->ofm)== 'p');
872498Sdlw #endif
882498Sdlw return(OK);
892498Sdlw }
902498Sdlw x.cunit=lunit;
912498Sdlw x.csta=FROM_OPEN;
922498Sdlw x.cerr=errflag;
932498Sdlw if(n=f_clos(&x)) return(n);
942498Sdlw }
9536103Sbostic exists = (stat(buf,&sbuf)==NULL);
962597Sdlw if(!exists && OLD) err(errflag,F_EROLDF,"open");
972597Sdlw if( exists && NEW) err(errflag,F_ERNEWF,"open");
9819962Slibs errno = F_ERSYS;
992498Sdlw if(isdev(buf))
1002498Sdlw { if((b->ufd = fopen(buf,"r")) != NULL) b->uwrt = NO;
1012498Sdlw else err(errflag,errno,buf)
1022498Sdlw }
1032498Sdlw else
10436103Sbostic {
10519962Slibs errno = F_ERSYS;
10619962Slibs if((b->ufd = fopen(buf, "a")) != NULL)
10712036Sdlw { if(!opneof)
10812010Sdlw { if(freopen(buf, "r", b->ufd) != NULL)
10912010Sdlw b->uwrt = NO;
11012010Sdlw else
11112010Sdlw err(errflag, errno, buf)
11212010Sdlw }
11312010Sdlw else
11412010Sdlw b->uwrt = YES;
11512010Sdlw }
1162498Sdlw else if((b->ufd = fopen(buf, "r")) != NULL)
11712036Sdlw { if (opneof)
11811907Sdlw fseek(b->ufd, 0L, 2);
1192498Sdlw b->uwrt = NO;
1202498Sdlw }
1212498Sdlw else err(errflag, errno, buf)
1222498Sdlw }
1232597Sdlw if((b->uinode=finode(b->ufd))==-1) err(errflag,F_ERSTAT,"open")
1242498Sdlw b->ufnm = (char *) calloc(strlen(buf)+1,sizeof(char));
1252597Sdlw if(b->ufnm==NULL) err(errflag,F_ERSPACE,"open")
1262498Sdlw strcpy(b->ufnm,buf);
1272498Sdlw b->uscrtch = SCRATCH;
1282498Sdlw b->uend = NO;
1292498Sdlw b->useek = canseek(b->ufd);
1308943Sdlw if (a->oacc == NULL)
1318943Sdlw a->oacc = "seq";
1328943Sdlw if (lcase(*a->oacc)=='s' && a->orl > 0)
1338943Sdlw {
1346604Sdlw fputs("Warning: open: record length ignored on sequential access\n", units[0].ufd);
1358943Sdlw b->url = 0;
1368943Sdlw }
1378943Sdlw else if (a->orl < 0 || (lcase(*a->oacc)=='d' && a->orl == 0))
1386604Sdlw err(errflag,F_ERARG,"recl on open")
1396604Sdlw else
1406604Sdlw b->url = a->orl;
14112008Sdlw if (a->oblnk)
14212008Sdlw b->ublnk = (lcase(*a->oblnk)=='z');
14312008Sdlw else if (lunit == STDERR)
14412008Sdlw b->ublnk = NO;
14512008Sdlw else
14612024Sdlw b->ublnk = blzero;
1472498Sdlw if (a->ofm)
1482498Sdlw {
1492498Sdlw switch(lcase(*a->ofm))
1502498Sdlw {
1512498Sdlw case 'f':
1522498Sdlw b->ufmt = YES;
1532498Sdlw b->uprnt = NO;
1542498Sdlw break;
1552498Sdlw #ifndef KOSHER
1562498Sdlw case 'p': /* print file *** NOT STANDARD FORTRAN ***/
1572498Sdlw b->ufmt = YES;
1582498Sdlw b->uprnt = YES;
1592498Sdlw break;
1602498Sdlw #endif
1612498Sdlw case 'u':
1622498Sdlw b->ufmt = NO;
1632498Sdlw b->uprnt = NO;
1642498Sdlw break;
1652498Sdlw default:
1662597Sdlw err(errflag,F_ERARG,"open form=")
1672498Sdlw }
1682498Sdlw }
1692498Sdlw else /* not specified */
1702498Sdlw { b->ufmt = (b->url==0);
17112008Sdlw if (lunit == STDERR)
17212008Sdlw b->uprnt = NO;
17312008Sdlw else
17412024Sdlw b->uprnt = ccntrl;
1752498Sdlw }
1762498Sdlw if(b->url && b->useek) rewind(b->ufd);
1772498Sdlw return(OK);
1782498Sdlw }
1792498Sdlw
fk_open(rd,seq,fmt,n)1802498Sdlw fk_open(rd,seq,fmt,n) ftnint n;
1812498Sdlw { char nbuf[10];
1822498Sdlw olist a;
1832498Sdlw sprintf(nbuf, fortfile, (int)n);
1842498Sdlw a.oerr=errflag;
1852498Sdlw a.ounit=n;
1862498Sdlw a.ofnm=nbuf;
1872498Sdlw a.ofnmlen=strlen(nbuf);
1882498Sdlw a.osta=NULL;
1892498Sdlw a.oacc= seq==SEQ?"s":"d";
1902498Sdlw a.ofm = fmt==FMT?"f":"u";
1912498Sdlw a.orl = seq==DIR?1:0;
1922498Sdlw a.oblnk=NULL;
1932498Sdlw return(f_open(&a));
1942498Sdlw }
1952498Sdlw
19620984Slibs LOCAL
isdev(s)1972498Sdlw isdev(s) char *s;
1982498Sdlw { struct stat x;
1992498Sdlw int j;
2002498Sdlw if(stat(s, &x) == -1) return(NO);
2012498Sdlw if((j = (x.st_mode&S_IFMT)) == S_IFREG || j == S_IFDIR) return(NO);
2022498Sdlw else return(YES);
2032498Sdlw }
2042498Sdlw
20520984Slibs /*initialization routine*/
f_init()20620984Slibs f_init()
20720984Slibs {
20820984Slibs ini_std(STDERR, stderr, WRITE);
20920984Slibs ini_std(STDIN, stdin, READ);
21020984Slibs ini_std(STDOUT, stdout, WRITE);
21120984Slibs setlinebuf(stderr);
21220984Slibs }
21320984Slibs
21420984Slibs LOCAL
ini_std(u,F,w)21520984Slibs ini_std(u,F,w) FILE *F;
21620984Slibs { unit *p;
21720984Slibs p = &units[u];
21820984Slibs p->ufd = F;
21920984Slibs p->ufnm = NULL;
22020984Slibs p->useek = canseek(F);
22120984Slibs p->ufmt = YES;
22220984Slibs p->uwrt = (w==WRITE)? YES : NO;
22320984Slibs p->uscrtch = p->uend = NO;
22420984Slibs p->ublnk = blzero;
22520984Slibs p->uprnt = ccntrl;
22620984Slibs p->url = 0;
22720984Slibs p->uinode = finode(F);
22820984Slibs }
22920984Slibs
23020984Slibs LOCAL
canseek(f)23120984Slibs canseek(f) FILE *f; /*SYSDEP*/
23220984Slibs { struct stat x;
23320984Slibs return( (fstat(fileno(f),&x)==0) &&
23420984Slibs (x.st_nlink > 0 /*!pipe*/) && !isatty(fileno(f)) );
23520984Slibs }
23620984Slibs
23720984Slibs LOCAL
finode(f)23820984Slibs finode(f) FILE *f;
23920984Slibs { struct stat x;
24020984Slibs if(fstat(fileno(f),&x)==0) return(x.st_ino);
24120984Slibs else return(-1);
24220984Slibs }
24320984Slibs
inode(a)24420984Slibs inode(a) char *a;
24520984Slibs { struct stat x;
24620984Slibs if(stat(a,&x)==0) return(x.st_ino);
24720984Slibs else return(-1);
24820984Slibs }
249