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