1 #include "config.h"
2 #include "f2c.h"
3 #include "fio.h"
4
5 #include <sys/types.h>
6 #include <unistd.h>
7
8 #undef abs
9 #undef min
10 #undef max
11 #include <stdlib.h>
12 #include <string.h>
13
14 extern char *f__r_mode[], *f__w_mode[];
15
16 integer
f_end(alist * a)17 f_end (alist * a)
18 {
19 unit *b;
20 FILE *tf;
21
22 if (f__init & 2)
23 f__fatal (131, "I/O recursion");
24 if (a->aunit >= MXUNIT || a->aunit < 0)
25 err (a->aerr, 101, "endfile");
26 b = &f__units[a->aunit];
27 if (b->ufd == NULL)
28 {
29 char nbuf[10];
30 sprintf (nbuf, "fort.%ld", (long) a->aunit);
31 if ((tf = fopen (nbuf, f__w_mode[0])))
32 fclose (tf);
33 return (0);
34 }
35 b->uend = 1;
36 return (b->useek ? t_runc (a) : 0);
37 }
38
39 #ifndef HAVE_FTRUNCATE
40 static int
copy(FILE * from,register long len,FILE * to)41 copy (FILE * from, register long len, FILE * to)
42 {
43 int len1;
44 char buf[BUFSIZ];
45
46 while (fread (buf, len1 = len > BUFSIZ ? BUFSIZ : (int) len, 1, from))
47 {
48 if (!fwrite (buf, len1, 1, to))
49 return 1;
50 if ((len -= len1) <= 0)
51 break;
52 }
53 return 0;
54 }
55 #endif /* !defined(HAVE_FTRUNCATE) */
56
57 int
t_runc(alist * a)58 t_runc (alist * a)
59 {
60 off_t loc, len;
61 unit *b;
62 int rc;
63 FILE *bf;
64 #ifndef HAVE_FTRUNCATE
65 FILE *tf;
66 #endif /* !defined(HAVE_FTRUNCATE) */
67
68 b = &f__units[a->aunit];
69 if (b->url)
70 return (0); /*don't truncate direct files */
71 loc = FTELL (bf = b->ufd);
72 FSEEK (bf, 0, SEEK_END);
73 len = FTELL (bf);
74 if (loc >= len || b->useek == 0 || b->ufnm == NULL)
75 return (0);
76 #ifndef HAVE_FTRUNCATE
77 rc = 0;
78 fclose (b->ufd);
79 if (!loc)
80 {
81 if (!(bf = fopen (b->ufnm, f__w_mode[b->ufmt])))
82 rc = 1;
83 if (b->uwrt)
84 b->uwrt = 1;
85 goto done;
86 }
87 if (!(bf = fopen (b->ufnm, f__r_mode[0])) || !(tf = tmpfile ()))
88 {
89 #ifdef NON_UNIX_STDIO
90 bad:
91 #endif
92 rc = 1;
93 goto done;
94 }
95 if (copy (bf, loc, tf))
96 {
97 bad1:
98 rc = 1;
99 goto done1;
100 }
101 if (!(bf = freopen (b->ufnm, f__w_mode[0], bf)))
102 goto bad1;
103 FSEEK (tf, 0, SEEK_SET);
104 if (copy (tf, loc, bf))
105 goto bad1;
106 b->uwrt = 1;
107 b->urw = 2;
108 #ifdef NON_UNIX_STDIO
109 if (b->ufmt)
110 {
111 fclose (bf);
112 if (!(bf = fopen (b->ufnm, f__w_mode[3])))
113 goto bad;
114 FSEEK (bf, 0, SEEK_END);
115 b->urw = 3;
116 }
117 #endif
118 done1:
119 fclose (tf);
120 done:
121 f__cf = b->ufd = bf;
122 #else /* !defined(HAVE_FTRUNCATE) */
123 fflush (b->ufd);
124 rc = ftruncate (fileno (b->ufd), loc);
125 FSEEK (bf, loc, SEEK_SET);
126 #endif /* !defined(HAVE_FTRUNCATE) */
127 if (rc)
128 err (a->aerr, 111, "endfile");
129 return 0;
130 }
131