jafs-library-20020725
[openafs.git] / src / JAVA / libjafs / FileOutputStream.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_FileOutputStream.h"
24
25 #include <stdio.h>
26 #include <fcntl.h>
27 #include <afs/afs_usrops.h>
28
29 #ifdef DMALLOC
30 #include "dmalloc.h"
31 #endif
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  * @returns             file descriptor
52  * @exception   AFSFileException  if an I/O or other file related error occurs.
53  */
54 JNIEXPORT jint JNICALL Java_org_openafs_jafs_FileOutputStream_openWrite
55   (JNIEnv *env, jobject obj, jstring fileNameUTF)
56 {
57   int err;
58   jint fd = -1;         //file descriptor
59
60   fd = openAFSFile(env, fileNameUTF, O_CREAT | O_TRUNC, 0644, &err);
61   if (fd < 0) {
62     fprintf(stderr, "FileOutputStream::openWrite(): err=%d\n", err);
63     throwAFSFileException(env, err, NULL);
64   }
65   return fd;
66 }
67
68 /**
69  * Opens an AFS file, with the specified name, for writing.
70  * 
71  *  env         the Java environment
72  *  obj         the current Java object
73  *  fileNameUTF name of file to be opened
74  *
75  * @return              file descriptor
76  * @exception   AFSFileException  if an I/O or other file related error occurs.
77  */
78 JNIEXPORT jint JNICALL Java_org_openafs_jafs_FileOutputStream_openAppend
79   (JNIEnv *env, jobject obj, jstring fileNameUTF)
80 {
81   int err;
82   jint fd = -1;         //file descriptor
83
84   fd = openAFSFile(env, fileNameUTF, O_CREAT | O_APPEND, 0644, &err);
85   if (fd < 0) {
86     fprintf(stderr, "FileOutputStream::openAppend(): err=%d\n", err);
87     throwAFSFileException(env, err, NULL);
88   }
89   return fd;
90 }
91
92 /**
93  * Writes 'lenght' bytes from the specified byte array starting at offset 
94  * 'offset' to this file output stream. 
95  * 
96  *  env         the Java environment
97  *  obj         the current Java object
98  *  jbytes              the data to be written
99  *  offset              the start offset in the data
100  *  length              the number of bytes that are written
101  *
102  * @exception   AFSFileException  if an I/O or other file related error occurs.
103  */
104 JNIEXPORT void JNICALL Java_org_openafs_jafs_FileOutputStream_write
105   (JNIEnv *env, jobject obj, jbyteArray jbytes, jint offset, jint length)
106 {
107     int fd, written, toWrite;
108     jint twritten;
109     jclass thisClass;
110     jmethodID getFileDescriptorID;
111     char *bytes;
112     jfieldID fid;
113
114     thisClass = (*env)->GetObjectClass(env, obj);
115     fid = (*env)->GetFieldID(env, thisClass, "fileDescriptor", "I");
116     fd = (*env)->GetIntField(env, obj, fid);
117     if(fd < 0) {
118       fprintf(stderr, "FileOutputStream::write(): failed to get file 
119                        descriptor\n");
120       throwAFSFileException(env, 0, "Failed to get file descriptor!");
121     }
122     bytes = (char*) malloc(length);
123     if(bytes == NULL) {
124       fprintf(stderr, "FileOutputStream::write(): malloc failed of %d bytes\n",
125                        length);
126       throwAFSFileException(env, 0, "Failed to allocate memory!");
127     }
128     (*env) -> GetByteArrayRegion(env, jbytes, offset, length, bytes);
129     toWrite = length;
130     twritten = 0;
131     while(toWrite>0) {
132       written = uafs_write(fd, bytes, length);
133       twritten += written;
134       if(written<0) {
135         free(bytes);
136         throwAFSFileException(env, errno, NULL);
137       }
138       toWrite -= written;
139     }
140     free(bytes);
141 }
142
143 /**
144  * Closes this file output stream and releases any system resources 
145  * associated with this stream. This file output stream may no longer 
146  * be used for writing bytes. 
147  * 
148  *  env         the Java environment
149  *  obj         the current Java object
150  *
151  * @exception   AFSFileException  if an I/O or other file related error occurs.
152  */
153 JNIEXPORT void JNICALL Java_org_openafs_jafs_FileOutputStream_close
154   (JNIEnv *env, jobject obj)
155 {
156     int fd, rc;
157     jclass thisClass;
158     jmethodID getFileDescriptorID;
159     char *bytes;
160     jfieldID fid;
161
162     thisClass = (*env)->GetObjectClass(env, obj);
163     fid = (*env)->GetFieldID(env, thisClass, "fileDescriptor", "I");
164     fd = (*env)->GetIntField(env, obj, fid);
165     if(fd < 0) {
166       fprintf(stderr, "FileOutputStream::close(): failed to get file descriptor\n");
167       throwAFSFileException(env, 0, "Failed to get file descriptor!");
168     }
169     rc = uafs_close(fd);
170     if (rc != 0) {
171       throwAFSFileException(env, rc, NULL);
172     }
173 }
174
175