]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - gnu/libexec/uucp/libunix/trunc.c
unfinished sblive driver, playback/mixer only for now - not enabled in
[FreeBSD/FreeBSD.git] / gnu / libexec / uucp / libunix / trunc.c
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 \f
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      kucharsk@Solbourne.com (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 }