1 /* ftruncate emulations that work on some System V's. 2 This file is in the public domain. */ 3 4 #ifdef HAVE_CONFIG_H 5 #include "config.h" 6 #endif 7 8 #include <sys/types.h> 9 #include <fcntl.h> 10 11 #ifdef F_CHSIZE 12 int 13 ftruncate (fd, length) 14 int fd; 15 off_t length; 16 { 17 return fcntl (fd, F_CHSIZE, length); 18 } 19 #else 20 #ifdef F_FREESP 21 /* The following function was written by 22 kucharsk@Solbourne.com (William Kucharski) */ 23 24 #include <sys/stat.h> 25 #include <errno.h> 26 #include <unistd.h> 27 28 int 29 ftruncate (fd, length) 30 int fd; 31 off_t length; 32 { 33 struct flock fl; 34 struct stat filebuf; 35 36 if (fstat (fd, &filebuf) < 0) 37 return -1; 38 39 if (filebuf.st_size < length) 40 { 41 /* Extend file length. */ 42 if (lseek (fd, (length - 1), SEEK_SET) < 0) 43 return -1; 44 45 /* Write a "0" byte. */ 46 if (write (fd, "", 1) != 1) 47 return -1; 48 } 49 else 50 { 51 /* Truncate length. */ 52 fl.l_whence = 0; 53 fl.l_len = 0; 54 fl.l_start = length; 55 fl.l_type = F_WRLCK; /* Write lock on file space. */ 56 57 /* This relies on the UNDOCUMENTED F_FREESP argument to 58 fcntl, which truncates the file so that it ends at the 59 position indicated by fl.l_start. 60 Will minor miracles never cease? */ 61 if (fcntl (fd, F_FREESP, &fl) < 0) 62 return -1; 63 } 64 65 return 0; 66 } 67 #else 68 int 69 ftruncate (fd, length) 70 int fd; 71 off_t length; 72 { 73 return chsize (fd, length); 74 } 75 #endif 76 #endif 77