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