1 #include "lib.h"
2 #include <unistd.h>
3 #include <string.h>
4 #include <stdio.h>
5 #include <errno.h>
6 #include <stdlib.h>
7 #include "sys9.h"
8 #include "dir.h"
9
10 int
rename(const char * from,const char * to)11 rename(const char *from, const char *to)
12 {
13 int n;
14 char *f, *t;
15 Dir *d, nd;
16
17 if(access(to, 0) >= 0){
18 if(_REMOVE(to) < 0){
19 _syserrno();
20 return -1;
21 }
22 }
23 if((d = _dirstat(to)) != nil){
24 free(d);
25 errno = EEXIST;
26 return -1;
27 }
28 if((d = _dirstat(from)) == nil){
29 _syserrno();
30 return -1;
31 }
32 f = strrchr(from, '/');
33 t = strrchr(to, '/');
34 f = f? f+1 : (char *)from;
35 t = t? t+1 : (char *)to;
36 n = 0;
37 if(f-from==t-to && strncmp(from, to, f-from)==0){
38 /* from and to are in same directory (we miss some cases) */
39 _nulldir(&nd);
40 nd.name = t;
41 if(_dirwstat(from, &nd) < 0){
42 _syserrno();
43 n = -1;
44 }
45 }else{
46 /* different directories: have to copy */
47 int ffd, tfd;
48 char buf[8192];
49
50 tfd = -1;
51 if((ffd = _OPEN(from, 0)) < 0 ||
52 (tfd = _CREATE(to, 1, d->mode)) < 0){
53 _CLOSE(ffd);
54 _syserrno();
55 n = -1;
56 }
57 while(n>=0 && (n = _READ(ffd, buf, 8192)) > 0)
58 if(_WRITE(tfd, buf, n) != n){
59 _syserrno();
60 n = -1;
61 }
62 _CLOSE(ffd);
63 _CLOSE(tfd);
64 if(n>0)
65 n = 0;
66 if(n == 0) {
67 if(_REMOVE(from) < 0){
68 _syserrno();
69 return -1;
70 }
71 }
72 }
73 free(d);
74 return n;
75 }
76