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