/contrib/cvs/lib/ftruncate.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 76 lines · 55 code · 10 blank · 11 comment · 6 complexity · fe4829ce2a04af060c44368f073a2c48 MD5 · raw file

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