Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  2. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  3. /* ------------------------- rename() for DJGPP -------------------------- */
  4.  
  5. /*
  6.  *  An implementation of rename() which can move both files AND
  7.  *  directories on the same filesystem (in the DOS world this means
  8.  *  the same logical drive).  Most cases are simply passed to the
  9.  *  DOS Int 21h/AH=56h function.  Special treatment is required for
  10.  *  renaming (moving) directories which don't share their parent
  11.  *  directory, because DOS won't allow this.  This is called ``Prune
  12.  *  and graft'' operation.  Most of the code below handles this
  13.  *  special case.  It recursively creates subdirectories at the
  14.  *  target path, moves regular files there, then deletes the (empty)
  15.  *  directories at the source.
  16.  *
  17.  *  An alternative (and much faster) implementation would be to access
  18.  *  the parent directories of the source and the target at the disk
  19.  *  sector level and rewrite them with BIOS calls.  However, this won't
  20.  *  work for networked drives and will leave the file system in an
  21.  *  inconsistent state, should the machine crash before the operation
  22.  *  is completed.  (A hybrid approach which uses the fast method when
  23.  *  possible and the slow one otherwise, is left as an exercise for the
  24.  *  ambitious readers. ;-)
  25.  */
  26.  
  27. #include <libc/stubs.h>
  28. #include <libc/bss.h>
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <stdlib.h>
  32. #include <ctype.h>
  33. #include <errno.h>
  34. #include <io.h>
  35. #include <sys/stat.h>
  36. #include <dir.h>
  37. #include <fcntl.h>
  38.  
  39. // \begin{diamond}[23.02.2007]
  40. // this is the only solution allowed by existing Kolibri system functions
  41. // it is better than nothing :)
  42. // But renaming of large files will be time-consuming operation...
  43. // and renaming of directories is impossible...
  44.  
  45. int rename(const char *old, const char *new)
  46. {
  47.         int f1,f2;
  48.         char* data;
  49.         int bytes;
  50.         f1 = dosemu_open(old,O_RDONLY);
  51.         if (f1 < 0) {errno = ENOENT; return -1;}
  52.         f2 = dosemu_open(new,O_WRONLY|O_CREAT|O_EXCL);
  53.         if (f2 < 0) {dosemu_close(f1); errno = EACCES; return -1;}
  54.         data = malloc(32768);
  55.         if (!data) {dosemu_close(f2); dosemu_close(f1); errno = ENOMEM; return -1;}
  56.         do
  57.         {
  58.                 bytes = dosemu_read(f1, data, 32768);
  59.                 if (bytes >= 0)
  60.                         bytes = dosemu_write(f2, data, bytes);
  61.         } while (bytes == 32768);
  62.         free(data);
  63.         dosemu_close(f2);
  64.         dosemu_close(f1);
  65.         if (bytes == -1)
  66.         {
  67.                 errno = EACCES;
  68.                 return -1;
  69.         }
  70.         remove(old);
  71.         return 0;
  72. }
  73.  
  74. // \end{diamond}[23.02.2007]
  75.