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, i; 14 char *f, *t; 15 Dir *d; 16 long mode; 17 18 if(access(to, 0) >= 0){ 19 if(_REMOVE(to) < 0){ 20 _syserrno(); 21 return -1; 22 } 23 } 24 if((d = _dirstat(to)) != nil){ 25 free(d); 26 errno = EEXIST; 27 return -1; 28 } 29 if((d = _dirstat(from)) == nil){ 30 _syserrno(); 31 return -1; 32 } 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 d->name = t; 42 if(_dirwstat(from, d) < 0){ 43 _syserrno(); 44 n = -1; 45 } 46 }else{ 47 /* different directories: have to copy */ 48 int ffd, tfd; 49 char buf[8192]; 50 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