• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
3   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4   *
5   * This code is free software; you can redistribute it and/or modify it
6   * under the terms of the GNU General Public License version 2 only, as
7   * published by the Free Software Foundation.  Oracle designates this
8   * particular file as subject to the "Classpath" exception as provided
9   * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package sun.nio.fs;
27  
28  import java.security.AccessController;
29  import java.security.PrivilegedAction;
30  
31  /**
32   * Unix system and library calls.
33   */
34  
35  class UnixNativeDispatcher {
UnixNativeDispatcher()36      protected UnixNativeDispatcher() { }
37  
38      // returns a NativeBuffer containing the given path
copyToNativeBuffer(UnixPath path)39      private static NativeBuffer copyToNativeBuffer(UnixPath path) {
40          byte[] cstr = path.getByteArrayForSysCalls();
41          int size = cstr.length + 1;
42          NativeBuffer buffer = NativeBuffers.getNativeBufferFromCache(size);
43          if (buffer == null) {
44              buffer = NativeBuffers.allocNativeBuffer(size);
45          } else {
46              // buffer already contains the path
47              if (buffer.owner() == path)
48                  return buffer;
49          }
50          NativeBuffers.copyCStringToNativeBuffer(cstr, buffer);
51          buffer.setOwner(path);
52          return buffer;
53      }
54  
55      /**
56       * char *getcwd(char *buf, size_t size);
57       */
getcwd()58      static native byte[] getcwd();
59  
60      /**
61       * int dup(int filedes)
62       */
dup(int filedes)63      static native int dup(int filedes) throws UnixException;
64  
65      /**
66       * int open(const char* path, int oflag, mode_t mode)
67       */
open(UnixPath path, int flags, int mode)68      static int open(UnixPath path, int flags, int mode) throws UnixException {
69          NativeBuffer buffer = copyToNativeBuffer(path);
70          try {
71              return open0(buffer.address(), flags, mode);
72          } finally {
73              buffer.release();
74          }
75      }
open0(long pathAddress, int flags, int mode)76      private static native int open0(long pathAddress, int flags, int mode)
77          throws UnixException;
78  
79      /**
80       * int openat(int dfd, const char* path, int oflag, mode_t mode)
81       */
openat(int dfd, byte[] path, int flags, int mode)82      static int openat(int dfd, byte[] path, int flags, int mode) throws UnixException {
83          NativeBuffer buffer = NativeBuffers.asNativeBuffer(path);
84          try {
85              return openat0(dfd, buffer.address(), flags, mode);
86          } finally {
87              buffer.release();
88          }
89      }
openat0(int dfd, long pathAddress, int flags, int mode)90      private static native int openat0(int dfd, long pathAddress, int flags, int mode)
91          throws UnixException;
92  
93      /**
94       * close(int filedes)
95       */
close(int fd)96      static native void close(int fd);
97  
98      /**
99       * FILE* fopen(const char *filename, const char* mode);
100       */
fopen(UnixPath filename, String mode)101      static long fopen(UnixPath filename, String mode) throws UnixException {
102          NativeBuffer pathBuffer = copyToNativeBuffer(filename);
103          NativeBuffer modeBuffer = NativeBuffers.asNativeBuffer(Util.toBytes(mode));
104          try {
105              return fopen0(pathBuffer.address(), modeBuffer.address());
106          } finally {
107              modeBuffer.release();
108              pathBuffer.release();
109          }
110      }
fopen0(long pathAddress, long modeAddress)111      private static native long fopen0(long pathAddress, long modeAddress)
112          throws UnixException;
113  
114      /**
115       * fclose(FILE* stream)
116       */
fclose(long stream)117      static native void fclose(long stream) throws UnixException;
118  
119      /**
120       * link(const char* existing, const char* new)
121       */
link(UnixPath existing, UnixPath newfile)122      static void link(UnixPath existing, UnixPath newfile) throws UnixException {
123          NativeBuffer existingBuffer = copyToNativeBuffer(existing);
124          NativeBuffer newBuffer = copyToNativeBuffer(newfile);
125          try {
126              link0(existingBuffer.address(), newBuffer.address());
127          } finally {
128              newBuffer.release();
129              existingBuffer.release();
130          }
131      }
link0(long existingAddress, long newAddress)132      private static native void link0(long existingAddress, long newAddress)
133          throws UnixException;
134  
135      /**
136       * unlink(const char* path)
137       */
unlink(UnixPath path)138      static void unlink(UnixPath path) throws UnixException {
139          NativeBuffer buffer = copyToNativeBuffer(path);
140          try {
141              unlink0(buffer.address());
142          } finally {
143              buffer.release();
144          }
145      }
unlink0(long pathAddress)146      private static native void unlink0(long pathAddress) throws UnixException;
147  
148      /**
149       * unlinkat(int dfd, const char* path, int flag)
150       */
unlinkat(int dfd, byte[] path, int flag)151      static void unlinkat(int dfd, byte[] path, int flag) throws UnixException {
152          NativeBuffer buffer = NativeBuffers.asNativeBuffer(path);
153          try {
154              unlinkat0(dfd, buffer.address(), flag);
155          } finally {
156              buffer.release();
157          }
158      }
unlinkat0(int dfd, long pathAddress, int flag)159      private static native void unlinkat0(int dfd, long pathAddress, int flag)
160          throws UnixException;
161  
162      /**
163       * mknod(const char* path, mode_t mode, dev_t dev)
164       */
mknod(UnixPath path, int mode, long dev)165      static void mknod(UnixPath path, int mode, long dev) throws UnixException {
166          NativeBuffer buffer = copyToNativeBuffer(path);
167          try {
168              mknod0(buffer.address(), mode, dev);
169          } finally {
170              buffer.release();
171          }
172      }
mknod0(long pathAddress, int mode, long dev)173      private static native void mknod0(long pathAddress, int mode, long dev)
174          throws UnixException;
175  
176      /**
177       *  rename(const char* old, const char* new)
178       */
rename(UnixPath from, UnixPath to)179      static void rename(UnixPath from, UnixPath to) throws UnixException {
180          NativeBuffer fromBuffer = copyToNativeBuffer(from);
181          NativeBuffer toBuffer = copyToNativeBuffer(to);
182          try {
183              rename0(fromBuffer.address(), toBuffer.address());
184          } finally {
185              toBuffer.release();
186              fromBuffer.release();
187          }
188      }
rename0(long fromAddress, long toAddress)189      private static native void rename0(long fromAddress, long toAddress)
190          throws UnixException;
191  
192      /**
193       *  renameat(int fromfd, const char* old, int tofd, const char* new)
194       */
renameat(int fromfd, byte[] from, int tofd, byte[] to)195      static void renameat(int fromfd, byte[] from, int tofd, byte[] to) throws UnixException {
196          NativeBuffer fromBuffer = NativeBuffers.asNativeBuffer(from);
197          NativeBuffer toBuffer = NativeBuffers.asNativeBuffer(to);
198          try {
199              renameat0(fromfd, fromBuffer.address(), tofd, toBuffer.address());
200          } finally {
201              toBuffer.release();
202              fromBuffer.release();
203          }
204      }
renameat0(int fromfd, long fromAddress, int tofd, long toAddress)205      private static native void renameat0(int fromfd, long fromAddress, int tofd, long toAddress)
206          throws UnixException;
207  
208      /**
209       * mkdir(const char* path, mode_t mode)
210       */
mkdir(UnixPath path, int mode)211      static void mkdir(UnixPath path, int mode) throws UnixException {
212          NativeBuffer buffer = copyToNativeBuffer(path);
213          try {
214              mkdir0(buffer.address(), mode);
215          } finally {
216              buffer.release();
217          }
218      }
mkdir0(long pathAddress, int mode)219      private static native void mkdir0(long pathAddress, int mode) throws UnixException;
220  
221      /**
222       * rmdir(const char* path)
223       */
rmdir(UnixPath path)224      static void rmdir(UnixPath path) throws UnixException {
225          NativeBuffer buffer = copyToNativeBuffer(path);
226          try {
227              rmdir0(buffer.address());
228          } finally {
229              buffer.release();
230          }
231      }
rmdir0(long pathAddress)232      private static native void rmdir0(long pathAddress) throws UnixException;
233  
234      /**
235       * readlink(const char* path, char* buf, size_t bufsize)
236       *
237       * @return  link target
238       */
readlink(UnixPath path)239      static byte[] readlink(UnixPath path) throws UnixException {
240          NativeBuffer buffer = copyToNativeBuffer(path);
241          try {
242              return readlink0(buffer.address());
243          } finally {
244              buffer.release();
245          }
246      }
readlink0(long pathAddress)247      private static native byte[] readlink0(long pathAddress) throws UnixException;
248  
249      /**
250       * realpath(const char* path, char* resolved_name)
251       *
252       * @return  resolved path
253       */
realpath(UnixPath path)254      static byte[] realpath(UnixPath path) throws UnixException {
255          NativeBuffer buffer = copyToNativeBuffer(path);
256          try {
257              return realpath0(buffer.address());
258          } finally {
259              buffer.release();
260          }
261      }
realpath0(long pathAddress)262      private static native byte[] realpath0(long pathAddress) throws UnixException;
263  
264      /**
265       * symlink(const char* name1, const char* name2)
266       */
symlink(byte[] name1, UnixPath name2)267      static void symlink(byte[] name1, UnixPath name2) throws UnixException {
268          NativeBuffer targetBuffer = NativeBuffers.asNativeBuffer(name1);
269          NativeBuffer linkBuffer = copyToNativeBuffer(name2);
270          try {
271              symlink0(targetBuffer.address(), linkBuffer.address());
272          } finally {
273              linkBuffer.release();
274              targetBuffer.release();
275          }
276      }
symlink0(long name1, long name2)277      private static native void symlink0(long name1, long name2)
278          throws UnixException;
279  
280      /**
281       * stat(const char* path, struct stat* buf)
282       */
stat(UnixPath path, UnixFileAttributes attrs)283      static void stat(UnixPath path, UnixFileAttributes attrs) throws UnixException {
284          NativeBuffer buffer = copyToNativeBuffer(path);
285          try {
286              stat0(buffer.address(), attrs);
287          } finally {
288              buffer.release();
289          }
290      }
stat0(long pathAddress, UnixFileAttributes attrs)291      private static native void stat0(long pathAddress, UnixFileAttributes attrs)
292          throws UnixException;
293  
294  
295      /**
296       * stat(const char* path, struct stat* buf)
297       *
298       * @return st_mode (file type and mode) or 0 if an error occurs.
299       */
stat(UnixPath path)300      static int stat(UnixPath path) {
301          NativeBuffer buffer = copyToNativeBuffer(path);
302          try {
303              return stat1(buffer.address());
304          } finally {
305              buffer.release();
306          }
307      }
stat1(long pathAddress)308      private static native int stat1(long pathAddress);
309  
310  
311      /**
312       * lstat(const char* path, struct stat* buf)
313       */
lstat(UnixPath path, UnixFileAttributes attrs)314      static void lstat(UnixPath path, UnixFileAttributes attrs) throws UnixException {
315          NativeBuffer buffer = copyToNativeBuffer(path);
316          try {
317              lstat0(buffer.address(), attrs);
318          } finally {
319              buffer.release();
320          }
321      }
lstat0(long pathAddress, UnixFileAttributes attrs)322      private static native void lstat0(long pathAddress, UnixFileAttributes attrs)
323          throws UnixException;
324  
325      /**
326       * fstat(int filedes, struct stat* buf)
327       */
fstat(int fd, UnixFileAttributes attrs)328      static native void fstat(int fd, UnixFileAttributes attrs) throws UnixException;
329  
330      /**
331       * fstatat(int filedes,const char* path,  struct stat* buf, int flag)
332       */
fstatat(int dfd, byte[] path, int flag, UnixFileAttributes attrs)333      static void fstatat(int dfd, byte[] path, int flag, UnixFileAttributes attrs)
334          throws UnixException
335      {
336          NativeBuffer buffer = NativeBuffers.asNativeBuffer(path);
337          try {
338              fstatat0(dfd, buffer.address(), flag, attrs);
339          } finally {
340              buffer.release();
341          }
342      }
fstatat0(int dfd, long pathAddress, int flag, UnixFileAttributes attrs)343      private static native void fstatat0(int dfd, long pathAddress, int flag,
344          UnixFileAttributes attrs) throws UnixException;
345  
346      /**
347       * chown(const char* path, uid_t owner, gid_t group)
348       */
chown(UnixPath path, int uid, int gid)349      static void chown(UnixPath path, int uid, int gid) throws UnixException {
350          NativeBuffer buffer = copyToNativeBuffer(path);
351          try {
352              chown0(buffer.address(), uid, gid);
353          } finally {
354              buffer.release();
355          }
356      }
chown0(long pathAddress, int uid, int gid)357      private static native void chown0(long pathAddress, int uid, int gid)
358          throws UnixException;
359  
360      /**
361       * lchown(const char* path, uid_t owner, gid_t group)
362       */
lchown(UnixPath path, int uid, int gid)363      static void lchown(UnixPath path, int uid, int gid) throws UnixException {
364          NativeBuffer buffer = copyToNativeBuffer(path);
365          try {
366              lchown0(buffer.address(), uid, gid);
367          } finally {
368              buffer.release();
369          }
370      }
lchown0(long pathAddress, int uid, int gid)371      private static native void lchown0(long pathAddress, int uid, int gid)
372          throws UnixException;
373  
374      /**
375       * fchown(int filedes, uid_t owner, gid_t group)
376       */
fchown(int fd, int uid, int gid)377      static native void fchown(int fd, int uid, int gid) throws UnixException;
378  
379      /**
380       * chmod(const char* path, mode_t mode)
381       */
chmod(UnixPath path, int mode)382      static void chmod(UnixPath path, int mode) throws UnixException {
383          NativeBuffer buffer = copyToNativeBuffer(path);
384          try {
385              chmod0(buffer.address(), mode);
386          } finally {
387              buffer.release();
388          }
389      }
chmod0(long pathAddress, int mode)390      private static native void chmod0(long pathAddress, int mode)
391          throws UnixException;
392  
393      /**
394       * fchmod(int fildes, mode_t mode)
395       */
fchmod(int fd, int mode)396      static native void fchmod(int fd, int mode) throws UnixException;
397  
398      /**
399       * utimes(conar char* path, const struct timeval times[2])
400       */
utimes(UnixPath path, long times0, long times1)401      static void utimes(UnixPath path, long times0, long times1)
402          throws UnixException
403      {
404          NativeBuffer buffer = copyToNativeBuffer(path);
405          try {
406              utimes0(buffer.address(), times0, times1);
407          } finally {
408              buffer.release();
409          }
410      }
utimes0(long pathAddress, long times0, long times1)411      private static native void utimes0(long pathAddress, long times0, long times1)
412          throws UnixException;
413  
414      /**
415       * futimes(int fildes,, const struct timeval times[2])
416       */
futimes(int fd, long times0, long times1)417      static native void futimes(int fd, long times0, long times1) throws UnixException;
418  
419      /**
420       * DIR *opendir(const char* dirname)
421       */
opendir(UnixPath path)422      static long opendir(UnixPath path) throws UnixException {
423          NativeBuffer buffer = copyToNativeBuffer(path);
424          try {
425              return opendir0(buffer.address());
426          } finally {
427              buffer.release();
428          }
429      }
opendir0(long pathAddress)430      private static native long opendir0(long pathAddress) throws UnixException;
431  
432      /**
433       * DIR* fdopendir(int filedes)
434       */
fdopendir(int dfd)435      static native long fdopendir(int dfd) throws UnixException;
436  
437  
438      /**
439       * closedir(DIR* dirp)
440       */
closedir(long dir)441      static native void closedir(long dir) throws UnixException;
442  
443      /**
444       * struct dirent* readdir(DIR *dirp)
445       *
446       * @return  dirent->d_name
447       */
readdir(long dir)448      static native byte[] readdir(long dir) throws UnixException;
449  
450      /**
451       * size_t read(int fildes, void* buf, size_t nbyte)
452       */
read(int fildes, long buf, int nbyte)453      static native int read(int fildes, long buf, int nbyte) throws UnixException;
454  
455      /**
456       * size_t writeint fildes, void* buf, size_t nbyte)
457       */
write(int fildes, long buf, int nbyte)458      static native int write(int fildes, long buf, int nbyte) throws UnixException;
459  
460      /**
461       * access(const char* path, int amode);
462       */
access(UnixPath path, int amode)463      static void access(UnixPath path, int amode) throws UnixException {
464          NativeBuffer buffer = copyToNativeBuffer(path);
465          try {
466              access0(buffer.address(), amode);
467          } finally {
468              buffer.release();
469          }
470      }
access0(long pathAddress, int amode)471      private static native void access0(long pathAddress, int amode) throws UnixException;
472  
473      /**
474       * access(constant char* path, F_OK)
475       *
476       * @return true if the file exists, false otherwise
477       */
exists(UnixPath path)478      static boolean exists(UnixPath path) {
479          NativeBuffer buffer = copyToNativeBuffer(path);
480          try {
481              return exists0(buffer.address());
482          } finally {
483              buffer.release();
484          }
485      }
exists0(long pathAddress)486      private static native boolean exists0(long pathAddress);
487  
488  
489      /**
490       * struct passwd *getpwuid(uid_t uid);
491       *
492       * @return  passwd->pw_name
493       */
getpwuid(int uid)494      static native byte[] getpwuid(int uid) throws UnixException;
495  
496      /**
497       * struct group *getgrgid(gid_t gid);
498       *
499       * @return  group->gr_name
500       */
getgrgid(int gid)501      static native byte[] getgrgid(int gid) throws UnixException;
502  
503      /**
504       * struct passwd *getpwnam(const char *name);
505       *
506       * @return  passwd->pw_uid
507       */
getpwnam(String name)508      static int getpwnam(String name) throws UnixException {
509          NativeBuffer buffer = NativeBuffers.asNativeBuffer(Util.toBytes(name));
510          try {
511              return getpwnam0(buffer.address());
512          } finally {
513              buffer.release();
514          }
515      }
getpwnam0(long nameAddress)516      private static native int getpwnam0(long nameAddress) throws UnixException;
517  
518      /**
519       * struct group *getgrnam(const char *name);
520       *
521       * @return  group->gr_name
522       */
getgrnam(String name)523      static int getgrnam(String name) throws UnixException {
524          NativeBuffer buffer = NativeBuffers.asNativeBuffer(Util.toBytes(name));
525          try {
526              return getgrnam0(buffer.address());
527          } finally {
528              buffer.release();
529          }
530      }
getgrnam0(long nameAddress)531      private static native int getgrnam0(long nameAddress) throws UnixException;
532  
533      /**
534       * statvfs(const char* path, struct statvfs *buf)
535       */
statvfs(UnixPath path, UnixFileStoreAttributes attrs)536      static void statvfs(UnixPath path, UnixFileStoreAttributes attrs)
537          throws UnixException
538      {
539          NativeBuffer buffer = copyToNativeBuffer(path);
540          try {
541              statvfs0(buffer.address(), attrs);
542          } finally {
543              buffer.release();
544          }
545      }
statvfs0(long pathAddress, UnixFileStoreAttributes attrs)546      private static native void statvfs0(long pathAddress, UnixFileStoreAttributes attrs)
547          throws UnixException;
548  
549      /**
550       * long int pathconf(const char *path, int name);
551       */
pathconf(UnixPath path, int name)552      static long pathconf(UnixPath path, int name) throws UnixException {
553          NativeBuffer buffer = copyToNativeBuffer(path);
554          try {
555              return pathconf0(buffer.address(), name);
556          } finally {
557              buffer.release();
558          }
559      }
pathconf0(long pathAddress, int name)560      private static native long pathconf0(long pathAddress, int name)
561          throws UnixException;
562  
563      /**
564       * long fpathconf(int fildes, int name);
565       */
fpathconf(int filedes, int name)566      static native long fpathconf(int filedes, int name) throws UnixException;
567  
568      /**
569       * char* strerror(int errnum)
570       */
strerror(int errnum)571      static native byte[] strerror(int errnum);
572  
573      /**
574       * Capabilities
575       */
576      private static final int SUPPORTS_OPENAT        = 1 << 1;    // syscalls
577      private static final int SUPPORTS_FUTIMES       = 1 << 2;
578      private static final int SUPPORTS_BIRTHTIME     = 1 << 16;   // other features
579      private static final int capabilities;
580  
581      /**
582       * Supports openat and other *at calls.
583       */
openatSupported()584      static boolean openatSupported() {
585          return (capabilities & SUPPORTS_OPENAT) != 0;
586      }
587  
588      /**
589       * Supports futimes or futimesat
590       */
futimesSupported()591      static boolean futimesSupported() {
592          return (capabilities & SUPPORTS_FUTIMES) != 0;
593      }
594  
595      /**
596       * Supports file birth (creation) time attribute
597       */
birthtimeSupported()598      static boolean birthtimeSupported() {
599          return (capabilities & SUPPORTS_BIRTHTIME) != 0;
600      }
601  
init()602      private static native int init();
603      static {
604          // Android-removed: Code to load native libraries, doesn't make sense on Android.
605          /*
606          AccessController.doPrivileged(new PrivilegedAction<Void>() {
607              public Void run() {
608                  System.loadLibrary("nio");
609                  return null;
610          }});
611          */
612          capabilities = init();
613      }
614  }
615