Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}