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]>> |