xref: /plan9-contrib/sys/src/ape/lib/ap/plan9/unlink.c (revision 781103c4074deb8af160e8a0da2742ba6b29dc2b)
13e12c5d1SDavid du Colombier #include "lib.h"
23e12c5d1SDavid du Colombier #include <unistd.h>
33e12c5d1SDavid du Colombier #include <errno.h>
4219b2ee8SDavid du Colombier #include <stdio.h>
5219b2ee8SDavid du Colombier #include <string.h>
69a747e4fSDavid du Colombier #include <stdlib.h>
73e12c5d1SDavid du Colombier #include "sys9.h"
8219b2ee8SDavid du Colombier #include "dir.h"
9219b2ee8SDavid du Colombier 
103e12c5d1SDavid du Colombier 
113e12c5d1SDavid du Colombier /*
123e12c5d1SDavid du Colombier  * BUG: errno mapping
133e12c5d1SDavid du Colombier  */
143e12c5d1SDavid du Colombier 
153e12c5d1SDavid du Colombier int
unlink(const char * path)163e12c5d1SDavid du Colombier unlink(const char *path)
173e12c5d1SDavid du Colombier {
18219b2ee8SDavid du Colombier 	int n, i, fd;
19d9306527SDavid du Colombier 	long long nn;
203ff48bf5SDavid du Colombier 	Dir *db1, *db2, nd;
21219b2ee8SDavid du Colombier 	Fdinfo *f;
229a747e4fSDavid du Colombier  	char *p, newname[PATH_MAX], newelem[32];
233e12c5d1SDavid du Colombier 
24219b2ee8SDavid du Colombier 	/* if the file is already open, make it close-on-exec (and rename to qid) */
259a747e4fSDavid du Colombier 	if((db1 = _dirstat(path)) == nil) {
26219b2ee8SDavid du Colombier 		_syserrno();
27219b2ee8SDavid du Colombier 		return -1;
28219b2ee8SDavid du Colombier 	}
29219b2ee8SDavid du Colombier 	fd = -1;
30219b2ee8SDavid du Colombier 	for(i=0, f = _fdinfo;i < OPEN_MAX; i++, f++) {
319a747e4fSDavid du Colombier 		if((f->flags&FD_ISOPEN) && (db2=_dirfstat(i)) != nil) {
329a747e4fSDavid du Colombier 			if(db1->qid.path == db2->qid.path &&
339a747e4fSDavid du Colombier 			   db1->qid.vers == db2->qid.vers &&
349a747e4fSDavid du Colombier 			   db1->type == db2->type &&
359a747e4fSDavid du Colombier 			   db1->dev == db2->dev) {
363ff48bf5SDavid du Colombier 				sprintf(newelem, "%8.8lx%8.8lx", (ulong)(db2->qid.path>>32), (ulong)db2->qid.path);
373ff48bf5SDavid du Colombier 				_nulldir(&nd);
383ff48bf5SDavid du Colombier 				nd.name = newelem;
393ff48bf5SDavid du Colombier 				if(_dirfwstat(i, &nd) < 0)
407dd7cddfSDavid du Colombier 					p = (char*)path;
417dd7cddfSDavid du Colombier 				else {
42219b2ee8SDavid du Colombier 					p = strrchr(path, '/');
43219b2ee8SDavid du Colombier 					if(p == 0)
449a747e4fSDavid du Colombier 						p = newelem;
45219b2ee8SDavid du Colombier 					else {
463ff48bf5SDavid du Colombier 						memmove(newname, path, p-path);
473ff48bf5SDavid du Colombier 						newname[p-path] = '/';
483ff48bf5SDavid du Colombier 						strcpy(newname+(p-path)+1, newelem);
497dd7cddfSDavid du Colombier 						p = newname;
50219b2ee8SDavid du Colombier 					}
517dd7cddfSDavid du Colombier 				}
527dd7cddfSDavid du Colombier 				/* reopen remove on close */
537dd7cddfSDavid du Colombier 				fd = _OPEN(p, 64|(f->oflags));
549a747e4fSDavid du Colombier 				if(fd < 0){
559a747e4fSDavid du Colombier 					free(db2);
56219b2ee8SDavid du Colombier 					continue;
579a747e4fSDavid du Colombier 				}
58d9306527SDavid du Colombier 				nn = _SEEK(i, 0, 1);
59d9306527SDavid du Colombier 				if(nn < 0)
60d9306527SDavid du Colombier 					nn = 0;
61d9306527SDavid du Colombier 				_SEEK(fd, nn, 0);
62219b2ee8SDavid du Colombier 				_DUP(fd, i);
63219b2ee8SDavid du Colombier 				_CLOSE(fd);
649a747e4fSDavid du Colombier 				free(db1);
65219b2ee8SDavid du Colombier 				return 0;
66219b2ee8SDavid du Colombier 			}
679a747e4fSDavid du Colombier 			free(db2);
68219b2ee8SDavid du Colombier 		}
69219b2ee8SDavid du Colombier 	}
70*781103c4SDavid du Colombier 	n = 0;
71219b2ee8SDavid du Colombier 	if(fd == -1)
723e12c5d1SDavid du Colombier 		if((n=_REMOVE(path)) < 0)
733e12c5d1SDavid du Colombier 			_syserrno();
749a747e4fSDavid du Colombier 	free(db1);
753e12c5d1SDavid du Colombier 	return n;
763e12c5d1SDavid du Colombier }
77