+
+ public class HostDirFD extends DirFD {
+ private final File f;
+ private final File[] children;
+ public HostDirFD(File f) { this.f = f; children = f.listFiles(); }
+ public int size() { return children.length; }
+ public String name(int n) { return children[n].getName(); }
+ public int inode(int n) { return inodes.get(children[n].getAbsolutePath()); }
+ public int parentInode() {
+ File parent = f.getParentFile();
+ return parent == null ? -1 : inodes.get(parent.getAbsolutePath());
+ }
+ public int myInode() { return inodes.get(f.getAbsolutePath()); }
+ public int myDev() { return devno; }
+ }
+ }
+
+ private static void putInt(byte[] buf, int off, int n) {
+ buf[off+0] = (byte)((n>>>24)&0xff);
+ buf[off+1] = (byte)((n>>>16)&0xff);
+ buf[off+2] = (byte)((n>>> 8)&0xff);
+ buf[off+3] = (byte)((n>>> 0)&0xff);
+ }
+
+ public static abstract class DirFD extends FD {
+ private int pos = -2;
+
+ protected abstract int size();
+ protected abstract String name(int n);
+ protected abstract int inode(int n);
+ protected abstract int myDev();
+ protected int parentInode() { return -1; }
+ protected int myInode() { return -1; }
+
+ public int getdents(byte[] buf, int off, int len) {
+ int ooff = off;
+ int ino;
+ int reclen;
+ OUTER: for(;len > 0 && pos < size();pos++){
+ switch(pos) {
+ case -2:
+ case -1:
+ ino = pos == -1 ? parentInode() : myInode();
+ if(ino == -1) continue;
+ reclen = 9 + (pos == -1 ? 2 : 1);
+ if(reclen > len) break OUTER;
+ buf[off+8] = '.';
+ if(pos == -1) buf[off+9] = '.';
+ break;
+ default: {
+ String f = name(pos);
+ byte[] fb = getBytes(f);
+ reclen = fb.length + 9;
+ if(reclen > len) break OUTER;
+ ino = inode(pos);
+ System.arraycopy(fb,0,buf,off+8,fb.length);
+ }
+ }
+ buf[off+reclen-1] = 0; // null terminate
+ reclen = (reclen + 3) & ~3; // add padding
+ putInt(buf,off,reclen);
+ putInt(buf,off+4,ino);
+ off += reclen;
+ len -= reclen;
+ }
+ return off-ooff;
+ }
+
+ protected FStat _fstat() {
+ return new FStat() {
+ public int type() { return S_IFDIR; }
+ public int inode() { return myInode(); }
+ public int dev() { return myDev(); }
+ };
+ }