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