1 #include "f2c.h"
2 #include "fio.h"
3 
4 /* Compile this with -DNO_TRUNCATE if unistd.h does not exist or */
5 /* if it does not define int truncate(const char *name, off_t). */
6 
7 /* [BL] */
8 #ifdef WIN32
9 #define MSDOS
10 #endif
11 
12 #ifdef MSDOS
13 #undef NO_TRUNCATE
14 #define NO_TRUNCATE
15 #endif
16 
17 #ifndef NO_TRUNCATE
18 #include "unistd.h"
19 #endif
20 
21 #ifdef KR_headers
22 extern char *strcpy();
23 extern FILE *tmpfile();
24 #else
25 #undef abs
26 #undef min
27 #undef max
28 #include "stdlib.h"
29 #include "string.h"
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 #endif
34 
35 extern char *f__r_mode[], *f__w_mode[];
36 
37 #ifdef KR_headers
f_end(a)38 integer f_end(a) alist *a;
39 #else
40 integer f_end(alist *a)
41 #endif
42 {
43 	unit *b;
44 	FILE *tf;
45 
46 	if(a->aunit>=MXUNIT || a->aunit<0) err(a->aerr,101,"endfile");
47 	b = &f__units[a->aunit];
48 	if(b->ufd==NULL) {
49 		char nbuf[10];
50 		sprintf(nbuf,"fort.%ld",(long)a->aunit);
51 		if (tf = FOPEN(nbuf, f__w_mode[0]))
52 			fclose(tf);
53 		return(0);
54 		}
55 	b->uend=1;
56 	return(b->useek ? t_runc(a) : 0);
57 }
58 
59 #ifdef NO_TRUNCATE
60  static int
61 #ifdef KR_headers
copy(from,len,to)62 copy(from, len, to) FILE *from, *to; register long len;
63 #else
64 copy(FILE *from, register long len, FILE *to)
65 #endif
66 {
67 	int len1;
68 	char buf[BUFSIZ];
69 
70 	while(fread(buf, len1 = len > BUFSIZ ? BUFSIZ : (int)len, 1, from)) {
71 		if (!fwrite(buf, len1, 1, to))
72 			return 1;
73 		if ((len -= len1) <= 0)
74 			break;
75 		}
76 	return 0;
77 	}
78 #endif /* NO_TRUNCATE */
79 
80  int
81 #ifdef KR_headers
t_runc(a)82 t_runc(a) alist *a;
83 #else
84 t_runc(alist *a)
85 #endif
86 {
87 	OFF_T loc, len;
88 	unit *b;
89 	int rc;
90 	FILE *bf;
91 #ifdef NO_TRUNCATE
92 	FILE *tf;
93 #endif
94 
95 	b = &f__units[a->aunit];
96 	if(b->url)
97 		return(0);	/*don't truncate direct files*/
98 	loc=FTELL(bf = b->ufd);
99 	FSEEK(bf,(OFF_T)0,SEEK_END);
100 	len=FTELL(bf);
101 	if (loc >= len || b->useek == 0)
102 		return(0);
103 #ifdef NO_TRUNCATE
104 	if (b->ufnm == NULL)
105 		return 0;
106 	rc = 0;
107 	fclose(b->ufd);
108 	if (!loc) {
109 		if (!(bf = FOPEN(b->ufnm, f__w_mode[b->ufmt])))
110 			rc = 1;
111 		if (b->uwrt)
112 			b->uwrt = 1;
113 		goto done;
114 		}
115 	if (!(bf = FOPEN(b->ufnm, f__r_mode[0]))
116 	 || !(tf = tmpfile())) {
117 #ifdef NON_UNIX_STDIO
118  bad:
119 #endif
120 		rc = 1;
121 		goto done;
122 		}
123 	if (copy(bf, (long)loc, tf)) {
124  bad1:
125 		rc = 1;
126 		goto done1;
127 		}
128 	if (!(bf = FREOPEN(b->ufnm, f__w_mode[0], bf)))
129 		goto bad1;
130 	rewind(tf);
131 	if (copy(tf, (long)loc, bf))
132 		goto bad1;
133 	b->uwrt = 1;
134 	b->urw = 2;
135 #ifdef NON_UNIX_STDIO
136 	if (b->ufmt) {
137 		fclose(bf);
138 		if (!(bf = FOPEN(b->ufnm, f__w_mode[3])))
139 			goto bad;
140 		FSEEK(bf,(OFF_T)0,SEEK_END);
141 		b->urw = 3;
142 		}
143 #endif
144 done1:
145 	fclose(tf);
146 done:
147 	f__cf = b->ufd = bf;
148 #else /* NO_TRUNCATE */
149 	if (b->urw & 2)
150 		fflush(b->ufd); /* necessary on some Linux systems */
151 #ifndef FTRUNCATE
152 #define FTRUNCATE ftruncate
153 #endif
154 	rc = FTRUNCATE(fileno(b->ufd), loc);
155 	/* The following FSEEK is unnecessary on some systems, */
156 	/* but should be harmless. */
157 	FSEEK(b->ufd, (OFF_T)0, SEEK_END);
158 #endif /* NO_TRUNCATE */
159 	if (rc)
160 		err(a->aerr,111,"endfile");
161 	return 0;
162 	}
163 #ifdef __cplusplus
164 }
165 #endif
166