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