< prev index next >

src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java

Print this page

  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 /**
 29  * Unix system and library calls.
 30  */
 31 
 32 class UnixNativeDispatcher {
 33     protected UnixNativeDispatcher() { }
 34 
 35     // returns a NativeBuffer containing the given path
 36     static NativeBuffer copyToNativeBuffer(UnixPath path) {
 37         byte[] cstr = path.getByteArrayForSysCalls();
 38         int size = cstr.length + 1;
 39         NativeBuffer buffer = NativeBuffers.getNativeBufferFromCache(size);
 40         if (buffer == null) {
 41             buffer = NativeBuffers.allocNativeBuffer(size);
 42         } else {
 43             // buffer already contains the path
 44             if (buffer.owner() == path)
 45                 return buffer;
 46         }
 47         NativeBuffers.copyCStringToNativeBuffer(cstr, buffer);
 48         buffer.setOwner(path);
 49         return buffer;
 50     }
 51 
 52     /**
 53      * char *getcwd(char *buf, size_t size);
 54      */
 55     static native byte[] getcwd();
 56 
 57     /**
 58      * int dup(int filedes)
 59      */
 60     static native int dup(int filedes) throws UnixException;
 61 
 62     /**
 63      * int open(const char* path, int oflag, mode_t mode)
 64      */
 65     static int open(UnixPath path, int flags, int mode) throws UnixException {
 66         NativeBuffer buffer = copyToNativeBuffer(path);
 67         try {
 68             return open0(buffer.address(), flags, mode);
 69         } finally {
 70             buffer.release();

 71         }
 72     }
 73     private static native int open0(long pathAddress, int flags, int mode)
 74         throws UnixException;
 75 
 76     /**
 77      * int openat(int dfd, const char* path, int oflag, mode_t mode)
 78      */
 79     static int openat(int dfd, byte[] path, int flags, int mode) throws UnixException {
 80         NativeBuffer buffer = NativeBuffers.asNativeBuffer(path);
 81         try {
 82             return openat0(dfd, buffer.address(), flags, mode);
 83         } finally {
 84             buffer.release();

 85         }
 86     }
 87     private static native int openat0(int dfd, long pathAddress, int flags, int mode)
 88         throws UnixException;
 89 
 90     /**
 91      * close(int filedes). If fd is -1 this is a no-op.
 92      */
 93     static void close(int fd) {
 94         if (fd != -1) {
 95             close0(fd);
 96         }
 97     }
 98     private static native void close0(int fd);
 99 
100     /**
101      * void rewind(FILE* stream);
102      */
103     static native void rewind(long stream) throws UnixException;
104 
105     /**
106      * ssize_t getline(char **lineptr, size_t *n, FILE *stream);
107      */
108     static native int getlinelen(long stream) throws UnixException;
109 
110     /**
111      * link(const char* existing, const char* new)
112      */
113     static void link(UnixPath existing, UnixPath newfile) throws UnixException {
114         NativeBuffer existingBuffer = copyToNativeBuffer(existing);
115         NativeBuffer newBuffer = copyToNativeBuffer(newfile);
116         try {
117             link0(existingBuffer.address(), newBuffer.address());
118         } finally {
119             newBuffer.release();
120             existingBuffer.release();


121         }
122     }
123     private static native void link0(long existingAddress, long newAddress)
124         throws UnixException;
125 
126     /**
127      * unlink(const char* path)
128      */
129     static void unlink(UnixPath path) throws UnixException {
130         NativeBuffer buffer = copyToNativeBuffer(path);
131         try {
132             unlink0(buffer.address());
133         } finally {
134             buffer.release();

135         }
136     }
137     private static native void unlink0(long pathAddress) throws UnixException;
138 
139     /**
140      * unlinkat(int dfd, const char* path, int flag)
141      */
142     static void unlinkat(int dfd, byte[] path, int flag) throws UnixException {
143         NativeBuffer buffer = NativeBuffers.asNativeBuffer(path);
144         try {
145             unlinkat0(dfd, buffer.address(), flag);
146         } finally {
147             buffer.release();

148         }
149     }
150     private static native void unlinkat0(int dfd, long pathAddress, int flag)
151         throws UnixException;
152 
153     /**
154      * mknod(const char* path, mode_t mode, dev_t dev)
155      */
156     static void mknod(UnixPath path, int mode, long dev) throws UnixException {
157         NativeBuffer buffer = copyToNativeBuffer(path);
158         try {
159             mknod0(buffer.address(), mode, dev);
160         } finally {
161             buffer.release();

162         }
163     }
164     private static native void mknod0(long pathAddress, int mode, long dev)
165         throws UnixException;
166 
167     /**
168      *  rename(const char* old, const char* new)
169      */
170     static void rename(UnixPath from, UnixPath to) throws UnixException {
171         NativeBuffer fromBuffer = copyToNativeBuffer(from);
172         NativeBuffer toBuffer = copyToNativeBuffer(to);
173         try {
174             rename0(fromBuffer.address(), toBuffer.address());
175         } finally {
176             toBuffer.release();
177             fromBuffer.release();


178         }
179     }
180     private static native void rename0(long fromAddress, long toAddress)
181         throws UnixException;
182 
183     /**
184      *  renameat(int fromfd, const char* old, int tofd, const char* new)
185      */
186     static void renameat(int fromfd, byte[] from, int tofd, byte[] to) throws UnixException {
187         NativeBuffer fromBuffer = NativeBuffers.asNativeBuffer(from);
188         NativeBuffer toBuffer = NativeBuffers.asNativeBuffer(to);
189         try {
190             renameat0(fromfd, fromBuffer.address(), tofd, toBuffer.address());
191         } finally {
192             toBuffer.release();
193             fromBuffer.release();


194         }
195     }
196     private static native void renameat0(int fromfd, long fromAddress, int tofd, long toAddress)
197         throws UnixException;
198 
199     /**
200      * mkdir(const char* path, mode_t mode)
201      */
202     static void mkdir(UnixPath path, int mode) throws UnixException {
203         NativeBuffer buffer = copyToNativeBuffer(path);
204         try {
205             mkdir0(buffer.address(), mode);
206         } finally {
207             buffer.release();

208         }
209     }
210     private static native void mkdir0(long pathAddress, int mode) throws UnixException;
211 
212     /**
213      * rmdir(const char* path)
214      */
215     static void rmdir(UnixPath path) throws UnixException {
216         NativeBuffer buffer = copyToNativeBuffer(path);
217         try {
218             rmdir0(buffer.address());
219         } finally {
220             buffer.release();

221         }
222     }
223     private static native void rmdir0(long pathAddress) throws UnixException;
224 
225     /**
226      * readlink(const char* path, char* buf, size_t bufsize)
227      *
228      * @return  link target
229      */
230     static byte[] readlink(UnixPath path) throws UnixException {
231         NativeBuffer buffer = copyToNativeBuffer(path);
232         try {
233             return readlink0(buffer.address());
234         } finally {
235             buffer.release();

236         }
237     }
238     private static native byte[] readlink0(long pathAddress) throws UnixException;
239 
240     /**
241      * realpath(const char* path, char* resolved_name)
242      *
243      * @return  resolved path
244      */
245     static byte[] realpath(UnixPath path) throws UnixException {
246         NativeBuffer buffer = copyToNativeBuffer(path);
247         try {
248             return realpath0(buffer.address());
249         } finally {
250             buffer.release();

251         }
252     }
253     private static native byte[] realpath0(long pathAddress) throws UnixException;
254 
255     /**
256      * symlink(const char* name1, const char* name2)
257      */
258     static void symlink(byte[] name1, UnixPath name2) throws UnixException {
259         NativeBuffer targetBuffer = NativeBuffers.asNativeBuffer(name1);
260         NativeBuffer linkBuffer = copyToNativeBuffer(name2);
261         try {
262             symlink0(targetBuffer.address(), linkBuffer.address());
263         } finally {
264             linkBuffer.release();
265             targetBuffer.release();


266         }
267     }
268     private static native void symlink0(long name1, long name2)
269         throws UnixException;
270 
271     /**
272      * stat(const char* path, struct stat* buf)
273      */
274     static void stat(UnixPath path, UnixFileAttributes attrs) throws UnixException {
275         NativeBuffer buffer = copyToNativeBuffer(path);
276         try {
277             stat0(buffer.address(), attrs);
278         } finally {
279             buffer.release();

280         }
281     }
282     private static native void stat0(long pathAddress, UnixFileAttributes attrs)
283         throws UnixException;
284 
285 
286     /**
287      * stat(const char* path, struct stat* buf)
288      *
289      * @return st_mode (file type and mode) or 0 if an error occurs.
290      */
291     static int stat(UnixPath path) {
292         NativeBuffer buffer = copyToNativeBuffer(path);
293         try {
294             return stat1(buffer.address());
295         } finally {
296             buffer.release();

297         }
298     }
299     private static native int stat1(long pathAddress);
300 
301 
302     /**
303      * lstat(const char* path, struct stat* buf)
304      */
305     static void lstat(UnixPath path, UnixFileAttributes attrs) throws UnixException {
306         NativeBuffer buffer = copyToNativeBuffer(path);
307         try {
308             lstat0(buffer.address(), attrs);
309         } finally {
310             buffer.release();

311         }
312     }
313     private static native void lstat0(long pathAddress, UnixFileAttributes attrs)
314         throws UnixException;
315 
316     /**
317      * fstat(int filedes, struct stat* buf)
318      */
319     static native void fstat(int fd, UnixFileAttributes attrs) throws UnixException;








320 
321     /**
322      * fstatat(int filedes,const char* path,  struct stat* buf, int flag)
323      */
324     static void fstatat(int dfd, byte[] path, int flag, UnixFileAttributes attrs)
325         throws UnixException
326     {
327         NativeBuffer buffer = NativeBuffers.asNativeBuffer(path);
328         try {
329             fstatat0(dfd, buffer.address(), flag, attrs);
330         } finally {
331             buffer.release();

332         }
333     }
334     private static native void fstatat0(int dfd, long pathAddress, int flag,
335         UnixFileAttributes attrs) throws UnixException;
336 
337     /**
338      * chown(const char* path, uid_t owner, gid_t group)
339      */
340     static void chown(UnixPath path, int uid, int gid) throws UnixException {
341         NativeBuffer buffer = copyToNativeBuffer(path);
342         try {
343             chown0(buffer.address(), uid, gid);
344         } finally {
345             buffer.release();

346         }
347     }
348     private static native void chown0(long pathAddress, int uid, int gid)
349         throws UnixException;
350 
351     /**
352      * lchown(const char* path, uid_t owner, gid_t group)
353      */
354     static void lchown(UnixPath path, int uid, int gid) throws UnixException {
355         NativeBuffer buffer = copyToNativeBuffer(path);
356         try {
357             lchown0(buffer.address(), uid, gid);
358         } finally {
359             buffer.release();

360         }
361     }
362     private static native void lchown0(long pathAddress, int uid, int gid)
363         throws UnixException;
364 
365     /**
366      * fchown(int filedes, uid_t owner, gid_t group)
367      */
368     static native void fchown(int fd, int uid, int gid) throws UnixException;







369 
370     /**
371      * chmod(const char* path, mode_t mode)
372      */
373     static void chmod(UnixPath path, int mode) throws UnixException {
374         NativeBuffer buffer = copyToNativeBuffer(path);
375         try {
376             chmod0(buffer.address(), mode);
377         } finally {
378             buffer.release();

379         }
380     }
381     private static native void chmod0(long pathAddress, int mode)
382         throws UnixException;
383 
384     /**
385      * fchmod(int fildes, mode_t mode)
386      */
387     static native void fchmod(int fd, int mode) throws UnixException;







388 
389     /**
390      * utimes(const char* path, const struct timeval times[2])
391      */
392     static void utimes(UnixPath path, long times0, long times1)
393         throws UnixException
394     {
395         NativeBuffer buffer = copyToNativeBuffer(path);
396         try {
397             utimes0(buffer.address(), times0, times1);
398         } finally {
399             buffer.release();

400         }
401     }
402     private static native void utimes0(long pathAddress, long times0, long times1)
403         throws UnixException;
404 
405     /**
406      * futimes(int fildes, const struct timeval times[2])
407      */
408     static native void futimes(int fd, long times0, long times1) throws UnixException;








409 
410     /**
411      * futimens(int fildes, const struct timespec times[2])
412      */
413     static native void futimens(int fd, long times0, long times1) throws UnixException;








414 
415     /**
416      * lutimes(const char* path, const struct timeval times[2])
417      */
418     static void lutimes(UnixPath path, long times0, long times1)
419         throws UnixException
420     {
421         NativeBuffer buffer = copyToNativeBuffer(path);
422         try {
423             lutimes0(buffer.address(), times0, times1);
424         } finally {
425             buffer.release();

426         }
427     }
428     private static native void lutimes0(long pathAddress, long times0, long times1)
429         throws UnixException;
430 
431     /**
432      * DIR *opendir(const char* dirname)
433      */
434     static long opendir(UnixPath path) throws UnixException {
435         NativeBuffer buffer = copyToNativeBuffer(path);
436         try {
437             return opendir0(buffer.address());
438         } finally {
439             buffer.release();

440         }
441     }
442     private static native long opendir0(long pathAddress) throws UnixException;
443 
444     /**
445      * DIR* fdopendir(int filedes)
446      */
447     static native long fdopendir(int dfd) throws UnixException;
448 
449 
450     /**
451      * closedir(DIR* dirp)
452      */
453     static native void closedir(long dir) throws UnixException;
454 
455     /**
456      * struct dirent* readdir(DIR *dirp)
457      *
458      * @return  dirent->d_name
459      */
460     static native byte[] readdir(long dir) throws UnixException;







461 
462     /**
463      * size_t read(int fildes, void* buf, size_t nbyte)
464      */
465     static native int read(int fildes, long buf, int nbyte) throws UnixException;







466 
467     /**
468      * size_t writeint fildes, void* buf, size_t nbyte)
469      */
470     static native int write(int fildes, long buf, int nbyte) throws UnixException;







471 
472     /**
473      * access(const char* path, int amode);
474      */
475     static void access(UnixPath path, int amode) throws UnixException {
476         NativeBuffer buffer = copyToNativeBuffer(path);
477         try {
478             access0(buffer.address(), amode);
479         } finally {
480             buffer.release();

481         }
482     }
483     private static native void access0(long pathAddress, int amode) throws UnixException;
484 
485     /**
486      * access(constant char* path, F_OK)
487      *
488      * @return true if the file exists, false otherwise
489      */
490     static boolean exists(UnixPath path) {
491         NativeBuffer buffer = copyToNativeBuffer(path);
492         try {
493             return exists0(buffer.address());
494         } finally {
495             buffer.release();

496         }
497     }
498     private static native boolean exists0(long pathAddress);
499 
500 
501     /**
502      * struct passwd *getpwuid(uid_t uid);
503      *
504      * @return  passwd->pw_name
505      */
506     static native byte[] getpwuid(int uid) throws UnixException;
507 
508     /**
509      * struct group *getgrgid(gid_t gid);
510      *
511      * @return  group->gr_name
512      */
513     static native byte[] getgrgid(int gid) throws UnixException;
514 
515     /**
516      * struct passwd *getpwnam(const char *name);
517      *
518      * @return  passwd->pw_uid
519      */
520     static int getpwnam(String name) throws UnixException {
521         NativeBuffer buffer = NativeBuffers.asNativeBuffer(Util.toBytes(name));
522         try {
523             return getpwnam0(buffer.address());
524         } finally {
525             buffer.release();

526         }
527     }
528     private static native int getpwnam0(long nameAddress) throws UnixException;
529 
530     /**
531      * struct group *getgrnam(const char *name);
532      *
533      * @return  group->gr_name
534      */
535     static int getgrnam(String name) throws UnixException {
536         NativeBuffer buffer = NativeBuffers.asNativeBuffer(Util.toBytes(name));
537         try {
538             return getgrnam0(buffer.address());
539         } finally {
540             buffer.release();

541         }
542     }
543     private static native int getgrnam0(long nameAddress) throws UnixException;
544 
545     /**
546      * statvfs(const char* path, struct statvfs *buf)
547      */
548     static void statvfs(UnixPath path, UnixFileStoreAttributes attrs)
549         throws UnixException
550     {
551         NativeBuffer buffer = copyToNativeBuffer(path);
552         try {
553             statvfs0(buffer.address(), attrs);
554         } finally {
555             buffer.release();

556         }
557     }
558     private static native void statvfs0(long pathAddress, UnixFileStoreAttributes attrs)
559         throws UnixException;
560 
561     /**
562      * char* strerror(int errnum)
563      */
564     static native byte[] strerror(int errnum);
565 
566     /**
567      * ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size);
568      */
569     static int fgetxattr(int filedes, byte[] name, long valueAddress,
570                          int valueLen) throws UnixException
571     {
572         try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(name)) {
573             return fgetxattr0(filedes, buffer.address(), valueAddress, valueLen);





574         }
575     }
576 
577     private static native int fgetxattr0(int filedes, long nameAddress,
578         long valueAddress, int valueLen) throws UnixException;
579 
580     /**
581      *  fsetxattr(int filedes, const char *name, const void *value, size_t size, int flags);
582      */
583     static void fsetxattr(int filedes, byte[] name, long valueAddress,
584                           int valueLen) throws UnixException
585     {
586         try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(name)) {
587             fsetxattr0(filedes, buffer.address(), valueAddress, valueLen);





588         }
589     }
590 
591     private static native void fsetxattr0(int filedes, long nameAddress,
592         long valueAddress, int valueLen) throws UnixException;
593 
594     /**
595      * fremovexattr(int filedes, const char *name);
596      */
597     static void fremovexattr(int filedes, byte[] name) throws UnixException {
598         try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(name)) {
599             fremovexattr0(filedes, buffer.address());




600         }
601     }
602 
603     private static native void fremovexattr0(int filedes, long nameAddress)
604         throws UnixException;
605 
606     /**
607      * size_t flistxattr(int filedes, const char *list, size_t size)
608      */
609     static native int flistxattr(int filedes, long listAddress, int size)
610         throws UnixException;
611 
612     /**
613      * Capabilities
614      */
615     private static final int SUPPORTS_OPENAT        = 1 << 1;  // syscalls
616     private static final int SUPPORTS_FUTIMES       = 1 << 2;
617     private static final int SUPPORTS_FUTIMENS      = 1 << 3;
618     private static final int SUPPORTS_LUTIMES       = 1 << 4;
619     private static final int SUPPORTS_XATTR         = 1 << 5;

  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 jdk.internal.misc.Blocker;
 29 
 30 /**
 31  * Unix system and library calls.
 32  */
 33 
 34 class UnixNativeDispatcher {
 35     protected UnixNativeDispatcher() { }
 36 
 37     // returns a NativeBuffer containing the given path
 38     static NativeBuffer copyToNativeBuffer(UnixPath path) {
 39         byte[] cstr = path.getByteArrayForSysCalls();
 40         int size = cstr.length + 1;
 41         NativeBuffer buffer = NativeBuffers.getNativeBufferFromCache(size);
 42         if (buffer == null) {
 43             buffer = NativeBuffers.allocNativeBuffer(size);
 44         } else {
 45             // buffer already contains the path
 46             if (buffer.owner() == path)
 47                 return buffer;
 48         }
 49         NativeBuffers.copyCStringToNativeBuffer(cstr, buffer);
 50         buffer.setOwner(path);
 51         return buffer;
 52     }
 53 
 54     /**
 55      * char *getcwd(char *buf, size_t size);
 56      */
 57     static native byte[] getcwd();
 58 
 59     /**
 60      * int dup(int filedes)
 61      */
 62     static native int dup(int filedes) throws UnixException;
 63 
 64     /**
 65      * int open(const char* path, int oflag, mode_t mode)
 66      */
 67     static int open(UnixPath path, int flags, int mode) throws UnixException {
 68         try (NativeBuffer buffer = copyToNativeBuffer(path)) {
 69             if (Thread.currentThread().isVirtual()) {
 70                 return Blocker.managedBlock(() -> open0(buffer.address(), flags, mode));
 71             } else {
 72                 return open0(buffer.address(), flags, mode);
 73             }
 74         }
 75     }
 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      */
 82     static int openat(int dfd, byte[] path, int flags, int mode) throws UnixException {
 83         try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(path)) {
 84             if (Thread.currentThread().isVirtual()) {
 85                 return Blocker.managedBlock(() -> openat0(dfd, buffer.address(), flags, mode));
 86             } else {
 87                 return openat0(dfd, buffer.address(), flags, mode);
 88             }
 89         }
 90     }
 91     private static native int openat0(int dfd, long pathAddress, int flags, int mode)
 92         throws UnixException;
 93 
 94     /**
 95      * close(int filedes). If fd is -1 this is a no-op.
 96      */
 97     static void close(int fd) {
 98         if (fd != -1) {
 99             close0(fd);
100         }
101     }
102     private static native void close0(int fd);
103 
104     /**
105      * void rewind(FILE* stream);
106      */
107     static native void rewind(long stream) throws UnixException;
108 
109     /**
110      * ssize_t getline(char **lineptr, size_t *n, FILE *stream);
111      */
112     static native int getlinelen(long stream) throws UnixException;
113 
114     /**
115      * link(const char* existing, const char* new)
116      */
117     static void link(UnixPath existing, UnixPath newfile) throws UnixException {
118         try (NativeBuffer existingBuffer = copyToNativeBuffer(existing);
119              NativeBuffer newBuffer = copyToNativeBuffer(newfile)) {
120             long existingAddress = existingBuffer.address();
121             long newAddress = newBuffer.address();
122             if (Thread.currentThread().isVirtual()) {
123                 Blocker.managedBlock(() -> link0(existingAddress, newAddress));
124             } else {
125                 link0(existingAddress, newAddress);
126             }
127         }
128     }
129     private static native void link0(long existingAddress, long newAddress)
130         throws UnixException;
131 
132     /**
133      * unlink(const char* path)
134      */
135     static void unlink(UnixPath path) throws UnixException {
136         try (NativeBuffer buffer = copyToNativeBuffer(path)) {
137             if (Thread.currentThread().isVirtual()) {
138                 Blocker.managedBlock(() -> unlink0(buffer.address()));
139             } else {
140                 unlink0(buffer.address());
141             }
142         }
143     }
144     private static native void unlink0(long pathAddress) throws UnixException;
145 
146     /**
147      * unlinkat(int dfd, const char* path, int flag)
148      */
149     static void unlinkat(int dfd, byte[] path, int flag) throws UnixException {
150         try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(path)) {
151             if (Thread.currentThread().isVirtual()) {
152                 Blocker.managedBlock(() -> unlinkat0(dfd, buffer.address(), flag));
153             } else {
154                 unlinkat0(dfd, buffer.address(), flag);
155             }
156         }
157     }
158     private static native void unlinkat0(int dfd, long pathAddress, int flag)
159         throws UnixException;
160 
161     /**
162      * mknod(const char* path, mode_t mode, dev_t dev)
163      */
164     static void mknod(UnixPath path, int mode, long dev) throws UnixException {
165         try (NativeBuffer buffer = copyToNativeBuffer(path)) {
166             if (Thread.currentThread().isVirtual()) {
167                 Blocker.managedBlock(() -> mknod0(buffer.address(), mode, dev));
168             } else {
169                 mknod0(buffer.address(), mode, dev);
170             }
171         }
172     }
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      */
179     static void rename(UnixPath from, UnixPath to) throws UnixException {
180         try (NativeBuffer fromBuffer = copyToNativeBuffer(from);
181              NativeBuffer toBuffer = copyToNativeBuffer(to)) {
182             long fromAddress = fromBuffer.address();
183             long toAddress = toBuffer.address();
184             if (Thread.currentThread().isVirtual()) {
185                 Blocker.managedBlock(() -> rename0(fromAddress, toAddress));
186             } else {
187                 rename0(fromAddress, toAddress);
188             }
189         }
190     }
191     private static native void rename0(long fromAddress, long toAddress)
192         throws UnixException;
193 
194     /**
195      *  renameat(int fromfd, const char* old, int tofd, const char* new)
196      */
197     static void renameat(int fromfd, byte[] from, int tofd, byte[] to) throws UnixException {
198         try (NativeBuffer fromBuffer = NativeBuffers.asNativeBuffer(from);
199              NativeBuffer toBuffer = NativeBuffers.asNativeBuffer(to)) {
200             long fromAddress = fromBuffer.address();
201             long toAddress = toBuffer.address();
202             if (Thread.currentThread().isVirtual()) {
203                 Blocker.managedBlock(() -> renameat0(fromfd, fromAddress, tofd, toAddress));
204             } else {
205                 renameat0(fromfd, fromAddress, tofd, toAddress);
206             }
207         }
208     }
209     private static native void renameat0(int fromfd, long fromAddress, int tofd, long toAddress)
210         throws UnixException;
211 
212     /**
213      * mkdir(const char* path, mode_t mode)
214      */
215     static void mkdir(UnixPath path, int mode) throws UnixException {
216         try (NativeBuffer buffer = copyToNativeBuffer(path)) {
217             if (Thread.currentThread().isVirtual()) {
218                 Blocker.managedBlock(() -> mkdir0(buffer.address(), mode));
219             } else {
220                 mkdir0(buffer.address(), mode);
221             }
222         }
223     }
224     private static native void mkdir0(long pathAddress, int mode) throws UnixException;
225 
226     /**
227      * rmdir(const char* path)
228      */
229     static void rmdir(UnixPath path) throws UnixException {
230         try (NativeBuffer buffer = copyToNativeBuffer(path)) {
231             if (Thread.currentThread().isVirtual()) {
232                 Blocker.managedBlock(() -> rmdir0(buffer.address()));
233             } else {
234                 rmdir0(buffer.address());
235             }
236         }
237     }
238     private static native void rmdir0(long pathAddress) throws UnixException;
239 
240     /**
241      * readlink(const char* path, char* buf, size_t bufsize)
242      *
243      * @return  link target
244      */
245     static byte[] readlink(UnixPath path) throws UnixException {
246         try (NativeBuffer buffer = copyToNativeBuffer(path)) {
247             if (Thread.currentThread().isVirtual()) {
248                 return Blocker.managedBlock(() -> readlink0(buffer.address()));
249             } else {
250                 return readlink0(buffer.address());
251             }
252         }
253     }
254     private static native byte[] readlink0(long pathAddress) throws UnixException;
255 
256     /**
257      * realpath(const char* path, char* resolved_name)
258      *
259      * @return  resolved path
260      */
261     static byte[] realpath(UnixPath path) throws UnixException {
262         try (NativeBuffer buffer = copyToNativeBuffer(path)) {
263             if (Thread.currentThread().isVirtual()) {
264                 return Blocker.managedBlock(() -> realpath0(buffer.address()));
265             } else {
266                 return realpath0(buffer.address());
267             }
268         }
269     }
270     private static native byte[] realpath0(long pathAddress) throws UnixException;
271 
272     /**
273      * symlink(const char* name1, const char* name2)
274      */
275     static void symlink(byte[] name1, UnixPath name2) throws UnixException {
276         try (NativeBuffer targetBuffer = NativeBuffers.asNativeBuffer(name1);
277              NativeBuffer linkBuffer = copyToNativeBuffer(name2)) {
278             long targetAddress = targetBuffer.address();
279             long linkAddress = linkBuffer.address();
280             if (Thread.currentThread().isVirtual()) {
281                 Blocker.managedBlock(() -> symlink0(targetAddress, linkAddress));
282             } else {
283                 symlink0(targetAddress, linkAddress);
284             }
285         }
286     }
287     private static native void symlink0(long name1, long name2)
288         throws UnixException;
289 
290     /**
291      * stat(const char* path, struct stat* buf)
292      */
293     static void stat(UnixPath path, UnixFileAttributes attrs) throws UnixException {
294         try (NativeBuffer buffer = copyToNativeBuffer(path)) {
295             if (Thread.currentThread().isVirtual()) {
296                 Blocker.managedBlock(() -> stat0(buffer.address(), attrs));
297             } else {
298                 stat0(buffer.address(), attrs);
299             }
300         }
301     }
302     private static native void stat0(long pathAddress, UnixFileAttributes attrs)
303         throws UnixException;
304 
305 
306     /**
307      * stat(const char* path, struct stat* buf)
308      *
309      * @return st_mode (file type and mode) or 0 if an error occurs.
310      */
311     static int stat(UnixPath path) {
312         try (NativeBuffer buffer = copyToNativeBuffer(path)) {
313             if (Thread.currentThread().isVirtual()) {
314                 return Blocker.managedBlock(() -> stat1(buffer.address()));
315             } else {
316                 return stat1(buffer.address());
317             }
318         }
319     }
320     private static native int stat1(long pathAddress);
321 
322 
323     /**
324      * lstat(const char* path, struct stat* buf)
325      */
326     static void lstat(UnixPath path, UnixFileAttributes attrs) throws UnixException {
327         try (NativeBuffer buffer = copyToNativeBuffer(path)) {
328             if (Thread.currentThread().isVirtual()) {
329                 Blocker.managedBlock(() -> lstat0(buffer.address(), attrs));
330             } else {
331                 lstat0(buffer.address(), attrs);
332             }
333         }
334     }
335     private static native void lstat0(long pathAddress, UnixFileAttributes attrs)
336         throws UnixException;
337 
338     /**
339      * fstat(int filedes, struct stat* buf)
340      */
341     static void fstat(int fd, UnixFileAttributes attrs) throws UnixException {
342         if (Thread.currentThread().isVirtual()) {
343             Blocker.managedBlock(() -> fstat0(fd, attrs));
344         } else {
345             fstat0(fd, attrs);
346         }
347     }
348     private static native void fstat0(int fd, UnixFileAttributes attrs)
349         throws UnixException;
350 
351     /**
352      * fstatat(int filedes,const char* path,  struct stat* buf, int flag)
353      */
354     static void fstatat(int dfd, byte[] path, int flag, UnixFileAttributes attrs)
355         throws UnixException
356     {
357         try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(path)) {
358             if (Thread.currentThread().isVirtual()) {
359                 Blocker.managedBlock(() -> fstatat0(dfd, buffer.address(), flag, attrs));
360             } else {
361                 fstatat0(dfd, buffer.address(), flag, attrs);
362             }
363         }
364     }
365     private static native void fstatat0(int dfd, long pathAddress, int flag,
366         UnixFileAttributes attrs) throws UnixException;
367 
368     /**
369      * chown(const char* path, uid_t owner, gid_t group)
370      */
371     static void chown(UnixPath path, int uid, int gid) throws UnixException {
372         try (NativeBuffer buffer = copyToNativeBuffer(path)) {
373             if (Thread.currentThread().isVirtual()) {
374                 Blocker.managedBlock(() -> chown0(buffer.address(), uid, gid));
375             } else {
376                 chown0(buffer.address(), uid, gid);
377             }
378         }
379     }
380     private static native void chown0(long pathAddress, int uid, int gid)
381         throws UnixException;
382 
383     /**
384      * lchown(const char* path, uid_t owner, gid_t group)
385      */
386     static void lchown(UnixPath path, int uid, int gid) throws UnixException {
387         try (NativeBuffer buffer = copyToNativeBuffer(path)) {
388             if (Thread.currentThread().isVirtual()) {
389                 Blocker.managedBlock(() -> lchown0(buffer.address(), uid, gid));
390             } else {
391                 lchown0(buffer.address(), uid, gid);
392             }
393         }
394     }
395     private static native void lchown0(long pathAddress, int uid, int gid)
396         throws UnixException;
397 
398     /**
399      * fchown(int filedes, uid_t owner, gid_t group)
400      */
401     static void fchown(int fd, int uid, int gid) throws UnixException {
402         if (Thread.currentThread().isVirtual()) {
403             Blocker.managedBlock(() -> fchown0(fd, uid, gid));
404         } else {
405             fchown0(fd, uid, gid);
406         }
407     }
408     static native void fchown0(int fd, int uid, int gid) throws UnixException;
409 
410     /**
411      * chmod(const char* path, mode_t mode)
412      */
413     static void chmod(UnixPath path, int mode) throws UnixException {
414         try (NativeBuffer buffer = copyToNativeBuffer(path)) {
415             if (Thread.currentThread().isVirtual()) {
416                 Blocker.managedBlock(() -> chmod0(buffer.address(), mode));
417             } else {
418                 chmod0(buffer.address(), mode);
419             }
420         }
421     }
422     private static native void chmod0(long pathAddress, int mode)
423         throws UnixException;
424 
425     /**
426      * fchmod(int fildes, mode_t mode)
427      */
428     static void fchmod(int fd, int mode) throws UnixException {
429         if (Thread.currentThread().isVirtual()) {
430             Blocker.managedBlock(() -> fchmod0(fd, mode));
431         } else {
432             fchmod0(fd, mode);
433         }
434     }
435     private static native void fchmod0(int fd, int mode) throws UnixException;
436 
437     /**
438      * utimes(const char* path, const struct timeval times[2])
439      */
440     static void utimes(UnixPath path, long times0, long times1)
441         throws UnixException
442     {
443         try (NativeBuffer buffer = copyToNativeBuffer(path)) {
444             if (Thread.currentThread().isVirtual()) {
445                 Blocker.managedBlock(() -> utimes0(buffer.address(), times0, times1));
446             } else {
447                 utimes0(buffer.address(), times0, times1);
448             }
449         }
450     }
451     private static native void utimes0(long pathAddress, long times0, long times1)
452         throws UnixException;
453 
454     /**
455      * futimes(int fildes, const struct timeval times[2])
456      */
457     static void futimes(int fd, long times0, long times1) throws UnixException {
458         if (Thread.currentThread().isVirtual()) {
459             Blocker.managedBlock(() -> futimes0(fd, times0, times1));
460         } else {
461             futimes0(fd, times0, times1);
462         }
463     }
464     private static native void futimes0(int fd, long times0, long times1)
465         throws UnixException;
466 
467     /**
468      * futimens(int fildes, const struct timespec times[2])
469      */
470     static void futimens(int fd, long times0, long times1) throws UnixException {
471         if (Thread.currentThread().isVirtual()) {
472             Blocker.managedBlock(() -> futimens0(fd, times0, times1));
473         } else {
474             futimens0(fd, times0, times1);
475         }
476     }
477     private static native void futimens0(int fd, long times0, long times1)
478         throws UnixException;
479 
480     /**
481      * lutimes(const char* path, const struct timeval times[2])
482      */
483     static void lutimes(UnixPath path, long times0, long times1)
484         throws UnixException
485     {
486         try (NativeBuffer buffer = copyToNativeBuffer(path)) {
487             if (Thread.currentThread().isVirtual()) {
488                 Blocker.managedBlock(() -> lutimes0(buffer.address(), times0, times1));
489             } else {
490                 lutimes0(buffer.address(), times0, times1);
491             }
492         }
493     }
494     private static native void lutimes0(long pathAddress, long times0, long times1)
495         throws UnixException;
496 
497     /**
498      * DIR *opendir(const char* dirname)
499      */
500     static long opendir(UnixPath path) throws UnixException {
501         try (NativeBuffer buffer = copyToNativeBuffer(path)) {
502             if (Thread.currentThread().isVirtual()) {
503                 return Blocker.managedBlock(() -> opendir0(buffer.address()));
504             } else {
505                 return opendir0(buffer.address());
506             }
507         }
508     }
509     private static native long opendir0(long pathAddress) throws UnixException;
510 
511     /**
512      * DIR* fdopendir(int filedes)
513      */
514     static native long fdopendir(int dfd) throws UnixException;
515 
516 
517     /**
518      * closedir(DIR* dirp)
519      */
520     static native void closedir(long dir) throws UnixException;
521 
522     /**
523      * struct dirent* readdir(DIR *dirp)
524      *
525      * @return  dirent->d_name
526      */
527     static byte[] readdir(long dir) throws UnixException {
528         if (Thread.currentThread().isVirtual()) {
529             return Blocker.managedBlock(() -> readdir0(dir));
530         } else {
531             return readdir0(dir);
532         }
533     }
534     static native byte[] readdir0(long dir) throws UnixException;
535 
536     /**
537      * size_t read(int fildes, void* buf, size_t nbyte)
538      */
539     static int read(int fildes, long buf, int nbyte) throws UnixException {
540         if (Thread.currentThread().isVirtual()) {
541             return Blocker.managedBlock(() -> read0(fildes, buf, nbyte));
542         } else {
543             return read0(fildes, buf, nbyte);
544         }
545     }
546     private static native int read0(int fildes, long buf, int nbyte) throws UnixException;
547 
548     /**
549      * size_t writeint fildes, void* buf, size_t nbyte)
550      */
551     static int write(int fildes, long buf, int nbyte) throws UnixException {
552         if (Thread.currentThread().isVirtual()) {
553             return Blocker.managedBlock(() -> write0(fildes, buf, nbyte));
554         } else {
555             return write0(fildes, buf, nbyte);
556         }
557     }
558     private static native int write0(int fildes, long buf, int nbyte) throws UnixException;
559 
560     /**
561      * access(const char* path, int amode);
562      */
563     static void access(UnixPath path, int amode) throws UnixException {
564         try (NativeBuffer buffer = copyToNativeBuffer(path)) {
565             if (Thread.currentThread().isVirtual()) {
566                 Blocker.managedBlock(() -> access0(buffer.address(), amode));
567             } else {
568                 access0(buffer.address(), amode);
569             }
570         }
571     }
572     private static native void access0(long pathAddress, int amode) throws UnixException;
573 
574     /**
575      * access(constant char* path, F_OK)
576      *
577      * @return true if the file exists, false otherwise
578      */
579     static boolean exists(UnixPath path) {
580         try (NativeBuffer buffer = copyToNativeBuffer(path)) {
581             if (Thread.currentThread().isVirtual()) {
582                 return Blocker.managedBlock(() -> exists0(buffer.address()));
583             } else {
584                 return exists0(buffer.address());
585             }
586         }
587     }
588     private static native boolean exists0(long pathAddress);
589 

