From f89d273c01e149c574f57e329fa4d58aba71812d Mon Sep 17 00:00:00 2001 From: David Crawshaw Date: Sat, 30 Jun 2007 03:34:40 -0700 Subject: [PATCH] support unlink before close (from Joe Wilson) darcs-hash:20070630103440-0c629-4f1eec911ced256699d8278ef038e7f8fb073561.gz --- src/org/ibex/nestedvm/Runtime.java | 18 +++++++++++++----- src/org/ibex/nestedvm/UnixRuntime.java | 30 +++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/org/ibex/nestedvm/Runtime.java b/src/org/ibex/nestedvm/Runtime.java index 8e6b5f0..161e3a9 100644 --- a/src/org/ibex/nestedvm/Runtime.java +++ b/src/org/ibex/nestedvm/Runtime.java @@ -698,18 +698,18 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { return i; } - /** Hook for subclasses to do something when the process closes an FD */ - void _closedFD(FD fd) { } + /** Hooks for subclasses before and after the process closes an FD */ + void _preCloseFD(FD fd) { } + void _postCloseFD(FD fd) { } /** Closes file descriptor fdn and removes it from the file descriptor table */ public final boolean closeFD(int fdn) { if(state == EXITED || state == EXECED) throw new IllegalStateException("closeFD called in inappropriate state"); if(fdn < 0 || fdn >= OPEN_MAX) return false; if(fds[fdn] == null) return false; - - _closedFD(fds[fdn]); - + _preCloseFD(fds[fdn]); fds[fdn].close(); + _postCloseFD(fds[fdn]); fds[fdn] = null; return true; } @@ -1209,6 +1209,14 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { /** File Descriptor class */ public static abstract class FD { private int refCount = 1; + private String normalizedPath = null; + private boolean deleteOnClose = false; + + public void setNormalizedPath(String path) { normalizedPath = path; } + public String getNormalizedPath() { return normalizedPath; } + + public void markDeleteOnClose() { deleteOnClose = true; } + public boolean isMarkedForDeleteOnClose() { return deleteOnClose; } /** Read some bytes. Should return the number of bytes read, 0 on EOF, or throw an IOException on error */ public int read(byte[] a, int off, int length) throws ErrnoException { throw new ErrnoException(EBADFD); } diff --git a/src/org/ibex/nestedvm/UnixRuntime.java b/src/org/ibex/nestedvm/UnixRuntime.java index 0291ab8..fed82d0 100644 --- a/src/org/ibex/nestedvm/UnixRuntime.java +++ b/src/org/ibex/nestedvm/UnixRuntime.java @@ -164,7 +164,10 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { } FD _open(String path, int flags, int mode) throws ErrnoException { - return gs.open(this,normalizePath(path),flags,mode); + path = normalizePath(path); + FD fd = gs.open(this,path,flags,mode); + if (fd != null && path != null) fd.setNormalizedPath(path); + return fd; } private int sys_getppid() { @@ -703,7 +706,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { return n; } - void _closedFD(FD fd) { + void _preCloseFD(FD fd) { // release all fcntl locks on this file Seekable s = fd.seekable(); if (s == null) return; @@ -720,6 +723,13 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { } catch (IOException e) { throw new RuntimeException(e); } } + void _postCloseFD(FD fd) { + if (fd.isMarkedForDeleteOnClose()) { + try { gs.unlink(this, fd.getNormalizedPath()); } + catch (Throwable t) {} + } + } + /** Implements the F_GETLK and F_SETLK cases of fcntl syscall. * If l_start = 0 and l_len = 0 the lock refers to the entire file. * Uses GlobalState to ensure locking across processes in the same JVM. @@ -1617,7 +1627,21 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { File f = hostFile(path); if(r.sm != null && !r.sm.allowUnlink(f)) throw new ErrnoException(EPERM); if(!f.exists()) throw new ErrnoException(ENOENT); - if(!f.delete()) throw new ErrnoException(EPERM); + if(!f.delete()) { + // Can't delete file immediately, so mark for + // delete on close all matching FDs + boolean marked = false; + for(int i=0;i