unlink.c 1.5 KB

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