1 /****************************************************************
2 Copyright 1990 - 1997 by AT&T, Lucent Technologies and Bellcore.
3 
4 Permission to use, copy, modify, and distribute this software
5 and its documentation for any purpose and without fee is hereby
6 granted, provided that the above copyright notice appear in all
7 copies and that both that the copyright notice and this
8 permission notice and warranty disclaimer appear in supporting
9 documentation, and that the names of AT&T, Bell Laboratories,
10 Lucent or Bellcore or any of their entities not be used in
11 advertising or publicity pertaining to distribution of the
12 software without specific, written prior permission.
13 
14 AT&T, Lucent and Bellcore disclaim all warranties with regard to
15 this software, including all implied warranties of
16 merchantability and fitness.  In no event shall AT&T, Lucent or
17 Bellcore be liable for any special, indirect or consequential
18 damages or any damages whatsoever resulting from loss of use,
19 data or profits, whether in an action of contract, negligence or
20 other tortious action, arising out of or in connection with the
21 use or performance of this software.
22 ****************************************************************/
23 
24 #include <f2c_config.h>
25 #include "f2c.h"
26 #include "fio.h"
27 
28 #ifdef HAVE_FTRUNCATE
29 #include <unistd.h>
30 #endif
31 
32 #undef abs
33 #undef min
34 #undef max
35 #include "stdlib.h"
36 #include "string.h"
37 
f_end(alist * a)38 integer f_end(alist *a)
39 {
40 	unit *b;
41 	FILE *tf;
42 
43 	if(a->aunit>=MXUNIT || a->aunit<0) err(a->aerr,101,"endfile");
44 	b = &f__units[a->aunit];
45 	if(b->ufd==NULL) {
46 		char nbuf[10];
47 		sprintf(nbuf,"fort.%ld",(long)a->aunit);
48 		if (tf = fopen(nbuf, f__w_mode[0]))
49 			fclose(tf);
50 		return(0);
51 		}
52 	b->uend=1;
53 	return(b->useek ? t_runc(a) : 0);
54 }
55 
56 #if !defined(HAVE_FTRUNCATE)
57 static int
copy(FILE * from,register long len,FILE * to)58 copy(FILE *from, register long len, FILE *to)
59 {
60 	int len1;
61 	char buf[BUFSIZ];
62 
63 	while(fread(buf, len1 = len > BUFSIZ ? BUFSIZ : (int)len, 1, from)) {
64 		if (!fwrite(buf, len1, 1, to))
65 			return 1;
66 		if ((len -= len1) <= 0)
67 			break;
68 		}
69 	return 0;
70 }
71 #endif /* !HAVE_FTRUNCATE */
72 
73 int
t_runc(alist * a)74 t_runc(alist *a)
75 {
76 	OFF_T loc, len;
77 	unit *b;
78 	int rc;
79 	FILE *bf;
80 #if !defined(HAVE_FTRUNCATE)
81 	FILE *tf;
82 #endif
83 
84 	b = &f__units[a->aunit];
85 	if(b->url)
86 		return(0);	/*don't truncate direct files*/
87 	loc=FTELL(bf = b->ufd);
88 	FSEEK(bf,(OFF_T)0,SEEK_END);
89 	len=FTELL(bf);
90 	if (loc >= len || b->useek == 0)
91 		return(0);
92 #ifndef HAVE_FTRUNCATE
93 	if (b->ufnm == NULL)
94 		return 0;
95 	rc = 0;
96 	fclose(b->ufd);
97 	if (!loc) {
98 		if (!(bf = fopen(b->ufnm, f__w_mode[b->ufmt])))
99 			rc = 1;
100 		if (b->uwrt)
101 			b->uwrt = 1;
102 		goto done;
103 		}
104 	if (!(bf = fopen(b->ufnm, f__r_mode[0]))
105 	 || !(tf = tmpfile())) {
106 #ifdef NON_UNIX_STDIO
107  bad:
108 #endif
109 		rc = 1;
110 		goto done;
111 		}
112 	if (copy(bf, (long)loc, tf)) {
113  bad1:
114 		rc = 1;
115 		goto done1;
116 		}
117 	if (!(bf = freopen(b->ufnm, f__w_mode[0], bf)))
118 		goto bad1;
119 	rewind(tf);
120 	if (copy(tf, (long)loc, bf))
121 		goto bad1;
122 	b->uwrt = 1;
123 	b->urw = 2;
124 #ifdef NON_UNIX_STDIO
125 	if (b->ufmt) {
126 		fclose(bf);
127 		if (!(bf = fopen(b->ufnm, f__w_mode[3])))
128 			goto bad;
129 		FSEEK(bf,(OFF_T)0,SEEK_END);
130 		b->urw = 3;
131 		}
132 #endif
133 done1:
134 	fclose(tf);
135 done:
136 	f__cf = b->ufd = bf;
137 #else /* !HAVE_TRUNCATE */
138 	if (b->urw & 2)
139 		fflush(b->ufd); /* necessary on some Linux systems */
140 	rc = ftruncate(fileno(b->ufd), loc);
141 	/* The following FSEEK is unnecessary on some systems, */
142 	/* but should be harmless. */
143 	FSEEK(b->ufd, (OFF_T)0, SEEK_END);
144 #endif /* HAVE_TRUNCATE */
145 	if (rc)
146 		err(a->aerr,111,"endfile");
147 	return 0;
148 }
149