xref: /plan9/sys/src/ape/lib/ap/plan9/rename.c (revision 781103c4074deb8af160e8a0da2742ba6b29dc2b)
13e12c5d1SDavid du Colombier #include "lib.h"
23e12c5d1SDavid du Colombier #include <unistd.h>
33e12c5d1SDavid du Colombier #include <string.h>
43e12c5d1SDavid du Colombier #include <stdio.h>
53e12c5d1SDavid du Colombier #include <errno.h>
69a747e4fSDavid du Colombier #include <stdlib.h>
73e12c5d1SDavid du Colombier #include "sys9.h"
83e12c5d1SDavid du Colombier #include "dir.h"
93e12c5d1SDavid du Colombier 
103e12c5d1SDavid du Colombier int
rename(const char * from,const char * to)113e12c5d1SDavid du Colombier rename(const char *from, const char *to)
123e12c5d1SDavid du Colombier {
13*781103c4SDavid du Colombier 	int n;
143e12c5d1SDavid du Colombier 	char *f, *t;
15d3c05884SDavid du Colombier 	Dir *d, nd;
163e12c5d1SDavid du Colombier 
173e12c5d1SDavid du Colombier 	if(access(to, 0) >= 0){
183e12c5d1SDavid du Colombier 		if(_REMOVE(to) < 0){
193e12c5d1SDavid du Colombier 			_syserrno();
203e12c5d1SDavid du Colombier 			return -1;
213e12c5d1SDavid du Colombier 		}
223e12c5d1SDavid du Colombier 	}
239a747e4fSDavid du Colombier 	if((d = _dirstat(to)) != nil){
249a747e4fSDavid du Colombier 		free(d);
253e12c5d1SDavid du Colombier 		errno = EEXIST;
263e12c5d1SDavid du Colombier 		return -1;
273e12c5d1SDavid du Colombier 	}
289a747e4fSDavid du Colombier 	if((d = _dirstat(from)) == nil){
293e12c5d1SDavid du Colombier 		_syserrno();
303e12c5d1SDavid du Colombier 		return -1;
313e12c5d1SDavid du Colombier 	}
323e12c5d1SDavid du Colombier 	f = strrchr(from, '/');
333e12c5d1SDavid du Colombier 	t = strrchr(to, '/');
34*781103c4SDavid du Colombier 	f = f? f+1 : (char *)from;
35*781103c4SDavid du Colombier 	t = t? t+1 : (char *)to;
363e12c5d1SDavid du Colombier 	n = 0;
373e12c5d1SDavid du Colombier 	if(f-from==t-to && strncmp(from, to, f-from)==0){
383e12c5d1SDavid du Colombier 		/* from and to are in same directory (we miss some cases) */
39d3c05884SDavid du Colombier 		_nulldir(&nd);
40d3c05884SDavid du Colombier 		nd.name = t;
41d3c05884SDavid du Colombier 		if(_dirwstat(from, &nd) < 0){
423e12c5d1SDavid du Colombier 			_syserrno();
433e12c5d1SDavid du Colombier 			n = -1;
443e12c5d1SDavid du Colombier 		}
453e12c5d1SDavid du Colombier 	}else{
463e12c5d1SDavid du Colombier 		/* different directories: have to copy */
473e12c5d1SDavid du Colombier 		int ffd, tfd;
483e12c5d1SDavid du Colombier 		char buf[8192];
493e12c5d1SDavid du Colombier 
50*781103c4SDavid du Colombier 		tfd = -1;
513e12c5d1SDavid du Colombier 		if((ffd = _OPEN(from, 0)) < 0 ||
529a747e4fSDavid du Colombier 		   (tfd = _CREATE(to, 1, d->mode)) < 0){
533e12c5d1SDavid du Colombier 			_CLOSE(ffd);
543e12c5d1SDavid du Colombier 			_syserrno();
553e12c5d1SDavid du Colombier 			n = -1;
563e12c5d1SDavid du Colombier 		}
577dd7cddfSDavid du Colombier 		while(n>=0 && (n = _READ(ffd, buf, 8192)) > 0)
583e12c5d1SDavid du Colombier 			if(_WRITE(tfd, buf, n) != n){
593e12c5d1SDavid du Colombier 				_syserrno();
603e12c5d1SDavid du Colombier 				n = -1;
613e12c5d1SDavid du Colombier 			}
623e12c5d1SDavid du Colombier 		_CLOSE(ffd);
633e12c5d1SDavid du Colombier 		_CLOSE(tfd);
643e12c5d1SDavid du Colombier 		if(n>0)
653e12c5d1SDavid du Colombier 			n = 0;
667dd7cddfSDavid du Colombier 		if(n == 0) {
677dd7cddfSDavid du Colombier 			if(_REMOVE(from) < 0){
687dd7cddfSDavid du Colombier 				_syserrno();
697dd7cddfSDavid du Colombier 				return -1;
707dd7cddfSDavid du Colombier 			}
717dd7cddfSDavid du Colombier 		}
723e12c5d1SDavid du Colombier 	}
739a747e4fSDavid du Colombier 	free(d);
743e12c5d1SDavid du Colombier 	return n;
753e12c5d1SDavid du Colombier }
76