xref: /plan9-contrib/sys/src/ape/lib/ap/plan9/unlink.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include "lib.h"
2 #include <unistd.h>
3 #include <errno.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include "sys9.h"
7 #include "dir.h"
8 
9 
10 /*
11  * BUG: errno mapping
12  */
13 
14 int
15 unlink(const char *path)
16 {
17 	int n, i, fd;
18 	Dir db1, db2;
19 	Fdinfo *f;
20  	char *p, cd[DIRLEN], newname[PATH_MAX];
21 
22 	/* if the file is already open, make it close-on-exec (and rename to qid) */
23 	if(_STAT(path, cd) < 0){
24 		_syserrno();
25 		return -1;
26 	}
27 	convM2D(cd, &db1);
28 	fd = -1;
29 	for(i=0, f = _fdinfo;i < OPEN_MAX; i++, f++) {
30 		if((f->flags&FD_ISOPEN) && _FSTAT(i, cd) >= 0) {
31 			convM2D(cd, &db2);
32 			if(db1.qid.path == db2.qid.path &&
33 			   db1.qid.vers == db2.qid.vers &&
34 			   db1.type == db2.type &&
35 			   db1.dev == db2.dev) {
36 				memset(db2.name, 0, NAMELEN);
37 				sprintf(db2.name, "%.8x", db2.qid.path);
38 				convD2M(&db2, cd);
39 				if(_FWSTAT(i, cd) < 0)
40 					continue;
41 				/* reopen remove on close */
42 				p = strrchr(path, '/');
43 				if(p == 0)
44 					fd = _OPEN(db2.name, 64|(f->oflags));
45 				else {
46 					*p = '\0';
47 					sprintf(newname, "%s/%.8x", path, db2.qid.path);
48 					fd = _OPEN(newname, 64|(f->oflags));
49 				}
50 				if (fd < 0)
51 					continue;
52 				n = _SEEK(i, 0, 1);
53 				if (n < 0)
54 					n = 0;
55 				_SEEK(fd, n, 0);
56 				_DUP(fd, i);
57 				_CLOSE(fd);
58 				return 0;
59 			}
60 		}
61 	}
62 	if(fd == -1)
63 		if((n=_REMOVE(path)) < 0)
64 			_syserrno();
65 	return n;
66 }
67