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