|
|
1.1 root 1: /* trunc.c
2: Truncate a file to zero length. */
3:
4: #include "uucp.h"
5:
6: #include "uudefs.h"
7: #include "sysdep.h"
8: #include "system.h"
9:
10: #include <errno.h>
11:
12: #if HAVE_FCNTL_H
13: #include <fcntl.h>
14: #else
15: #if HAVE_SYS_FILE_H
16: #include <sys/file.h>
17: #endif
18: #endif
19:
20: #ifndef FD_CLOEXEC
21: #define FD_CLOEXEC 1
22: #endif
23:
24: #ifndef SEEK_SET
25: #define SEEK_SET 0
26: #endif
27:
28: /* External functions. */
29: #ifndef lseek
30: extern off_t lseek ();
31: #endif
32:
33: /* Truncate a file to zero length. If this fails, it closes and
34: removes the file. We support a number of different means of
35: truncation, which is probably a waste of time since this function
36: is currently only called when the 'f' protocol resends a file. */
37:
38: #if HAVE_FTRUNCATE
39: #undef HAVE_LTRUNC
40: #define HAVE_LTRUNC 0
41: #endif
42:
43: #if ! HAVE_FTRUNCATE && ! HAVE_LTRUNC
44: #ifdef F_CHSIZE
45: #define HAVE_F_CHSIZE 1
46: #else /* ! defined (F_CHSIZE) */
47: #ifdef F_FREESP
48: #define HAVE_F_FREESP 1
49: #endif /* defined (F_FREESP) */
50: #endif /* ! defined (F_CHSIZE) */
51: #endif /* ! HAVE_FTRUNCATE && ! HAVE_LTRUNC */
52:
53: openfile_t
54: esysdep_truncate (e, zname)
55: openfile_t e;
56: const char *zname;
57: {
58: int o;
59:
60: #if HAVE_FTRUNCATE || HAVE_LTRUNC || HAVE_F_CHSIZE || HAVE_F_FREESP
61: int itrunc;
62:
63: if (! ffilerewind (e))
64: {
65: ulog (LOG_ERROR, "rewind: %s", strerror (errno));
66: (void) ffileclose (e);
67: (void) remove (zname);
68: return EFILECLOSED;
69: }
70:
71: #if USE_STDIO
72: o = fileno (e);
73: #else
74: o = e;
75: #endif
76:
77: #if HAVE_FTRUNCATE
78: itrunc = ftruncate (o, 0);
79: #endif
80: #if HAVE_LTRUNC
81: itrunc = ltrunc (o, (long) 0, SEEK_SET);
82: #endif
83: #if HAVE_F_CHSIZE
84: itrunc = fcntl (o, F_CHSIZE, (off_t) 0);
85: #endif
86: #if HAVE_F_FREESP
87: /* This selection is based on an implementation of ftruncate by
88: [email protected] (William Kucharski). */
89: {
90: struct flock fl;
91:
92: fl.l_whence = 0;
93: fl.l_len = 0;
94: fl.l_start = 0;
95: fl.l_type = F_WRLCK;
96:
97: itrunc = fcntl (o, F_FREESP, &fl);
98: }
99: #endif
100:
101: if (itrunc != 0)
102: {
103: #if HAVE_FTRUNCATE
104: ulog (LOG_ERROR, "ftruncate: %s", strerror (errno));
105: #endif
106: #ifdef HAVE_LTRUNC
107: ulog (LOG_ERROR, "ltrunc: %s", strerror (errno));
108: #endif
109: #ifdef HAVE_F_CHSIZE
110: ulog (LOG_ERROR, "fcntl (F_CHSIZE): %s", strerror (errno));
111: #endif
112: #ifdef HAVE_F_FREESP
113: ulog (LOG_ERROR, "fcntl (F_FREESP): %s", strerror (errno));
114: #endif
115:
116: (void) ffileclose (e);
117: (void) remove (zname);
118: return EFILECLOSED;
119: }
120:
121: return e;
122: #else /* ! (HAVE_FTRUNCATE || HAVE_LTRUNC || HAVE_F_CHSIZE || HAVE_F_FREESP) */
123: (void) ffileclose (e);
124: (void) remove (zname);
125:
126: o = creat ((char *) zname, IPRIVATE_FILE_MODE);
127:
128: if (o == -1)
129: {
130: ulog (LOG_ERROR, "creat (%s): %s", zname, strerror (errno));
131: return EFILECLOSED;
132: }
133:
134: if (fcntl (o, F_SETFD, fcntl (o, F_GETFD, 0) | FD_CLOEXEC) < 0)
135: {
136: ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno));
137: (void) close (o);
138: return EFILECLOSED;
139: }
140:
141: #if USE_STDIO
142: e = fdopen (o, (char *) BINWRITE);
143:
144: if (e == NULL)
145: {
146: ulog (LOG_ERROR, "fdopen (%s): %s", zname, strerror (errno));
147: (void) close (o);
148: (void) remove (zname);
149: return NULL;
150: }
151: #else /* ! USE_STDIO */
152: e = o;
153: #endif /* ! USE_STDIO */
154:
155: return e;
156: #endif /* ! (HAVE_FTRUNCATE || HAVE_LTRUNC || HAVE_F_CHSIZE || HAVE_F_FREESP) */
157: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.