893N/A/*
2362N/A * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
893N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
893N/A *
893N/A * This code is free software; you can redistribute it and/or modify it
893N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
893N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
893N/A *
893N/A * This code is distributed in the hope that it will be useful, but WITHOUT
893N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
893N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
893N/A * version 2 for more details (a copy is included in the LICENSE file that
893N/A * accompanied this code).
893N/A *
893N/A * You should have received a copy of the GNU General Public License version
893N/A * 2 along with this work; if not, write to the Free Software Foundation,
893N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
893N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
893N/A */
893N/A
893N/Apackage sun.nio.fs;
893N/A
893N/Aimport java.security.AccessController;
893N/Aimport java.security.PrivilegedAction;
893N/A
893N/A/**
893N/A * Unix system and library calls.
893N/A */
893N/A
893N/Aclass UnixNativeDispatcher {
893N/A protected UnixNativeDispatcher() { }
893N/A
893N/A // returns a NativeBuffer containing the given path
893N/A private static NativeBuffer copyToNativeBuffer(UnixPath path) {
893N/A byte[] cstr = path.getByteArrayForSysCalls();
893N/A int size = cstr.length + 1;
893N/A NativeBuffer buffer = NativeBuffers.getNativeBufferFromCache(size);
893N/A if (buffer == null) {
893N/A buffer = NativeBuffers.allocNativeBuffer(size);
893N/A } else {
893N/A // buffer already contains the path
893N/A if (buffer.owner() == path)
893N/A return buffer;
893N/A }
893N/A NativeBuffers.copyCStringToNativeBuffer(cstr, buffer);
893N/A buffer.setOwner(path);
893N/A return buffer;
893N/A }
893N/A
893N/A /**
893N/A * char *getcwd(char *buf, size_t size);
893N/A */
893N/A static native byte[] getcwd();
893N/A
893N/A /**
893N/A * int dup(int filedes)
893N/A */
893N/A static native int dup(int filedes) throws UnixException;
893N/A
893N/A /**
893N/A * int open(const char* path, int oflag, mode_t mode)
893N/A */
893N/A static int open(UnixPath path, int flags, int mode) throws UnixException {
893N/A NativeBuffer buffer = copyToNativeBuffer(path);
893N/A try {
893N/A return open0(buffer.address(), flags, mode);
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native int open0(long pathAddress, int flags, int mode)
893N/A throws UnixException;
893N/A
893N/A /**
893N/A * int openat(int dfd, const char* path, int oflag, mode_t mode)
893N/A */
893N/A static int openat(int dfd, byte[] path, int flags, int mode) throws UnixException {
893N/A NativeBuffer buffer = NativeBuffers.asNativeBuffer(path);
893N/A try {
893N/A return openat0(dfd, buffer.address(), flags, mode);
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native int openat0(int dfd, long pathAddress, int flags, int mode)
893N/A throws UnixException;
893N/A
893N/A /**
893N/A * close(int filedes)
893N/A */
893N/A static native void close(int fd);
893N/A
893N/A /**
893N/A * FILE* fopen(const char *filename, const char* mode);
893N/A */
893N/A static long fopen(UnixPath filename, String mode) throws UnixException {
893N/A NativeBuffer pathBuffer = copyToNativeBuffer(filename);
893N/A NativeBuffer modeBuffer = NativeBuffers.asNativeBuffer(mode.getBytes());
893N/A try {
893N/A return fopen0(pathBuffer.address(), modeBuffer.address());
893N/A } finally {
893N/A modeBuffer.release();
893N/A pathBuffer.release();
893N/A }
893N/A }
893N/A private static native long fopen0(long pathAddress, long modeAddress)
893N/A throws UnixException;
893N/A
893N/A /**
893N/A * fclose(FILE* stream)
893N/A */
893N/A static native void fclose(long stream) throws UnixException;
893N/A
893N/A /**
893N/A * link(const char* existing, const char* new)
893N/A */
893N/A static void link(UnixPath existing, UnixPath newfile) throws UnixException {
893N/A NativeBuffer existingBuffer = copyToNativeBuffer(existing);
893N/A NativeBuffer newBuffer = copyToNativeBuffer(newfile);
893N/A try {
893N/A link0(existingBuffer.address(), newBuffer.address());
893N/A } finally {
893N/A newBuffer.release();
893N/A existingBuffer.release();
893N/A }
893N/A }
893N/A private static native void link0(long existingAddress, long newAddress)
893N/A throws UnixException;
893N/A
893N/A /**
893N/A * unlink(const char* path)
893N/A */
893N/A static void unlink(UnixPath path) throws UnixException {
893N/A NativeBuffer buffer = copyToNativeBuffer(path);
893N/A try {
893N/A unlink0(buffer.address());
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native void unlink0(long pathAddress) throws UnixException;
893N/A
893N/A /**
893N/A * unlinkat(int dfd, const char* path, int flag)
893N/A */
893N/A static void unlinkat(int dfd, byte[] path, int flag) throws UnixException {
893N/A NativeBuffer buffer = NativeBuffers.asNativeBuffer(path);
893N/A try {
893N/A unlinkat0(dfd, buffer.address(), flag);
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native void unlinkat0(int dfd, long pathAddress, int flag)
893N/A throws UnixException;
893N/A
893N/A /**
893N/A * mknod(const char* path, mode_t mode, dev_t dev)
893N/A */
893N/A static void mknod(UnixPath path, int mode, long dev) throws UnixException {
893N/A NativeBuffer buffer = copyToNativeBuffer(path);
893N/A try {
893N/A mknod0(buffer.address(), mode, dev);
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native void mknod0(long pathAddress, int mode, long dev)
893N/A throws UnixException;
893N/A
893N/A /**
893N/A * rename(const char* old, const char* new)
893N/A */
893N/A static void rename(UnixPath from, UnixPath to) throws UnixException {
893N/A NativeBuffer fromBuffer = copyToNativeBuffer(from);
893N/A NativeBuffer toBuffer = copyToNativeBuffer(to);
893N/A try {
893N/A rename0(fromBuffer.address(), toBuffer.address());
893N/A } finally {
893N/A toBuffer.release();
893N/A fromBuffer.release();
893N/A }
893N/A }
893N/A private static native void rename0(long fromAddress, long toAddress)
893N/A throws UnixException;
893N/A
893N/A /**
893N/A * renameat(int fromfd, const char* old, int tofd, const char* new)
893N/A */
893N/A static void renameat(int fromfd, byte[] from, int tofd, byte[] to) throws UnixException {
893N/A NativeBuffer fromBuffer = NativeBuffers.asNativeBuffer(from);
893N/A NativeBuffer toBuffer = NativeBuffers.asNativeBuffer(to);
893N/A try {
893N/A renameat0(fromfd, fromBuffer.address(), tofd, toBuffer.address());
893N/A } finally {
893N/A toBuffer.release();
893N/A fromBuffer.release();
893N/A }
893N/A }
893N/A private static native void renameat0(int fromfd, long fromAddress, int tofd, long toAddress)
893N/A throws UnixException;
893N/A
893N/A /**
893N/A * mkdir(const char* path, mode_t mode)
893N/A */
893N/A static void mkdir(UnixPath path, int mode) throws UnixException {
893N/A NativeBuffer buffer = copyToNativeBuffer(path);
893N/A try {
893N/A mkdir0(buffer.address(), mode);
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native void mkdir0(long pathAddress, int mode) throws UnixException;
893N/A
893N/A /**
893N/A * rmdir(const char* path)
893N/A */
893N/A static void rmdir(UnixPath path) throws UnixException {
893N/A NativeBuffer buffer = copyToNativeBuffer(path);
893N/A try {
893N/A rmdir0(buffer.address());
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native void rmdir0(long pathAddress) throws UnixException;
893N/A
893N/A /**
893N/A * readlink(const char* path, char* buf, size_t bufsize)
893N/A *
893N/A * @return link target
893N/A */
893N/A static byte[] readlink(UnixPath path) throws UnixException {
893N/A NativeBuffer buffer = copyToNativeBuffer(path);
893N/A try {
893N/A return readlink0(buffer.address());
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native byte[] readlink0(long pathAddress) throws UnixException;
893N/A
893N/A /**
893N/A * realpath(const char* path, char* resolved_name)
893N/A *
893N/A * @return resolved path
893N/A */
893N/A static byte[] realpath(UnixPath path) throws UnixException {
893N/A NativeBuffer buffer = copyToNativeBuffer(path);
893N/A try {
893N/A return realpath0(buffer.address());
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native byte[] realpath0(long pathAddress) throws UnixException;
893N/A
893N/A /**
893N/A * symlink(const char* name1, const char* name2)
893N/A */
893N/A static void symlink(byte[] name1, UnixPath name2) throws UnixException {
893N/A NativeBuffer targetBuffer = NativeBuffers.asNativeBuffer(name1);
893N/A NativeBuffer linkBuffer = copyToNativeBuffer(name2);
893N/A try {
893N/A symlink0(targetBuffer.address(), linkBuffer.address());
893N/A } finally {
893N/A linkBuffer.release();
893N/A targetBuffer.release();
893N/A }
893N/A }
893N/A private static native void symlink0(long name1, long name2)
893N/A throws UnixException;
893N/A
893N/A /**
893N/A * stat(const char* path, struct stat* buf)
893N/A */
893N/A static void stat(UnixPath path, UnixFileAttributes attrs) throws UnixException {
893N/A NativeBuffer buffer = copyToNativeBuffer(path);
893N/A try {
893N/A stat0(buffer.address(), attrs);
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native void stat0(long pathAddress, UnixFileAttributes attrs)
893N/A throws UnixException;
893N/A
893N/A /**
893N/A * lstat(const char* path, struct stat* buf)
893N/A */
893N/A static void lstat(UnixPath path, UnixFileAttributes attrs) throws UnixException {
893N/A NativeBuffer buffer = copyToNativeBuffer(path);
893N/A try {
893N/A lstat0(buffer.address(), attrs);
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native void lstat0(long pathAddress, UnixFileAttributes attrs)
893N/A throws UnixException;
893N/A
893N/A /**
893N/A * fstat(int filedes, struct stat* buf)
893N/A */
893N/A static native void fstat(int fd, UnixFileAttributes attrs) throws UnixException;
893N/A
893N/A /**
893N/A * fstatat(int filedes,const char* path, struct stat* buf, int flag)
893N/A */
893N/A static void fstatat(int dfd, byte[] path, int flag, UnixFileAttributes attrs)
893N/A throws UnixException
893N/A {
893N/A NativeBuffer buffer = NativeBuffers.asNativeBuffer(path);
893N/A try {
893N/A fstatat0(dfd, buffer.address(), flag, attrs);
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native void fstatat0(int dfd, long pathAddress, int flag,
893N/A UnixFileAttributes attrs) throws UnixException;
893N/A
893N/A /**
893N/A * chown(const char* path, uid_t owner, gid_t group)
893N/A */
893N/A static void chown(UnixPath path, int uid, int gid) throws UnixException {
893N/A NativeBuffer buffer = copyToNativeBuffer(path);
893N/A try {
893N/A chown0(buffer.address(), uid, gid);
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native void chown0(long pathAddress, int uid, int gid)
893N/A throws UnixException;
893N/A
893N/A /**
893N/A * lchown(const char* path, uid_t owner, gid_t group)
893N/A */
893N/A static void lchown(UnixPath path, int uid, int gid) throws UnixException {
893N/A NativeBuffer buffer = copyToNativeBuffer(path);
893N/A try {
893N/A lchown0(buffer.address(), uid, gid);
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native void lchown0(long pathAddress, int uid, int gid)
893N/A throws UnixException;
893N/A
893N/A /**
893N/A * fchown(int filedes, uid_t owner, gid_t group)
893N/A */
893N/A static native void fchown(int fd, int uid, int gid) throws UnixException;
893N/A
893N/A /**
893N/A * chmod(const char* path, mode_t mode)
893N/A */
893N/A static void chmod(UnixPath path, int mode) throws UnixException {
893N/A NativeBuffer buffer = copyToNativeBuffer(path);
893N/A try {
893N/A chmod0(buffer.address(), mode);
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native void chmod0(long pathAddress, int mode)
893N/A throws UnixException;
893N/A
893N/A /**
893N/A * fchmod(int fildes, mode_t mode)
893N/A */
893N/A static native void fchmod(int fd, int mode) throws UnixException;
893N/A
893N/A /**
893N/A * utimes(conar char* path, const struct timeval times[2])
893N/A */
893N/A static void utimes(UnixPath path, long times0, long times1)
893N/A throws UnixException
893N/A {
893N/A NativeBuffer buffer = copyToNativeBuffer(path);
893N/A try {
893N/A utimes0(buffer.address(), times0, times1);
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native void utimes0(long pathAddress, long times0, long times1)
893N/A throws UnixException;
893N/A
893N/A /**
893N/A * futimes(int fildes,, const struct timeval times[2])
893N/A */
893N/A static native void futimes(int fd, long times0, long times1) throws UnixException;
893N/A
893N/A /**
893N/A * DIR *opendir(const char* dirname)
893N/A */
893N/A static long opendir(UnixPath path) throws UnixException {
893N/A NativeBuffer buffer = copyToNativeBuffer(path);
893N/A try {
893N/A return opendir0(buffer.address());
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native long opendir0(long pathAddress) throws UnixException;
893N/A
893N/A /**
893N/A * DIR* fdopendir(int filedes)
893N/A */
893N/A static native long fdopendir(int dfd) throws UnixException;
893N/A
893N/A
893N/A /**
893N/A * closedir(DIR* dirp)
893N/A */
893N/A static native void closedir(long dir) throws UnixException;
893N/A
893N/A /**
893N/A * struct dirent* readdir(DIR *dirp)
893N/A *
893N/A * @return dirent->d_name
893N/A */
893N/A static native byte[] readdir(long dir) throws UnixException;
893N/A
893N/A /**
893N/A * size_t read(int fildes, void* buf, size_t nbyte)
893N/A */
893N/A static native int read(int fildes, long buf, int nbyte) throws UnixException;
893N/A
893N/A /**
893N/A * size_t writeint fildes, void* buf, size_t nbyte)
893N/A */
893N/A static native int write(int fildes, long buf, int nbyte) throws UnixException;
893N/A
893N/A /**
893N/A * access(const char* path, int amode);
893N/A */
893N/A static void access(UnixPath path, int amode) throws UnixException {
893N/A NativeBuffer buffer = copyToNativeBuffer(path);
893N/A try {
893N/A access0(buffer.address(), amode);
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native void access0(long pathAddress, int amode) throws UnixException;
893N/A
893N/A /**
893N/A * struct passwd *getpwuid(uid_t uid);
893N/A *
893N/A * @return passwd->pw_name
893N/A */
893N/A static native byte[] getpwuid(int uid) throws UnixException;
893N/A
893N/A /**
893N/A * struct group *getgrgid(gid_t gid);
893N/A *
893N/A * @return group->gr_name
893N/A */
893N/A static native byte[] getgrgid(int gid) throws UnixException;
893N/A
893N/A /**
893N/A * struct passwd *getpwnam(const char *name);
893N/A *
893N/A * @return passwd->pw_uid
893N/A */
893N/A static int getpwnam(String name) throws UnixException {
893N/A NativeBuffer buffer = NativeBuffers.asNativeBuffer(name.getBytes());
893N/A try {
893N/A return getpwnam0(buffer.address());
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native int getpwnam0(long nameAddress) throws UnixException;
893N/A
893N/A /**
893N/A * struct group *getgrnam(const char *name);
893N/A *
893N/A * @return group->gr_name
893N/A */
893N/A static int getgrnam(String name) throws UnixException {
893N/A NativeBuffer buffer = NativeBuffers.asNativeBuffer(name.getBytes());
893N/A try {
893N/A return getgrnam0(buffer.address());
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native int getgrnam0(long nameAddress) throws UnixException;
893N/A
893N/A /**
893N/A * statvfs(const char* path, struct statvfs *buf)
893N/A */
893N/A static void statvfs(UnixPath path, UnixFileStoreAttributes attrs)
893N/A throws UnixException
893N/A {
893N/A NativeBuffer buffer = copyToNativeBuffer(path);
893N/A try {
893N/A statvfs0(buffer.address(), attrs);
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native void statvfs0(long pathAddress, UnixFileStoreAttributes attrs)
893N/A throws UnixException;
893N/A
893N/A /**
893N/A * long int pathconf(const char *path, int name);
893N/A */
893N/A static long pathconf(UnixPath path, int name) throws UnixException {
893N/A NativeBuffer buffer = copyToNativeBuffer(path);
893N/A try {
893N/A return pathconf0(buffer.address(), name);
893N/A } finally {
893N/A buffer.release();
893N/A }
893N/A }
893N/A private static native long pathconf0(long pathAddress, int name)
893N/A throws UnixException;
893N/A
893N/A /**
893N/A * long fpathconf(int fildes, int name);
893N/A */
893N/A static native long fpathconf(int filedes, int name) throws UnixException;
893N/A
893N/A /**
893N/A * char* strerror(int errnum)
893N/A */
893N/A static native byte[] strerror(int errnum);
893N/A
1319N/A // indicates if openat, unlinkat, etc. is supported
1319N/A private static final boolean hasAtSysCalls;
1319N/A static boolean supportsAtSysCalls() {
1319N/A return hasAtSysCalls;
1319N/A }
1319N/A
5193N/A static boolean supportsNoFollowLinks() {
5193N/A return UnixConstants.O_NOFOLLOW != 0;
5193N/A }
5193N/A
1319N/A // initialize syscalls and fieldIDs
1319N/A private static native int init();
1319N/A
1319N/A // flags returned by init to indicate capabilities
1319N/A private static final int HAS_AT_SYSCALLS = 0x1;
893N/A
893N/A static {
893N/A AccessController.doPrivileged(new PrivilegedAction<Void>() {
893N/A public Void run() {
893N/A System.loadLibrary("nio");
893N/A return null;
893N/A }});
1319N/A int flags = init();
1319N/A
1319N/A hasAtSysCalls = (flags & HAS_AT_SYSCALLS) > 0;
893N/A }
893N/A}