#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
#ifndef lseek
extern off_t lseek ();
#endif
#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
#ifdef F_FREESP
#define HAVE_F_FREESP 1
#endif
#endif
#endif
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
{
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
(void) ffileclose (e);
(void) remove (zname);
o = creat ((char *) zname, IPRIVATE_FILE_MODE);
if (o == -1)
{
ulog (LOG_ERROR, "creat during esysdep_truncate (%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
e = o;
#endif
return e;
#endif
}