home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / tar-1.11.8-src.tgz / tar.out / fsf / tar / lib / ftruncate.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  2KB  |  104 lines

  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.  
  13. int
  14. ftruncate (fd, length)
  15.      int fd;
  16.      off_t length;
  17. {
  18.   return fcntl (fd, F_CHSIZE, length);
  19. }
  20.  
  21. #else /* not F_CHSIZE */
  22. #ifdef F_FREESP
  23.  
  24. /* By William Kucharski <kucharsk@netcom.com>.  */
  25.  
  26. #include <sys/stat.h>
  27. #include <errno.h>
  28. #ifdef HAVE_UNISTD_H
  29. #include <unistd.h>
  30. #endif
  31.  
  32. int
  33. ftruncate (fd, length)
  34.      int fd;
  35.      off_t length;
  36. {
  37.   struct flock fl;
  38.   struct stat filebuf;
  39.  
  40.   if (fstat (fd, &filebuf) < 0)
  41.     return -1;
  42.  
  43.   if (filebuf.st_size < length)
  44.     {
  45.       /* Extend file length. */
  46.       if (lseek (fd, (length - 1), SEEK_SET) < 0)
  47.     return -1;
  48.  
  49.       /* Write a "0" byte. */
  50.       if (write (fd, "", 1) != 1)
  51.     return -1;
  52.     }
  53.   else
  54.     {
  55.  
  56.       /* Truncate length. */
  57.  
  58.       fl.l_whence = 0;
  59.       fl.l_len = 0;
  60.       fl.l_start = length;
  61.       fl.l_type = F_WRLCK;    /* write lock on file space */
  62.  
  63.       /* This relies on the *undocumented* F_FREESP argument to fcntl,
  64.      which truncates the file so that it ends at the position
  65.      indicated by fl.l_start.  Will minor miracles never cease?  */
  66.  
  67.       if (fcntl (fd, F_FREESP, &fl) < 0)
  68.     return -1;
  69.     }
  70.  
  71.   return 0;
  72. }
  73.  
  74. #else /* not F_CHSIZE nor F_FREESP */
  75. #ifdef HAVE_CHSIZE
  76.  
  77. int
  78. ftruncate (fd, length)
  79.      int fd;
  80.      off_t length;
  81. {
  82.   return chsize (fd, length);
  83. }
  84.  
  85. #else /* not F_CHSIZE nor F_FREESP nor HAVE_CHSIZE */
  86.  
  87. #include <errno.h>
  88. #ifndef errno
  89. extern int errno;
  90. #endif
  91.  
  92. int
  93. ftruncate (fd, length)
  94.      int fd;
  95.      off_t length;
  96. {
  97.   errno = EIO;
  98.   return -1;
  99. }
  100.  
  101. #endif /* not HAVE_CHSIZE */
  102. #endif /* not F_FREESP */
  103. #endif /* not F_CHSIZE */
  104.