xref: /csrg-svn/usr.bin/f77/libI77/open.c (revision 36103)
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