home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / forth / pfe-0.000 / pfe-0 / pfe-0.9.13 / src / filesub.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-17  |  5.0 KB  |  266 lines

  1. /*
  2.  * This file is part of the portable Forth environment written in ANSI C.
  3.  * Copyright (C) 1995  Dirk Uwe Zoller
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Library General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2 of the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13.  * See the GNU Library General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Library General Public
  16.  * License along with this library; if not, write to the Free
  17.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  * This file is version 0.9.13 of 17-July-95
  20.  * Check for the latest version of this package via anonymous ftp at
  21.  *    roxi.rz.fht-mannheim.de:/pub/languages/forth/pfe-VERSION.tar.gz
  22.  * or    sunsite.unc.edu:/pub/languages/forth/pfe-VERSION.tar.gz
  23.  * or    ftp.cygnus.com:/pub/forth/pfe-VERSION.tar.gz
  24.  *
  25.  * Please direct any comments via internet to
  26.  *    duz@roxi.rz.fht-mannheim.de.
  27.  * Thank You.
  28.  */
  29. /*
  30.  * filesub.c --- Subroutines for double number (64 Bit) arithmetics.
  31.  * (duz 16Jul93)
  32.  */
  33.  
  34. #include "forth.h"
  35. #include "support.h"
  36.  
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39.  
  40. #include "nonansi.h"
  41. #include "missing.h"
  42.  
  43. #if !defined HAVE_ACCESS
  44. int
  45. access (const char *fn, int how)
  46. {
  47. #if defined HAVE_STAT
  48.  
  49.   struct stat st;        /* version using stat() */
  50.  
  51.   if (stat (fn, &st) != 0)
  52.     return -1;
  53.   switch (how)
  54.     {
  55.     default:
  56.       return -1;
  57.     case F_OK:
  58.       return 0;
  59.     case R_OK:
  60.       return (st.st_mode & S_IREAD) ? 0 : -1;
  61.     case W_OK:
  62.       return (st.st_mode & S_IWRITE) ? 0 : -1;
  63.     case X_OK:
  64.       return (st.st_mode & S_IEXEC) ? 0 : -1;
  65.     }
  66.  
  67. #else
  68.  
  69.   FILE *f;            /* limited version using ANSI-C fopen() */
  70.  
  71.   switch (how)
  72.     {
  73.     default:
  74.       return -1;
  75.     case F_OK:
  76.     case R_OK:
  77.       if ((f = fopen (fn, "r")) == NULL)
  78.     return -1;
  79.       fclose (f);
  80.       return 0;
  81.     case W_OK:
  82.       if ((f = fopen (fn, "r+")) == NULL)
  83.     return -1;
  84.       fclose (f);
  85.       return 0;
  86.     case X_OK:
  87.       return -1;
  88.     }
  89.  
  90. #endif
  91. }
  92. #endif
  93.  
  94. long
  95. fsize (FILE * f)        /* Result: file length, -1 on error */
  96. {
  97. #if defined HAVE_FSTAT && defined HAVE_FILENO
  98.  
  99.   struct stat st;        /* version using fstat() */
  100.   int fh = fileno (f);
  101.  
  102.   if (fh < 0 || fstat (fh, &st) < 0)
  103.     return -1;
  104.   return st.st_size;
  105.  
  106. #else
  107.  
  108.   long pos, len;        /* ANSI-C version using fseek()/ftell() */
  109.  
  110.   clearerr (f);
  111.   pos = ftell (f);
  112.   if (pos == -1)
  113.     return -1;
  114.   if (fseek (f, 0, SEEK_END) != 0)
  115.     return -1;
  116.   len = ftell (f);
  117.   if (fseek (f, pos, SEEK_SET) != 0)
  118.     return -1;
  119.   return len;
  120.  
  121. #endif
  122. }
  123.  
  124. long
  125. size (const char *fn)        /* Result: file length, -1 on error */
  126. {
  127. #if defined HAVE_STAT
  128.  
  129.   struct stat st;
  130.  
  131.   if (stat (fn, &st) != 0)
  132.     return -1;
  133.   return st.st_size;
  134.  
  135. #else
  136.  
  137.   FILE *f;
  138.   long len;
  139.  
  140.   f = fopen (fn, "r");
  141.   if (f == NULL)
  142.     return -1;
  143.   len = fsize (f);
  144.   fclose (f);
  145.   return len;
  146.  
  147. #endif
  148. }
  149.  
  150. long
  151. copy (const char *src, const char *dst, long limit)
  152. /*
  153.  * Copies file, but at most limit characters.
  154.  * Returns destination file length if successful, -1 otherwise.
  155.  */
  156. {
  157.   FILE *f, *g;
  158.   char buf[BUFSIZ];
  159.   size_t n;
  160.   long m;
  161.  
  162.   if ((f = fopen (src, "rb")) == NULL)
  163.     return -1;
  164.   if ((g = fopen (dst, "wb")) == NULL)
  165.     {
  166.       fclose (f);
  167.       return -1;
  168.     }
  169.   for (m = limit; m; m -= n)
  170.     {
  171.       n = (size_t) (BUFSIZ < m ? BUFSIZ : m);
  172.       n = fread (buf, 1, n, f);
  173.       if (n == 0 || n != fwrite (buf, 1, n, g))
  174.     break;
  175.     }
  176.   n = ferror (f) || ferror (g);
  177.   fclose (f);
  178.   fclose (g);
  179.   return n ? -1 : limit - m;
  180. }
  181.  
  182. int
  183. move (const char *src, const char *dst)
  184. /*
  185.  * Renames or moves file, returns 0 on success, -1 on error.
  186.  */
  187. {
  188.   if (rename (src, dst) == 0)
  189.     return 0;
  190.   if (copy (src, dst, LONG_MAX) != -1)
  191.     {
  192.       return remove (src);
  193.     }
  194.   else
  195.     {
  196.       remove (dst);
  197.       return -1;
  198.     }
  199. }
  200.  
  201. static int
  202. fextend (FILE * f, long size)    /* make file longer */
  203. {
  204.   long n;
  205.  
  206.   if (fseek (f, 0, SEEK_END) != 0)
  207.     return -1;
  208.   for (n = ftell (f); n < size; n++)
  209.     if (putc (0, f) == EOF)
  210.       return -1;
  211.   return 0;
  212. }
  213.  
  214. static int
  215. extend (const char *fn, long size)
  216. {
  217.   FILE *f;
  218.   int result;
  219.  
  220.   f = fopen (fn, "ab");
  221.   if (f == NULL)
  222.     return -1;
  223.   result = fextend (f, size);
  224.   fclose (f);
  225.   return result;
  226. }
  227.  
  228. #ifndef HAVE_TRUNCATE
  229. int
  230. truncate (const char *path, long length)
  231. {
  232.   char tfn[L_tmpnam];
  233.   long len;
  234.  
  235.   tmpnam (tfn);
  236.   len = copy (path, tfn, length);
  237.   if (len == length && remove (path) == 0)
  238.     {
  239.       return move (tfn, path);
  240.     }
  241.   else
  242.     {
  243.       remove (tfn);
  244.       return 0;
  245.     }
  246. }
  247. #endif
  248.  
  249. int
  250. resize (const char *fn, long new_size)
  251. /*
  252.  * Truncates or extends file.
  253.  * Returns 0 if successful, -1 otherwise.
  254.  */
  255. {
  256.   long old_size;
  257.  
  258.   old_size = size (fn);
  259.   if (old_size == -1)
  260.     return -1;
  261.   if (old_size <= new_size)
  262.     return extend (fn, new_size);
  263.   else
  264.     return truncate (fn, new_size);
  265. }
  266.