Path: blob/master/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java
41137 views
/*1* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.nio.fs;2627/**28* Unix system and library calls.29*/3031class UnixNativeDispatcher {32protected UnixNativeDispatcher() { }3334// returns a NativeBuffer containing the given path35static NativeBuffer copyToNativeBuffer(UnixPath path) {36byte[] cstr = path.getByteArrayForSysCalls();37int size = cstr.length + 1;38NativeBuffer buffer = NativeBuffers.getNativeBufferFromCache(size);39if (buffer == null) {40buffer = NativeBuffers.allocNativeBuffer(size);41} else {42// buffer already contains the path43if (buffer.owner() == path)44return buffer;45}46NativeBuffers.copyCStringToNativeBuffer(cstr, buffer);47buffer.setOwner(path);48return buffer;49}5051/**52* char *getcwd(char *buf, size_t size);53*/54static native byte[] getcwd();5556/**57* int dup(int filedes)58*/59static native int dup(int filedes) throws UnixException;6061/**62* int open(const char* path, int oflag, mode_t mode)63*/64static int open(UnixPath path, int flags, int mode) throws UnixException {65NativeBuffer buffer = copyToNativeBuffer(path);66try {67return open0(buffer.address(), flags, mode);68} finally {69buffer.release();70}71}72private static native int open0(long pathAddress, int flags, int mode)73throws UnixException;7475/**76* int openat(int dfd, const char* path, int oflag, mode_t mode)77*/78static int openat(int dfd, byte[] path, int flags, int mode) throws UnixException {79NativeBuffer buffer = NativeBuffers.asNativeBuffer(path);80try {81return openat0(dfd, buffer.address(), flags, mode);82} finally {83buffer.release();84}85}86private static native int openat0(int dfd, long pathAddress, int flags, int mode)87throws UnixException;8889/**90* close(int filedes). If fd is -1 this is a no-op.91*/92static void close(int fd) {93if (fd != -1) {94close0(fd);95}96}97private static native void close0(int fd);9899/**100* void rewind(FILE* stream);101*/102static native void rewind(long stream) throws UnixException;103104/**105* ssize_t getline(char **lineptr, size_t *n, FILE *stream);106*/107static native int getlinelen(long stream) throws UnixException;108109/**110* link(const char* existing, const char* new)111*/112static void link(UnixPath existing, UnixPath newfile) throws UnixException {113NativeBuffer existingBuffer = copyToNativeBuffer(existing);114NativeBuffer newBuffer = copyToNativeBuffer(newfile);115try {116link0(existingBuffer.address(), newBuffer.address());117} finally {118newBuffer.release();119existingBuffer.release();120}121}122private static native void link0(long existingAddress, long newAddress)123throws UnixException;124125/**126* unlink(const char* path)127*/128static void unlink(UnixPath path) throws UnixException {129NativeBuffer buffer = copyToNativeBuffer(path);130try {131unlink0(buffer.address());132} finally {133buffer.release();134}135}136private static native void unlink0(long pathAddress) throws UnixException;137138/**139* unlinkat(int dfd, const char* path, int flag)140*/141static void unlinkat(int dfd, byte[] path, int flag) throws UnixException {142NativeBuffer buffer = NativeBuffers.asNativeBuffer(path);143try {144unlinkat0(dfd, buffer.address(), flag);145} finally {146buffer.release();147}148}149private static native void unlinkat0(int dfd, long pathAddress, int flag)150throws UnixException;151152/**153* mknod(const char* path, mode_t mode, dev_t dev)154*/155static void mknod(UnixPath path, int mode, long dev) throws UnixException {156NativeBuffer buffer = copyToNativeBuffer(path);157try {158mknod0(buffer.address(), mode, dev);159} finally {160buffer.release();161}162}163private static native void mknod0(long pathAddress, int mode, long dev)164throws UnixException;165166/**167* rename(const char* old, const char* new)168*/169static void rename(UnixPath from, UnixPath to) throws UnixException {170NativeBuffer fromBuffer = copyToNativeBuffer(from);171NativeBuffer toBuffer = copyToNativeBuffer(to);172try {173rename0(fromBuffer.address(), toBuffer.address());174} finally {175toBuffer.release();176fromBuffer.release();177}178}179private static native void rename0(long fromAddress, long toAddress)180throws UnixException;181182/**183* renameat(int fromfd, const char* old, int tofd, const char* new)184*/185static void renameat(int fromfd, byte[] from, int tofd, byte[] to) throws UnixException {186NativeBuffer fromBuffer = NativeBuffers.asNativeBuffer(from);187NativeBuffer toBuffer = NativeBuffers.asNativeBuffer(to);188try {189renameat0(fromfd, fromBuffer.address(), tofd, toBuffer.address());190} finally {191toBuffer.release();192fromBuffer.release();193}194}195private static native void renameat0(int fromfd, long fromAddress, int tofd, long toAddress)196throws UnixException;197198/**199* mkdir(const char* path, mode_t mode)200*/201static void mkdir(UnixPath path, int mode) throws UnixException {202NativeBuffer buffer = copyToNativeBuffer(path);203try {204mkdir0(buffer.address(), mode);205} finally {206buffer.release();207}208}209private static native void mkdir0(long pathAddress, int mode) throws UnixException;210211/**212* rmdir(const char* path)213*/214static void rmdir(UnixPath path) throws UnixException {215NativeBuffer buffer = copyToNativeBuffer(path);216try {217rmdir0(buffer.address());218} finally {219buffer.release();220}221}222private static native void rmdir0(long pathAddress) throws UnixException;223224/**225* readlink(const char* path, char* buf, size_t bufsize)226*227* @return link target228*/229static byte[] readlink(UnixPath path) throws UnixException {230NativeBuffer buffer = copyToNativeBuffer(path);231try {232return readlink0(buffer.address());233} finally {234buffer.release();235}236}237private static native byte[] readlink0(long pathAddress) throws UnixException;238239/**240* realpath(const char* path, char* resolved_name)241*242* @return resolved path243*/244static byte[] realpath(UnixPath path) throws UnixException {245NativeBuffer buffer = copyToNativeBuffer(path);246try {247return realpath0(buffer.address());248} finally {249buffer.release();250}251}252private static native byte[] realpath0(long pathAddress) throws UnixException;253254/**255* symlink(const char* name1, const char* name2)256*/257static void symlink(byte[] name1, UnixPath name2) throws UnixException {258NativeBuffer targetBuffer = NativeBuffers.asNativeBuffer(name1);259NativeBuffer linkBuffer = copyToNativeBuffer(name2);260try {261symlink0(targetBuffer.address(), linkBuffer.address());262} finally {263linkBuffer.release();264targetBuffer.release();265}266}267private static native void symlink0(long name1, long name2)268throws UnixException;269270/**271* stat(const char* path, struct stat* buf)272*/273static void stat(UnixPath path, UnixFileAttributes attrs) throws UnixException {274NativeBuffer buffer = copyToNativeBuffer(path);275try {276stat0(buffer.address(), attrs);277} finally {278buffer.release();279}280}281private static native void stat0(long pathAddress, UnixFileAttributes attrs)282throws UnixException;283284285/**286* stat(const char* path, struct stat* buf)287*288* @return st_mode (file type and mode) or 0 if an error occurs.289*/290static int stat(UnixPath path) {291NativeBuffer buffer = copyToNativeBuffer(path);292try {293return stat1(buffer.address());294} finally {295buffer.release();296}297}298private static native int stat1(long pathAddress);299300301/**302* lstat(const char* path, struct stat* buf)303*/304static void lstat(UnixPath path, UnixFileAttributes attrs) throws UnixException {305NativeBuffer buffer = copyToNativeBuffer(path);306try {307lstat0(buffer.address(), attrs);308} finally {309buffer.release();310}311}312private static native void lstat0(long pathAddress, UnixFileAttributes attrs)313throws UnixException;314315/**316* fstat(int filedes, struct stat* buf)317*/318static native void fstat(int fd, UnixFileAttributes attrs) throws UnixException;319320/**321* fstatat(int filedes,const char* path, struct stat* buf, int flag)322*/323static void fstatat(int dfd, byte[] path, int flag, UnixFileAttributes attrs)324throws UnixException325{326NativeBuffer buffer = NativeBuffers.asNativeBuffer(path);327try {328fstatat0(dfd, buffer.address(), flag, attrs);329} finally {330buffer.release();331}332}333private static native void fstatat0(int dfd, long pathAddress, int flag,334UnixFileAttributes attrs) throws UnixException;335336/**337* chown(const char* path, uid_t owner, gid_t group)338*/339static void chown(UnixPath path, int uid, int gid) throws UnixException {340NativeBuffer buffer = copyToNativeBuffer(path);341try {342chown0(buffer.address(), uid, gid);343} finally {344buffer.release();345}346}347private static native void chown0(long pathAddress, int uid, int gid)348throws UnixException;349350/**351* lchown(const char* path, uid_t owner, gid_t group)352*/353static void lchown(UnixPath path, int uid, int gid) throws UnixException {354NativeBuffer buffer = copyToNativeBuffer(path);355try {356lchown0(buffer.address(), uid, gid);357} finally {358buffer.release();359}360}361private static native void lchown0(long pathAddress, int uid, int gid)362throws UnixException;363364/**365* fchown(int filedes, uid_t owner, gid_t group)366*/367static native void fchown(int fd, int uid, int gid) throws UnixException;368369/**370* chmod(const char* path, mode_t mode)371*/372static void chmod(UnixPath path, int mode) throws UnixException {373NativeBuffer buffer = copyToNativeBuffer(path);374try {375chmod0(buffer.address(), mode);376} finally {377buffer.release();378}379}380private static native void chmod0(long pathAddress, int mode)381throws UnixException;382383/**384* fchmod(int fildes, mode_t mode)385*/386static native void fchmod(int fd, int mode) throws UnixException;387388/**389* utimes(const char* path, const struct timeval times[2])390*/391static void utimes(UnixPath path, long times0, long times1)392throws UnixException393{394NativeBuffer buffer = copyToNativeBuffer(path);395try {396utimes0(buffer.address(), times0, times1);397} finally {398buffer.release();399}400}401private static native void utimes0(long pathAddress, long times0, long times1)402throws UnixException;403404/**405* futimes(int fildes, const struct timeval times[2])406*/407static native void futimes(int fd, long times0, long times1) throws UnixException;408409/**410* futimens(int fildes, const struct timespec times[2])411*/412static native void futimens(int fd, long times0, long times1) throws UnixException;413414/**415* lutimes(const char* path, const struct timeval times[2])416*/417static void lutimes(UnixPath path, long times0, long times1)418throws UnixException419{420NativeBuffer buffer = copyToNativeBuffer(path);421try {422lutimes0(buffer.address(), times0, times1);423} finally {424buffer.release();425}426}427private static native void lutimes0(long pathAddress, long times0, long times1)428throws UnixException;429430/**431* DIR *opendir(const char* dirname)432*/433static long opendir(UnixPath path) throws UnixException {434NativeBuffer buffer = copyToNativeBuffer(path);435try {436return opendir0(buffer.address());437} finally {438buffer.release();439}440}441private static native long opendir0(long pathAddress) throws UnixException;442443/**444* DIR* fdopendir(int filedes)445*/446static native long fdopendir(int dfd) throws UnixException;447448449/**450* closedir(DIR* dirp)451*/452static native void closedir(long dir) throws UnixException;453454/**455* struct dirent* readdir(DIR *dirp)456*457* @return dirent->d_name458*/459static native byte[] readdir(long dir) throws UnixException;460461/**462* size_t read(int fildes, void* buf, size_t nbyte)463*/464static native int read(int fildes, long buf, int nbyte) throws UnixException;465466/**467* size_t writeint fildes, void* buf, size_t nbyte)468*/469static native int write(int fildes, long buf, int nbyte) throws UnixException;470471/**472* access(const char* path, int amode);473*/474static void access(UnixPath path, int amode) throws UnixException {475NativeBuffer buffer = copyToNativeBuffer(path);476try {477access0(buffer.address(), amode);478} finally {479buffer.release();480}481}482private static native void access0(long pathAddress, int amode) throws UnixException;483484/**485* access(constant char* path, F_OK)486*487* @return true if the file exists, false otherwise488*/489static boolean exists(UnixPath path) {490NativeBuffer buffer = copyToNativeBuffer(path);491try {492return exists0(buffer.address());493} finally {494buffer.release();495}496}497private static native boolean exists0(long pathAddress);498499500/**501* struct passwd *getpwuid(uid_t uid);502*503* @return passwd->pw_name504*/505static native byte[] getpwuid(int uid) throws UnixException;506507/**508* struct group *getgrgid(gid_t gid);509*510* @return group->gr_name511*/512static native byte[] getgrgid(int gid) throws UnixException;513514/**515* struct passwd *getpwnam(const char *name);516*517* @return passwd->pw_uid518*/519static int getpwnam(String name) throws UnixException {520NativeBuffer buffer = NativeBuffers.asNativeBuffer(Util.toBytes(name));521try {522return getpwnam0(buffer.address());523} finally {524buffer.release();525}526}527private static native int getpwnam0(long nameAddress) throws UnixException;528529/**530* struct group *getgrnam(const char *name);531*532* @return group->gr_name533*/534static int getgrnam(String name) throws UnixException {535NativeBuffer buffer = NativeBuffers.asNativeBuffer(Util.toBytes(name));536try {537return getgrnam0(buffer.address());538} finally {539buffer.release();540}541}542private static native int getgrnam0(long nameAddress) throws UnixException;543544/**545* statvfs(const char* path, struct statvfs *buf)546*/547static void statvfs(UnixPath path, UnixFileStoreAttributes attrs)548throws UnixException549{550NativeBuffer buffer = copyToNativeBuffer(path);551try {552statvfs0(buffer.address(), attrs);553} finally {554buffer.release();555}556}557private static native void statvfs0(long pathAddress, UnixFileStoreAttributes attrs)558throws UnixException;559560/**561* char* strerror(int errnum)562*/563static native byte[] strerror(int errnum);564565/**566* ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size);567*/568static int fgetxattr(int filedes, byte[] name, long valueAddress,569int valueLen) throws UnixException570{571try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(name)) {572return fgetxattr0(filedes, buffer.address(), valueAddress, valueLen);573}574}575576private static native int fgetxattr0(int filedes, long nameAddress,577long valueAddress, int valueLen) throws UnixException;578579/**580* fsetxattr(int filedes, const char *name, const void *value, size_t size, int flags);581*/582static void fsetxattr(int filedes, byte[] name, long valueAddress,583int valueLen) throws UnixException584{585try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(name)) {586fsetxattr0(filedes, buffer.address(), valueAddress, valueLen);587}588}589590private static native void fsetxattr0(int filedes, long nameAddress,591long valueAddress, int valueLen) throws UnixException;592593/**594* fremovexattr(int filedes, const char *name);595*/596static void fremovexattr(int filedes, byte[] name) throws UnixException {597try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(name)) {598fremovexattr0(filedes, buffer.address());599}600}601602private static native void fremovexattr0(int filedes, long nameAddress)603throws UnixException;604605/**606* size_t flistxattr(int filedes, const char *list, size_t size)607*/608static native int flistxattr(int filedes, long listAddress, int size)609throws UnixException;610611/**612* Capabilities613*/614private static final int SUPPORTS_OPENAT = 1 << 1; // syscalls615private static final int SUPPORTS_FUTIMES = 1 << 2;616private static final int SUPPORTS_FUTIMENS = 1 << 3;617private static final int SUPPORTS_LUTIMES = 1 << 4;618private static final int SUPPORTS_XATTR = 1 << 5;619private static final int SUPPORTS_BIRTHTIME = 1 << 16; // other features620private static final int capabilities;621622/**623* Supports openat and other *at calls.624*/625static boolean openatSupported() {626return (capabilities & SUPPORTS_OPENAT) != 0;627}628629/**630* Supports futimes or futimesat631*/632static boolean futimesSupported() {633return (capabilities & SUPPORTS_FUTIMES) != 0;634}635636/**637* Supports futimens638*/639static boolean futimensSupported() {640return (capabilities & SUPPORTS_FUTIMENS) != 0;641}642643/**644* Supports lutimes645*/646static boolean lutimesSupported() {647return (capabilities & SUPPORTS_LUTIMES) != 0;648}649650/**651* Supports file birth (creation) time attribute652*/653static boolean birthtimeSupported() {654return (capabilities & SUPPORTS_BIRTHTIME) != 0;655}656657/**658* Supports extended attributes659*/660static boolean xattrSupported() {661return (capabilities & SUPPORTS_XATTR) != 0;662}663664private static native int init();665static {666jdk.internal.loader.BootLoader.loadLibrary("nio");667capabilities = init();668}669}670671672