590     /**
591      * struct passwd *getpwuid(uid_t uid);
592      *
593      * @return  passwd->pw_name
594      */
595     static native byte[] getpwuid(int uid) throws UnixException;
596 
597     /**
598      * struct group *getgrgid(gid_t gid);
599      *
600      * @return  group->gr_name
601      */
602     static native byte[] getgrgid(int gid) throws UnixException;
603 
604     /**
605      * struct passwd *getpwnam(const char *name);
606      *
607      * @return  passwd->pw_uid
608      */
609     static int getpwnam(String name) throws UnixException {
610         try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(Util.toBytes(name))) {
611             if (Thread.currentThread().isVirtual()) {
612                 return Blocker.managedBlock(() -> getpwnam0(buffer.address()));
613             } else {
614                 return getpwnam0(buffer.address());
615             }
616         }
617     }
618     private static native int getpwnam0(long nameAddress) throws UnixException;
619 
620     /**
621      * struct group *getgrnam(const char *name);
622      *
623      * @return  group->gr_name
624      */
625     static int getgrnam(String name) throws UnixException {
626         try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(Util.toBytes(name))) {
627             if (Thread.currentThread().isVirtual()) {
628                 return Blocker.managedBlock(() -> getgrnam0(buffer.address()));
629             } else {
630                 return getgrnam0(buffer.address());
631             }
632         }
633     }
634     private static native int getgrnam0(long nameAddress) throws UnixException;
635 
636     /**
637      * statvfs(const char* path, struct statvfs *buf)
638      */
639     static void statvfs(UnixPath path, UnixFileStoreAttributes attrs)
640         throws UnixException
641     {
642         try (NativeBuffer buffer = copyToNativeBuffer(path)) {
643             if (Thread.currentThread().isVirtual()) {
644                 Blocker.managedBlock(() -> statvfs0(buffer.address(), attrs));
645             } else {
646                 statvfs0(buffer.address(), attrs);
647             }
648         }
649     }
650     private static native void statvfs0(long pathAddress, UnixFileStoreAttributes attrs)
651         throws UnixException;
652 
653     /**
654      * char* strerror(int errnum)
655      */
656     static native byte[] strerror(int errnum);
657 
658     /**
659      * ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size);
660      */
661     static int fgetxattr(int filedes, byte[] name, long valueAddress, int valueLen)
662         throws UnixException
663     {
664         try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(name)) {
665             if (Thread.currentThread().isVirtual()) {
666                 return Blocker.managedBlock(() ->
667                         fgetxattr0(filedes, buffer.address(), valueAddress, valueLen));
668             } else {
669                 return fgetxattr0(filedes, buffer.address(), valueAddress, valueLen);
670             }
671         }
672     }
673 
674     private static native int fgetxattr0(int filedes, long nameAddress,
675         long valueAddress, int valueLen) throws UnixException;
676 
677     /**
678      *  fsetxattr(int filedes, const char *name, const void *value, size_t size, int flags);
679      */
680     static void fsetxattr(int filedes, byte[] name, long valueAddress, int valueLen)
681         throws UnixException
682     {
683         try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(name)) {
684             if (Thread.currentThread().isVirtual()) {
685                 Blocker.managedBlock(() ->
686                         fsetxattr0(filedes, buffer.address(), valueAddress, valueLen));
687             } else {
688                 fsetxattr0(filedes, buffer.address(), valueAddress, valueLen);
689             }
690         }
691     }
692 
693     private static native void fsetxattr0(int filedes, long nameAddress,
694         long valueAddress, int valueLen) throws UnixException;
695 
696     /**
697      * fremovexattr(int filedes, const char *name);
698      */
699     static void fremovexattr(int filedes, byte[] name) throws UnixException {
700         try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(name)) {
701             if (Thread.currentThread().isVirtual()) {
702                 Blocker.managedBlock(() -> fremovexattr0(filedes, buffer.address()));
703             } else {
704                 fremovexattr0(filedes, buffer.address());
705             }
706         }
707     }
708 
709     private static native void fremovexattr0(int filedes, long nameAddress)
710         throws UnixException;
711 
712     /**
713      * size_t flistxattr(int filedes, const char *list, size_t size)
714      */
715     static native int flistxattr(int filedes, long listAddress, int size)
716         throws UnixException;
717 
718     /**
719      * Capabilities
720      */
721     private static final int SUPPORTS_OPENAT        = 1 << 1;  // syscalls
722     private static final int SUPPORTS_FUTIMES       = 1 << 2;
723     private static final int SUPPORTS_FUTIMENS      = 1 << 3;
724     private static final int SUPPORTS_LUTIMES       = 1 << 4;
725     private static final int SUPPORTS_XATTR         = 1 << 5;
< prev index next >