• Home
  • 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