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