1 #include "lib.h"
2 #include <unistd.h>
3 #include <errno.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <stdlib.h>
7 #include "sys9.h"
8 #include "dir.h"
9
10
11 /*
12 * BUG: errno mapping
13 */
14
15 int
unlink(const char * path)16 unlink(const char *path)
17 {
18 int n, i, fd;
19 long long nn;
20 Dir *db1, *db2, nd;
21 Fdinfo *f;
22 char *p, newname[PATH_MAX], newelem[32];
23
24 /* if the file is already open, make it close-on-exec (and rename to qid) */
25 if((db1 = _dirstat(path)) == nil) {
26 _syserrno();
27 return -1;
28 }
29 fd = -1;
30 for(i=0, f = _fdinfo;i < OPEN_MAX; i++, f++) {
31 if((f->flags&FD_ISOPEN) && (db2=_dirfstat(i)) != nil) {
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 sprintf(newelem, "%8.8lx%8.8lx", (ulong)(db2->qid.path>>32), (ulong)db2->qid.path);
37 _nulldir(&nd);
38 nd.name = newelem;
39 if(_dirfwstat(i, &nd) < 0)
40 p = (char*)path;
41 else {
42 p = strrchr(path, '/');
43 if(p == 0)
44 p = newelem;
45 else {
46 memmove(newname, path, p-path);
47 newname[p-path] = '/';
48 strcpy(newname+(p-path)+1, newelem);
49 p = newname;
50 }
51 }
52 /* reopen remove on close */
53 fd = _OPEN(p, 64|(f->oflags));
54 if(fd < 0){
55 free(db2);
56 continue;
57 }
58 nn = _SEEK(i, 0, 1);
59 if(nn < 0)
60 nn = 0;
61 _SEEK(fd, nn, 0);
62 _DUP(fd, i);
63 _CLOSE(fd);
64 free(db1);
65 return 0;
66 }
67 free(db2);
68 }
69 }
70 n = 0;
71 if(fd == -1)
72 if((n=_REMOVE(path)) < 0)
73 _syserrno();
74 free(db1);
75 return n;
76 }
77