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