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