12498Sdlw /* 223083Skre * Copyright (c) 1980 Regents of the University of California. 323083Skre * All rights reserved. The Berkeley software License Agreement 423083Skre * specifies the terms and conditions for redistribution. 52498Sdlw * 6*36103Sbostic * @(#)open.c 5.3 10/24/88 723083Skre */ 823083Skre 923083Skre /* 1020984Slibs * open.c - f77 file open and I/O library initialization routines 112498Sdlw */ 122498Sdlw 132498Sdlw #include <sys/types.h> 142498Sdlw #include <sys/stat.h> 152498Sdlw #include <errno.h> 162498Sdlw #include "fio.h" 172498Sdlw 182498Sdlw #define SCRATCH (st=='s') 192498Sdlw #define NEW (st=='n') 202498Sdlw #define OLD (st=='o') 212498Sdlw #define OPEN (b->ufd) 2212104Sdlw #define FROM_OPEN "\2" /* for use in f_clos() */ 2319962Slibs #define BUF_LEN 256 242498Sdlw 2520984Slibs LOCAL char *tmplate = "tmp.FXXXXXX"; /* scratch file template */ 2620984Slibs LOCAL char *fortfile = "fort.%d"; /* default file template */ 272498Sdlw 2819962Slibs char *getenv(); 2919962Slibs 302498Sdlw f_open(a) olist *a; 312498Sdlw { unit *b; 32*36103Sbostic struct stat sbuf; 332498Sdlw int n,exists; 3419962Slibs char buf[BUF_LEN], env_name[BUF_LEN]; 3519962Slibs char *env_val, *p1, *p2, ch, st; 362498Sdlw cllist x; 372498Sdlw 382498Sdlw lfname = NULL; 392498Sdlw elist = NO; 402498Sdlw external = YES; /* for err */ 412498Sdlw errflag = a->oerr; 422498Sdlw lunit = a->ounit; 432597Sdlw if(not_legal(lunit)) err(errflag,F_ERUNIT,"open") 442498Sdlw b= &units[lunit]; 452498Sdlw if(a->osta) st = lcase(*a->osta); 462498Sdlw else st = 'u'; 472498Sdlw if(SCRATCH) 482498Sdlw { strcpy(buf,tmplate); 4925768Sjerry /* make a new temp file name, err if mktemp fails */ 5025768Sjerry if( strcmp( mktemp(buf), "/" ) == 0 ) 5125768Sjerry err(errflag, F_ERSYS, "open") 522498Sdlw } 5319962Slibs else 5419962Slibs { 5519962Slibs if(a->ofnm) g_char(a->ofnm,a->ofnmlen,buf); 5619962Slibs else sprintf(buf,fortfile,lunit); 5719962Slibs /* check if overriding file name via environment variable 5819962Slibs * first copy tail of name - delete periods as Bourne Shell 5919962Slibs * croaks if any periods in name 6019962Slibs */ 6119962Slibs p1 = buf; 6219962Slibs p2 = env_name; 6319962Slibs while ((ch = *p1++) != '\0') { 6419962Slibs if(ch == '/') p2 = env_name; 6519962Slibs else if(ch != '.') *p2++ = ch; 6619962Slibs } 6719962Slibs if(p2 != env_name) { 6819962Slibs *p2 = '\0'; 6919962Slibs if( (env_val = getenv( env_name )) != NULL ) { 7019962Slibs if(strlen(env_val) >= BUF_LEN-1 ) 7119962Slibs err(errflag,F_ERSTAT,"open: file name too long"); 7219962Slibs strcpy(buf, env_val); 7319962Slibs } 7419962Slibs } 7519962Slibs } 762498Sdlw lfname = &buf[0]; 772498Sdlw if(OPEN) 782498Sdlw { 792498Sdlw if(!a->ofnm || inode(buf)==b->uinode) 802498Sdlw { 812498Sdlw if(a->oblnk) b->ublnk= (lcase(*a->oblnk)== 'z'); 822498Sdlw #ifndef KOSHER 832498Sdlw if(a->ofm && b->ufmt) b->uprnt = (lcase(*a->ofm)== 'p'); 842498Sdlw #endif 852498Sdlw return(OK); 862498Sdlw } 872498Sdlw x.cunit=lunit; 882498Sdlw x.csta=FROM_OPEN; 892498Sdlw x.cerr=errflag; 902498Sdlw if(n=f_clos(&x)) return(n); 912498Sdlw } 92*36103Sbostic exists = (stat(buf,&sbuf)==NULL); 932597Sdlw if(!exists && OLD) err(errflag,F_EROLDF,"open"); 942597Sdlw if( exists && NEW) err(errflag,F_ERNEWF,"open"); 9519962Slibs errno = F_ERSYS; 962498Sdlw if(isdev(buf)) 972498Sdlw { if((b->ufd = fopen(buf,"r")) != NULL) b->uwrt = NO; 982498Sdlw else err(errflag,errno,buf) 992498Sdlw } 1002498Sdlw else 101*36103Sbostic { 10219962Slibs errno = F_ERSYS; 10319962Slibs if((b->ufd = fopen(buf, "a")) != NULL) 10412036Sdlw { if(!opneof) 10512010Sdlw { if(freopen(buf, "r", b->ufd) != NULL) 10612010Sdlw b->uwrt = NO; 10712010Sdlw else 10812010Sdlw err(errflag, errno, buf) 10912010Sdlw } 11012010Sdlw else 11112010Sdlw b->uwrt = YES; 11212010Sdlw } 1132498Sdlw else if((b->ufd = fopen(buf, "r")) != NULL) 11412036Sdlw { if (opneof) 11511907Sdlw fseek(b->ufd, 0L, 2); 1162498Sdlw b->uwrt = NO; 1172498Sdlw } 1182498Sdlw else err(errflag, errno, buf) 1192498Sdlw } 1202597Sdlw if((b->uinode=finode(b->ufd))==-1) err(errflag,F_ERSTAT,"open") 1212498Sdlw b->ufnm = (char *) calloc(strlen(buf)+1,sizeof(char)); 1222597Sdlw if(b->ufnm==NULL) err(errflag,F_ERSPACE,"open") 1232498Sdlw strcpy(b->ufnm,buf); 1242498Sdlw b->uscrtch = SCRATCH; 1252498Sdlw b->uend = NO; 1262498Sdlw b->useek = canseek(b->ufd); 1278943Sdlw if (a->oacc == NULL) 1288943Sdlw a->oacc = "seq"; 1298943Sdlw if (lcase(*a->oacc)=='s' && a->orl > 0) 1308943Sdlw { 1316604Sdlw fputs("Warning: open: record length ignored on sequential access\n", units[0].ufd); 1328943Sdlw b->url = 0; 1338943Sdlw } 1348943Sdlw else if (a->orl < 0 || (lcase(*a->oacc)=='d' && a->orl == 0)) 1356604Sdlw err(errflag,F_ERARG,"recl on open") 1366604Sdlw else 1376604Sdlw b->url = a->orl; 13812008Sdlw if (a->oblnk) 13912008Sdlw b->ublnk = (lcase(*a->oblnk)=='z'); 14012008Sdlw else if (lunit == STDERR) 14112008Sdlw b->ublnk = NO; 14212008Sdlw else 14312024Sdlw b->ublnk = blzero; 1442498Sdlw if (a->ofm) 1452498Sdlw { 1462498Sdlw switch(lcase(*a->ofm)) 1472498Sdlw { 1482498Sdlw case 'f': 1492498Sdlw b->ufmt = YES; 1502498Sdlw b->uprnt = NO; 1512498Sdlw break; 1522498Sdlw #ifndef KOSHER 1532498Sdlw case 'p': /* print file *** NOT STANDARD FORTRAN ***/ 1542498Sdlw b->ufmt = YES; 1552498Sdlw b->uprnt = YES; 1562498Sdlw break; 1572498Sdlw #endif 1582498Sdlw case 'u': 1592498Sdlw b->ufmt = NO; 1602498Sdlw b->uprnt = NO; 1612498Sdlw break; 1622498Sdlw default: 1632597Sdlw err(errflag,F_ERARG,"open form=") 1642498Sdlw } 1652498Sdlw } 1662498Sdlw else /* not specified */ 1672498Sdlw { b->ufmt = (b->url==0); 16812008Sdlw if (lunit == STDERR) 16912008Sdlw b->uprnt = NO; 17012008Sdlw else 17112024Sdlw b->uprnt = ccntrl; 1722498Sdlw } 1732498Sdlw if(b->url && b->useek) rewind(b->ufd); 1742498Sdlw return(OK); 1752498Sdlw } 1762498Sdlw 1772498Sdlw fk_open(rd,seq,fmt,n) ftnint n; 1782498Sdlw { char nbuf[10]; 1792498Sdlw olist a; 1802498Sdlw sprintf(nbuf, fortfile, (int)n); 1812498Sdlw a.oerr=errflag; 1822498Sdlw a.ounit=n; 1832498Sdlw a.ofnm=nbuf; 1842498Sdlw a.ofnmlen=strlen(nbuf); 1852498Sdlw a.osta=NULL; 1862498Sdlw a.oacc= seq==SEQ?"s":"d"; 1872498Sdlw a.ofm = fmt==FMT?"f":"u"; 1882498Sdlw a.orl = seq==DIR?1:0; 1892498Sdlw a.oblnk=NULL; 1902498Sdlw return(f_open(&a)); 1912498Sdlw } 1922498Sdlw 19320984Slibs LOCAL 1942498Sdlw isdev(s) char *s; 1952498Sdlw { struct stat x; 1962498Sdlw int j; 1972498Sdlw if(stat(s, &x) == -1) return(NO); 1982498Sdlw if((j = (x.st_mode&S_IFMT)) == S_IFREG || j == S_IFDIR) return(NO); 1992498Sdlw else return(YES); 2002498Sdlw } 2012498Sdlw 20220984Slibs /*initialization routine*/ 20320984Slibs f_init() 20420984Slibs { 20520984Slibs ini_std(STDERR, stderr, WRITE); 20620984Slibs ini_std(STDIN, stdin, READ); 20720984Slibs ini_std(STDOUT, stdout, WRITE); 20820984Slibs setlinebuf(stderr); 20920984Slibs } 21020984Slibs 21120984Slibs LOCAL 21220984Slibs ini_std(u,F,w) FILE *F; 21320984Slibs { unit *p; 21420984Slibs p = &units[u]; 21520984Slibs p->ufd = F; 21620984Slibs p->ufnm = NULL; 21720984Slibs p->useek = canseek(F); 21820984Slibs p->ufmt = YES; 21920984Slibs p->uwrt = (w==WRITE)? YES : NO; 22020984Slibs p->uscrtch = p->uend = NO; 22120984Slibs p->ublnk = blzero; 22220984Slibs p->uprnt = ccntrl; 22320984Slibs p->url = 0; 22420984Slibs p->uinode = finode(F); 22520984Slibs } 22620984Slibs 22720984Slibs LOCAL 22820984Slibs canseek(f) FILE *f; /*SYSDEP*/ 22920984Slibs { struct stat x; 23020984Slibs return( (fstat(fileno(f),&x)==0) && 23120984Slibs (x.st_nlink > 0 /*!pipe*/) && !isatty(fileno(f)) ); 23220984Slibs } 23320984Slibs 23420984Slibs LOCAL 23520984Slibs finode(f) FILE *f; 23620984Slibs { struct stat x; 23720984Slibs if(fstat(fileno(f),&x)==0) return(x.st_ino); 23820984Slibs else return(-1); 23920984Slibs } 24020984Slibs 24120984Slibs inode(a) char *a; 24220984Slibs { struct stat x; 24320984Slibs if(stat(a,&x)==0) return(x.st_ino); 24420984Slibs else return(-1); 24520984Slibs } 246