linux-mmap-antirecursion-avoid-spurious-eio-20090526
[openafs.git] / src / JAVA / libjafs / FileInputStream.c
1 /*
2  * Copyright (c) 2001-2002 International Business Machines Corp.
3  * All rights reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  * 
9  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
10  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
12  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR
13  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
14  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
15  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
16  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
17  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
18  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20  */
21
22 #include "Internal.h"
23 #include "org_openafs_jafs_FileInputStream.h"
24
25 #include <fcntl.h>
26
27 #ifdef DMALLOC
28 #include "dmalloc.h"
29 #endif
30
31 extern int errno;
32
33 /**
34  * Be carefull with the memory management:
35  *
36  * - For every GetStringUTFChars call the corresponding ReleaseStringUTFChars.
37  * - For every Get<type>ArrayElements call the corresponding
38  *   Release<type>ArrayElements
39  * - For every malloc call the corresponding free.
40  */
41
42 /*-------------------------------------------------------------------------*/
43
44 /**
45  * Opens an AFS file, with the specified name, for appending.
46  * 
47  *  env         the Java environment
48  *  obj         the current Java object
49  *  fileNameUTF name of file to be opened
50  *
51  * @return              file descriptor
52  * @exception   AFSFileException  if an I/O or other file related error occurs.
53  */
54 JNIEXPORT jint JNICALL Java_org_openafs_jafs_FileInputStream_openReadOnly
55   (JNIEnv *env, jobject obj, jstring fileNameUTF)
56 {
57   int err;
58   int fd = -1;          //file descriptor
59
60   fd = openAFSFile(env, fileNameUTF, O_RDONLY, 0, &err);
61   if (fd < 0) {
62     fprintf(stderr, "FileInputStream::openReadOnly(): err=%d\n", err);
63     throwAFSFileException( env, err, NULL );
64   }
65   return fd;
66 }
67
68 /**
69  * Reads up to 'length' bytes of data from this input stream
70  * into an array of bytes. This method blocks until some input is
71  * available.
72  * 
73  *  env         the Java environment
74  *  obj         the current Java object
75  *  jbytes              the data to be written
76  *  offset              the start offset in the data
77  *  length              the number of bytes that are written
78  *
79  * @return              the total number of bytes read into the buffer, or
80  *                      <code>-1</code> if there is no more data because the end of
81  *                      the file has been reached.
82  * @exception   AFSFileException  if an I/O or other file related error occurs.
83  */
84 JNIEXPORT jint JNICALL Java_org_openafs_jafs_FileInputStream_read
85   (JNIEnv *env, jobject obj, jbyteArray jbytes, jint offset, jint length)
86 {
87   int fd, bytesLen, bytesRead;
88   jclass thisClass;
89   jmethodID getFileDescriptorID;
90   jbyte *bytes;
91   jfieldID fid;
92
93   /* If we have to read 0 bytes just return */
94   if(length == 0) return 0;
95
96   thisClass = (*env)->GetObjectClass(env, obj);
97   fid = (*env)->GetFieldID(env, thisClass, "fileDescriptor", "I");
98   fd = (*env)->GetIntField(env, obj, fid);
99
100   if(fd < 0) {
101     fprintf(stderr, "FileInputStream::read(): invalid file state\n");
102     throwAFSFileException(env, 0, "Invalid file state");
103     return -1;
104   }
105
106   bytes = (*env) -> GetByteArrayElements(env, jbytes, 0);
107   bytesLen = (*env) -> GetArrayLength(env, jbytes);
108   bytesRead = uafs_read(fd, bytes, bytesLen);
109
110   if (errno != 0) throwAFSFileException(env, errno, NULL);
111
112   (*env) -> ReleaseByteArrayElements(env, jbytes, bytes, 0);
113   return (bytesRead > 0) ? bytesRead : -1;
114 }
115
116 /**
117  * Closes this file input stream and releases any system resources 
118  * associated with this stream. This file input stream may no longer 
119  * be used for writing bytes. 
120  * 
121  *  env         the Java environment
122  *  obj         the current Java object
123  *
124  * @exception   AFSFileException  if an I/O or other file related error occurs.
125  */
126 JNIEXPORT void JNICALL Java_org_openafs_jafs_FileInputStream_close
127   (JNIEnv *env, jobject obj)
128 {
129   int fd, rc;
130   jclass thisClass;
131   jmethodID getFileDescriptorID;
132   jfieldID fid;
133   char *bytes;
134
135   thisClass = (*env)->GetObjectClass(env, obj);
136   fid = (*env)->GetFieldID(env, thisClass, "fileDescriptor", "I");
137   fd = (*env)->GetIntField(env, obj, fid);
138
139   if(fd < 0) {
140     fprintf(stderr, "FileInputStream::close(): invalid file state\n");
141     throwAFSFileException(env, 0, "Invalid file state");
142     return;
143   }
144
145   rc = uafs_close(fd);
146
147   if (rc != 0) {
148     throwAFSFileException(env, errno, NULL);
149   }
150 }
151
152
153