1 /* |
1 /* |
2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
60 } |
69 } |
61 return rv; |
70 return rv; |
62 } |
71 } |
63 #endif |
72 #endif |
64 |
73 |
|
74 FD |
|
75 handleOpen(const char *path, int oflag, int mode) { |
|
76 FD fd; |
|
77 RESTARTABLE(open64(path, oflag, mode), fd); |
|
78 if (fd != -1) { |
|
79 struct stat64 buf64; |
|
80 int result; |
|
81 RESTARTABLE(fstat64(fd, &buf64), result); |
|
82 if (result != -1) { |
|
83 if (S_ISDIR(buf64.st_mode)) { |
|
84 close(fd); |
|
85 errno = EISDIR; |
|
86 fd = -1; |
|
87 } |
|
88 } else { |
|
89 close(fd); |
|
90 fd = -1; |
|
91 } |
|
92 } |
|
93 return fd; |
|
94 } |
|
95 |
65 void |
96 void |
66 fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags) |
97 fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags) |
67 { |
98 { |
68 WITH_PLATFORM_STRING(env, path, ps) { |
99 WITH_PLATFORM_STRING(env, path, ps) { |
69 FD fd; |
100 FD fd; |
72 /* Remove trailing slashes, since the kernel won't */ |
103 /* Remove trailing slashes, since the kernel won't */ |
73 char *p = (char *)ps + strlen(ps) - 1; |
104 char *p = (char *)ps + strlen(ps) - 1; |
74 while ((p > ps) && (*p == '/')) |
105 while ((p > ps) && (*p == '/')) |
75 *p-- = '\0'; |
106 *p-- = '\0'; |
76 #endif |
107 #endif |
77 fd = JVM_Open(ps, flags, 0666); |
108 fd = handleOpen(ps, flags, 0666); |
78 if (fd >= 0) { |
109 if (fd != -1) { |
79 SET_FD(this, fd, fid); |
110 SET_FD(this, fd, fid); |
80 } else { |
111 } else { |
81 throwFileNotFoundException(env, path); |
112 throwFileNotFoundException(env, path); |
82 } |
113 } |
83 } END_PLATFORM_STRING(env, ps); |
114 } END_PLATFORM_STRING(env, ps); |
84 } |
115 } |
85 |
|
86 |
116 |
87 void |
117 void |
88 fileClose(JNIEnv *env, jobject this, jfieldID fid) |
118 fileClose(JNIEnv *env, jobject this, jfieldID fid) |
89 { |
119 { |
90 FD fd = GET_FD(this, fid); |
120 FD fd = GET_FD(this, fid); |
112 JNU_ThrowIOExceptionWithLastError(env, "open /dev/null failed"); |
142 JNU_ThrowIOExceptionWithLastError(env, "open /dev/null failed"); |
113 } else { |
143 } else { |
114 dup2(devnull, fd); |
144 dup2(devnull, fd); |
115 close(devnull); |
145 close(devnull); |
116 } |
146 } |
117 } else if (JVM_Close(fd) == -1) { |
147 } else if (close(fd) == -1) { |
118 JNU_ThrowIOExceptionWithLastError(env, "close failed"); |
148 JNU_ThrowIOExceptionWithLastError(env, "close failed"); |
119 } |
149 } |
120 } |
150 } |
|
151 |
|
152 ssize_t |
|
153 handleRead(FD fd, void *buf, jint len) |
|
154 { |
|
155 ssize_t result; |
|
156 RESTARTABLE(read(fd, buf, len), result); |
|
157 return result; |
|
158 } |
|
159 |
|
160 ssize_t |
|
161 handleWrite(FD fd, const void *buf, jint len) |
|
162 { |
|
163 ssize_t result; |
|
164 RESTARTABLE(write(fd, buf, len), result); |
|
165 return result; |
|
166 } |
|
167 |
|
168 jint |
|
169 handleAvailable(FD fd, jlong *pbytes) |
|
170 { |
|
171 int mode; |
|
172 struct stat64 buf64; |
|
173 jlong size = -1, current = -1; |
|
174 |
|
175 int result; |
|
176 RESTARTABLE(fstat64(fd, &buf64), result); |
|
177 if (result != -1) { |
|
178 mode = buf64.st_mode; |
|
179 if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) { |
|
180 int n; |
|
181 int result; |
|
182 RESTARTABLE(ioctl(fd, FIONREAD, &n), result); |
|
183 if (result >= 0) { |
|
184 *pbytes = n; |
|
185 return 1; |
|
186 } |
|
187 } else if (S_ISREG(mode)) { |
|
188 size = buf64.st_size; |
|
189 } |
|
190 } |
|
191 |
|
192 if ((current = lseek64(fd, 0, SEEK_CUR)) == -1) { |
|
193 return 0; |
|
194 } |
|
195 |
|
196 if (size < current) { |
|
197 if ((size = lseek64(fd, 0, SEEK_END)) == -1) |
|
198 return 0; |
|
199 else if (lseek64(fd, current, SEEK_SET) == -1) |
|
200 return 0; |
|
201 } |
|
202 |
|
203 if (size >= current) { |
|
204 *pbytes = size - current; |
|
205 return 1; |
|
206 } else { |
|
207 return 0; |
|
208 } |
|
209 } |
|
210 |
|
211 jint |
|
212 handleSetLength(FD fd, jlong length) |
|
213 { |
|
214 int result; |
|
215 RESTARTABLE(ftruncate64(fd, length), result); |
|
216 return result; |
|
217 } |
|
218 |
|
219 size_t |
|
220 getLastErrorString(char *buf, size_t len) |
|
221 { |
|
222 if (errno == 0 || len < 1) return 0; |
|
223 |
|
224 const char *err = strerror(errno); |
|
225 size_t n = strlen(err); |
|
226 if (n >= len) |
|
227 n = len - 1; |
|
228 |
|
229 strncpy(buf, err, n); |
|
230 buf[n] = '\0'; |
|
231 return n; |
|
232 } |