Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 1881 → Rev 1882

/programs/develop/libraries/menuetlibc/src/libc/ansi/stdio/rename.c
0,0 → 1,74
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
/* ------------------------- rename() for DJGPP -------------------------- */
 
/*
* An implementation of rename() which can move both files AND
* directories on the same filesystem (in the DOS world this means
* the same logical drive). Most cases are simply passed to the
* DOS Int 21h/AH=56h function. Special treatment is required for
* renaming (moving) directories which don't share their parent
* directory, because DOS won't allow this. This is called ``Prune
* and graft'' operation. Most of the code below handles this
* special case. It recursively creates subdirectories at the
* target path, moves regular files there, then deletes the (empty)
* directories at the source.
*
* An alternative (and much faster) implementation would be to access
* the parent directories of the source and the target at the disk
* sector level and rewrite them with BIOS calls. However, this won't
* work for networked drives and will leave the file system in an
* inconsistent state, should the machine crash before the operation
* is completed. (A hybrid approach which uses the fast method when
* possible and the slow one otherwise, is left as an exercise for the
* ambitious readers. ;-)
*/
 
#include <libc/stubs.h>
#include <libc/bss.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <io.h>
#include <sys/stat.h>
#include <dir.h>
#include <fcntl.h>
 
// \begin{diamond}[23.02.2007]
// this is the only solution allowed by existing Kolibri system functions
// it is better than nothing :)
// But renaming of large files will be time-consuming operation...
// and renaming of directories is impossible...
 
int rename(const char *old, const char *new)
{
int f1,f2;
char* data;
int bytes;
f1 = dosemu_open(old,O_RDONLY);
if (f1 < 0) {errno = ENOENT; return -1;}
f2 = dosemu_open(new,O_WRONLY|O_CREAT|O_EXCL);
if (f2 < 0) {dosemu_close(f1); errno = EACCES; return -1;}
data = malloc(32768);
if (!data) {dosemu_close(f2); dosemu_close(f1); errno = ENOMEM; return -1;}
do
{
bytes = dosemu_read(f1, data, 32768);
if (bytes >= 0)
bytes = dosemu_write(f2, data, bytes);
} while (bytes == 32768);
free(data);
dosemu_close(f2);
dosemu_close(f1);
if (bytes == -1)
{
errno = EACCES;
return -1;
}
remove(old);
return 0;
}
 
// \end{diamond}[23.02.2007]
Property changes:
Added: svn:executable
+*
\ No newline at end of property