Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1882 clevermous 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 
28
#include 
29
#include 
30
#include 
31
#include 
32
#include 
33
#include 
34
#include 
35
#include 
36
#include 
37
#include 
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]