View Javadoc

1   // UnixFileSystem.java, created Thu Jul  4  4:50:03 2002 by joewhaley
2   // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
4   package joeq.ClassLib.Common.java.io;
5   
6   import joeq.Bootstrap.MethodInvocation;
7   import joeq.Class.PrimordialClassLoader;
8   import joeq.Class.jq_Class;
9   import joeq.Class.jq_DontAlign;
10  import joeq.Class.jq_Method;
11  import joeq.Class.jq_NameAndDesc;
12  import joeq.Main.jq;
13  import joeq.Memory.Address;
14  import joeq.Memory.CodeAddress;
15  import joeq.Memory.HeapAddress;
16  import joeq.Runtime.SystemInterface;
17  import joeq.Runtime.Unsafe;
18  import joeq.Runtime.SystemInterface.ExternalLink;
19  import joeq.Runtime.SystemInterface.Library;
20  import jwutil.util.Assert;
21  
22  /***
23   * UnixFileSystem
24   *
25   * @author John Whaley <jwhaley@alum.mit.edu>
26   * @version $Id: UnixFileSystem.java 1941 2004-09-30 03:37:06Z joewhaley $
27   */
28  public abstract class UnixFileSystem {
29  
30      public long getLength(java.io.File file) {
31          return SystemInterface.fs_stat_size(file.getPath());
32      }
33  
34      public boolean delete(java.io.File file) {
35          int res = SystemInterface.fs_remove(file.getPath());
36          return res == 0;
37      }
38  
39      public long getLastModifiedTime(java.io.File file) {
40          long res = SystemInterface.fs_getfiletime(file.getPath());
41          return res;
42      }
43  
44      public boolean rename(java.io.File file, java.io.File file1) {
45          int res = SystemInterface.fs_rename(file.getPath(), file1.getPath());
46          return res == 0;
47      }
48  
49      public String[] list(java.io.File file) {
50          int dir = SystemInterface.fs_opendir(file.getPath());
51          if (dir == 0) return null;
52          String[] s = new String[16];
53          int i;
54          Address ptr;
55          for (i=0; !(ptr=SystemInterface.fs_readdir(dir)).isNull(); ++i) {
56              if (i == s.length) {
57                  String[] s2 = new String[s.length<<1];
58                  System.arraycopy(s, 0, s2, 0, s.length);
59                  s = s2;
60              }
61              s[i] = SystemInterface.fromCString(ptr.offset(SystemInterface.readdir_name_offset));
62              if (s[i].equals(".") || s[i].equals("..")) --i;
63          }
64          SystemInterface.fs_closedir(dir);
65          String[] ret = new String[i];
66          System.arraycopy(s, 0, ret, 0, i);
67          return ret;
68      }
69  
70      public boolean createDirectory(java.io.File file) {
71          int res = SystemInterface.fs_mkdir(file.getPath());
72          return res == 0;
73      }
74  
75      public boolean setLastModifiedTime(java.io.File file, long l) {
76          int res = SystemInterface.fs_setfiletime(file.getPath(), l);
77          return res != 0;
78      }
79  
80      public String canonicalize(String s) throws java.io.IOException {
81          // TODO.
82          return s;
83      }
84  
85      /* from bits/stat.h on Redhat 9 */
86      public static class linux_stat extends SystemInterface.Stat implements jq_DontAlign {
87          long /*dev_t    */ st_dev;      /* device */
88          int __pad1;
89          int  /*ino_t    */ st_ino;      /* inode */
90          int  /*mode_t   */ st_mode;     /* protection */
91          int  /*nlink_t  */ st_nlink;    /* number of hard links */
92          int  /*uid_t    */ st_uid;      /* user ID of owner */
93          int  /*gid_t    */ st_gid;      /* group ID of owner */
94          long /*dev_t    */ st_rdev;     /* device type (if inode device) */
95          int __pad2;
96          int  /*off_t    */ st_size;     /* total size, in bytes */
97          int  /*blksize_t*/ st_blksize;  /* blocksize for filesystem I/O */
98          int  /*blkcnt_t */ st_blocks;   /* number of blocks allocated */
99          int  /*time_t   */ st_atime;    /* time of last access */
100         int __unused1;
101         int  /*time_t   */ st_mtime;    /* time of last modification */
102         int __unused2;
103         int  /*time_t   */ st_ctime;    /* time of last change */
104         int __unused3;
105         int __unused4;
106         int __unused5;
107         
108         public String toString() {
109             StringBuffer sb = new StringBuffer();
110             sb.append("{st_dev="); sb.append(st_dev);
111             sb.append(",st_ino="); sb.append(st_ino);
112             sb.append(",st_mode="); sb.append(st_mode);
113             sb.append(",st_nlink="); sb.append(st_nlink);
114             sb.append(",st_uid="); sb.append(st_uid);
115             sb.append(",st_gid="); sb.append(st_gid);
116             sb.append(",st_rdev="); sb.append(st_rdev);
117             sb.append(",st_size="); sb.append(st_size);
118             sb.append(",st_blksize="); sb.append(st_blksize);
119             sb.append(",st_blocks="); sb.append(st_blocks);
120             sb.append(",st_atime="); sb.append(st_atime);
121             sb.append(",st_mtime="); sb.append(st_mtime);
122             sb.append(",st_ctime="); sb.append(st_ctime);
123             sb.append('}');
124             return sb.toString();
125         }
126     }
127     /* Flags for st_mode field, from man page: */
128     static final int S_IFMT = 0170000;  //bitmask for the file type bitfields
129     static final int S_IFSOCK = 0140000;//socket
130     static final int S_IFLNK = 0120000; //symbolic link
131     static final int S_IFREG = 0100000; //regular file
132     static final int S_IFBLK = 0060000; //block device
133     static final int S_IFDIR = 0040000; //directory
134     static final int S_IFCHR = 0020000; //character device
135     static final int S_IFIFO = 0010000; //fifo
136     static final int S_ISUID = 0004000; //set UID bit
137     static final int S_ISGID = 0002000; //set GID bit (see below)
138     static final int S_ISVTX = 0001000; //sticky bit (see below)
139     static final int S_IRWXU = 00700;   //mask for file owner permissions
140     static final int S_IRUSR = 00400;   //owner has read permission
141     static final int S_IWUSR = 00200;   //owner has write permission
142     static final int S_IXUSR = 00100;   //owner has execute permission
143     static final int S_IRWXG = 00070;   //mask for group permissions
144     static final int S_IRGRP = 00040;   //group has read permission
145     static final int S_IWGRP = 00020;   //group has write permission
146     static final int S_IXGRP = 00010;   //group has execute permission
147     static final int S_IRWXO = 00007;   //mask for permissions for others (not in group)
148     static final int S_IROTH = 00004;   //others have read permission
149     static final int S_IWOTH = 00002;   //others have write permisson
150     static final int S_IXOTH = 00001;   //others have execute permission
151 
152     // Copied from FileSystem.java
153     public static final int BA_EXISTS    = 0x01;
154     public static final int BA_REGULAR   = 0x02;
155     public static final int BA_DIRECTORY = 0x04;
156     public static final int BA_HIDDEN    = 0x08;
157 
158     public int getBooleanAttributes0(java.io.File file) {
159         linux_stat s = new linux_stat();
160         int res = SystemInterface.file_stat(file.getPath(), s);
161         if (res != 0) return 0;
162         int result = BA_EXISTS;
163         if ((s.st_mode & S_IFDIR) != 0) result |= BA_DIRECTORY;
164         if ((s.st_mode & S_IFREG) != 0) result |= BA_REGULAR;
165         // hidden is handled by the caller.
166         return result;
167     }
168 
169     static final int R_OK = 4;
170     static final int W_OK = 2;
171     static final int X_OK = 1;
172     static final int F_OK = 0;
173 
174     public static int access(String fn, int mode) {
175         if (_access == null) return -1;
176         byte[] filename = SystemInterface.toCString(fn);
177         try {
178             CodeAddress a = _access.resolve();
179             Unsafe.pushArg(mode);
180             HeapAddress b = HeapAddress.addressOf(filename);
181             Unsafe.pushArgA(b);
182             Unsafe.getThreadBlock().disableThreadSwitch();
183             int rc = (int) Unsafe.invoke(a);
184             Unsafe.getThreadBlock().enableThreadSwitch();
185             return rc;
186         } catch (Throwable x) { Assert.UNREACHABLE(); }
187         return 0;
188     }
189 
190     public static /*final*/ ExternalLink _access;
191 
192     public boolean checkAccess(java.io.File file, boolean flag) {
193         int f = flag ? W_OK : R_OK;
194         int res = access(file.getPath(), f);
195         return res == 0;
196     }
197     /*
198     public native boolean createFileExclusively(String s)
199         throws IOException;
200     public synchronized native boolean deleteOnExit(File file);
201     public native boolean setReadOnly(File file);
202     */
203 
204     static {
205         if (jq.RunningNative) boot();
206         else if (jq.on_vm_startup != null) {
207             jq_Class c = (jq_Class) PrimordialClassLoader.loader.getOrCreateBSType("Ljava/io/UnixFileSystem;");
208             jq_Method m = c.getDeclaredStaticMethod(new jq_NameAndDesc("boot", "()V"));
209             MethodInvocation mi = new MethodInvocation(m, null);
210             jq.on_vm_startup.add(mi);
211         }
212     }
213 
214     public static void boot() {
215         Library c = SystemInterface.registerLibrary("libc.so.6");
216 
217         if (c != null) {
218             _access = c.resolve("access");
219         } else {
220             _access = null;
221         }
222 
223     }
224 
225     private static void initIDs() { }
226     
227     //public static final jq_Class _class = (jq_Class)PrimordialClassLoader.loader.getOrCreateBSType("Ljava/io/UnixFileSystem;");
228     //public static final jq_Initializer _constructor = (jq_Initializer)_class.getOrCreateInstanceMethod("<init>", "()V");
229 }