/[classpath]/classpath/native/jni/java-io/FileDescriptor.c
ViewVC logotype

Diff of /classpath/native/jni/java-io/FileDescriptor.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.11 by mkoch, Thu May 15 13:12:02 2003 UTC revision 1.12 by rupp, Wed Jul 9 08:14:18 2003 UTC
# Line 45  exception statement from your version. * Line 45  exception statement from your version. *
45   * Some of this coded adopted from the gcj native libraries   * Some of this coded adopted from the gcj native libraries
46   */   */
47    
48    /* do not move; needed here because of some macro definitions */
49  #include <config.h>  #include <config.h>
50    
51  /* FIXME: Need to make configure set these for us */  /* FIXME: Need to make configure set these for us */
# Line 54  exception statement from your version. * Line 55  exception statement from your version. *
55  #define HAVE_FSYNC  #define HAVE_FSYNC
56  #define HAVE_SELECT  #define HAVE_SELECT
57    
58  #include <stdio.h>  #include <jni.h>
59  #include <stdlib.h>  #include "jcl.h"
 #include <string.h>  
 #include <sys/types.h>  
 #include <sys/time.h>  
 #include <sys/stat.h>  
 #include <errno.h>  
 #include <fcntl.h>  
 #include <unistd.h>  
   
 #ifdef HAVE_SYS_IOCTL_H  
 #define BSD_COMP /* Get FIONREAD on Solaris2 */  
 #include <sys/ioctl.h>  
 #endif  
60    
61  #ifdef HAVE_SYS_FILIO_H /* Get FIONREAD on Solaris 2.5 */  #include "target_native.h"
62  #include <sys/filio.h>  #ifndef WITHOUT_FILESYSTEM
63      #include "target_native_file.h"
64  #endif  #endif
65    #include "target_native_math_int.h"
66    
 #include <jni.h>  
   
 #include "jcl.h"  
67  #include "java_io_FileDescriptor.h"  #include "java_io_FileDescriptor.h"
68    
69  // FIXME: This can't be right.  Need converter macros  // FIXME: This can't be right.  Need converter macros
70  #define CONVERT_JLONG_TO_INT(x) ((int)(x & 0xFFFFFFFF))  #define CONVERT_JLONG_TO_INT(x) TARGET_NATIVE_MATH_INT_INT64_TO_INT32(x)
71    #define CONVERT_INT_TO_JLONG(x) TARGET_NATIVE_MATH_INT_INT32_TO_INT64(x)
72    
73  // FIXME: This can't be right.  Need converter macros  // FIXME: This can't be right.  Need converter macros
74  #define CONVERT_JLONG_TO_OFF_T(x) (x)  #define CONVERT_JLONG_TO_OFF_T(x) TARGET_NATIVE_MATH_INT_INT64_TO_INT32(x)
75    #define CONVERT_OFF_T_TO_JLONG(x) TARGET_NATIVE_MATH_INT_INT32_TO_INT64(x)
76    
77  // FIXME: This can't be right.  Need converter macros  // FIXME: This can't be right.  Need converter macros
78  #define CONVERT_JINT_TO_INT(x) ((int)(x & 0xFFFFFFFF))  #define CONVERT_JINT_TO_INT(x) ((int)(x & 0xFFFFFFFF))
79    #define CONVERT_INT_TO_JINT(x) ((int)(x & 0xFFFFFFFF))
80    
81  // FIXME: This can't be right.  Need converter macros  // FIXME: This can't be right.  Need converter macros
82  #define CONVERT_SSIZE_T_TO_JINT(x) ((jint)(x & 0xFFFFFFFF))  #define CONVERT_SSIZE_T_TO_JINT(x) ((jint)(x & 0xFFFFFFFF))
83    #define CONVERT_JINT_TO_SSIZE_T(x) (x)
84    
85  /* These values must be kept in sync with FileDescriptor.java.  */  /* These values must be kept in sync with FileDescriptor.java.  */
86  #define SET 0  #define SET     0
87  #define CUR 1  #define CUR     1
88  #define END 2  #define END     2
89  #define READ 1  #define READ    1
90  #define WRITE 2  #define WRITE   2
91  #define APPEND 4  #define APPEND  4
92  #define EXCL 8  #define EXCL    8
93  #define SYNC 16  #define SYNC   16
94  #define DSYNC 32  #define DSYNC  32
   
95    
96  /*************************************************************************/  /*************************************************************************/
97    
# Line 133  Java_java_io_FileDescriptor_nativeInit(J Line 124  Java_java_io_FileDescriptor_nativeInit(J
124    INIT_FIELD ("in", 0);    INIT_FIELD ("in", 0);
125    INIT_FIELD ("out", 1);    INIT_FIELD ("out", 1);
126    INIT_FIELD ("err", 2);    INIT_FIELD ("err", 2);
127    
128    #undef INIT_FIELD
129  }  }
130    
131  /*************************************************************************/  /*************************************************************************/
# Line 143  JNIEXPORT jlong JNICALL Line 136  JNIEXPORT jlong JNICALL
136  Java_java_io_FileDescriptor_nativeOpen(JNIEnv *env, jobject obj, jstring name,  Java_java_io_FileDescriptor_nativeOpen(JNIEnv *env, jobject obj, jstring name,
137                                         jint jflags)                                         jint jflags)
138  {  {
139    int rc;    const char *filename;
140    char *cname;    int        flags;
141    int flags;    int        permissions;
142    int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;    int        native_fd;
143      int        result;
144    
145    cname = JCL_jstring_to_cstring(env, name);    filename = JCL_jstring_to_cstring(env, name);
146    if (!cname)    if (filename == NULL)
147      return(-1); /* Exception will already have been thrown */      return(-1); /* Exception will already have been thrown */
148    
149    flags = 0;    /* get file/permission flags for open() */
 #ifdef O_BINARY  
   flags |= O_BINARY;  
 #endif  
   
   /* We don't have to do any checking of the flags, as it is all done  
      in FileDescriptor.  We can assume everything is ok.  */  
150    if ((jflags & READ) && (jflags & WRITE))    if ((jflags & READ) && (jflags & WRITE))
151      flags |= O_RDWR | O_CREAT;      {
152          /* read/write */
153          flags       = TARGET_NATIVE_FILE_FILEFLAG_CREATE | TARGET_NATIVE_FILE_FILEFLAG_READWRITE;
154          permissions = TARGET_NATIVE_FILE_FILEPERMISSION_NORMAL;
155        }
156    else if ((jflags & READ))    else if ((jflags & READ))
157      flags |= O_RDONLY;      {
158          /* read */
159          flags       = TARGET_NATIVE_FILE_FILEFLAG_READ;
160          permissions = TARGET_NATIVE_FILE_FILEPERMISSION_NORMAL;
161        }
162    else    else
163      {      {
164        flags |= O_WRONLY | O_CREAT;        /* write */
165          flags       = TARGET_NATIVE_FILE_FILEFLAG_CREATE | TARGET_NATIVE_FILE_FILEFLAG_WRITE;
166        if ((jflags & APPEND))        if ((jflags & APPEND))
167          flags |= O_APPEND;          {
168               flags |= TARGET_NATIVE_FILE_FILEFLAG_APPEND;
169            }
170        else        else
171          flags |= O_TRUNC;          {
172               flags |= TARGET_NATIVE_FILE_FILEFLAG_TRUNCATE;
173        if ((jflags & EXCL))          }
174          {        permissions = TARGET_NATIVE_FILE_FILEPERMISSION_NORMAL;
           /* In this case we are making a temp file.  */  
           flags |= O_EXCL;  
           mode = S_IRUSR | S_IWUSR;  
         }  
175      }      }
176    
177    if ((jflags & SYNC))    if ((jflags & SYNC))
178      flags |= O_SYNC;      {
179          flags |= TARGET_NATIVE_FILE_FILEFLAG_SYNC;
180        }
181    
 #ifdef O_DSYNC  
182    if ((jflags & DSYNC))    if ((jflags & DSYNC))
183      flags |= O_DSYNC;      {
184  #else        flags |= TARGET_NATIVE_FILE_FILEFLAG_DSYNC;
185    // If O_DSYNC doesnt exist use O_SYNC instead.      }
186    if ((jflags & DSYNC))  #ifdef O_BINARY
187      flags |= O_SYNC;    flags |= TARGET_NATIVE_FILE_FILEFLAG_BINARY;
188  #endif  #endif
189    
190    rc = open (cname, flags, mode);    TARGET_NATIVE_FILE_OPEN(filename,native_fd,flags,permissions,result);
191      (*env)->ReleaseStringUTFChars(env, name, filename);
   (*env)->ReleaseStringUTFChars(env, name, cname);  
192    
193    if (rc == -1)    if (result != TARGET_NATIVE_OK)
194      {      {
195        /* We can only throw FileNotFoundException.  */        /* We can only throw FileNotFoundException.  */
196        JCL_ThrowException(env,"java/io/FileNotFoundException", strerror(errno));        JCL_ThrowException(env,
197                             "java/io/FileNotFoundException",
198                             TARGET_NATIVE_LAST_ERROR_STRING());
199          return JNI_JLONG_CONST_MINUS_1;
200      }      }
201    
202    return rc;    return CONVERT_INT_TO_JLONG(native_fd);
203  }  }
204    
205  /*************************************************************************/  /*************************************************************************/
# Line 213  Java_java_io_FileDescriptor_nativeOpen(J Line 210  Java_java_io_FileDescriptor_nativeOpen(J
210  JNIEXPORT jlong JNICALL  JNIEXPORT jlong JNICALL
211  Java_java_io_FileDescriptor_nativeClose(JNIEnv *env, jobject obj, jlong fd)  Java_java_io_FileDescriptor_nativeClose(JNIEnv *env, jobject obj, jlong fd)
212  {  {
213    int rc, native_fd;    int native_fd;
214      int result;
215    
216    native_fd = CONVERT_JLONG_TO_INT(fd);    native_fd = CONVERT_JLONG_TO_INT(fd);
217    
218    rc = close(native_fd);    TARGET_NATIVE_FILE_CLOSE(native_fd,result);
219    if (rc == -1)    if (result != TARGET_NATIVE_OK)
220      JCL_ThrowException(env, "java/io/IOException", strerror(errno));      {
221          JCL_ThrowException(env,
222                             "java/io/IOException",
223                             TARGET_NATIVE_LAST_ERROR_STRING());
224          return(JNI_JLONG_CONST_MINUS_1);
225        }
226    
227    return(rc);    return(JNI_JLONG_CONST_0);
228  }  }
229    
230  /*************************************************************************/  /*************************************************************************/
# Line 233  JNIEXPORT jlong JNICALL Line 236  JNIEXPORT jlong JNICALL
236  Java_java_io_FileDescriptor_nativeWriteByte(JNIEnv *env, jobject obj,  Java_java_io_FileDescriptor_nativeWriteByte(JNIEnv *env, jobject obj,
237                                              jlong fd, jint b)                                              jlong fd, jint b)
238  {  {
239    int native_fd;    int     native_fd;
240    int native_byte;    char    native_data;
241    char buf[1];    ssize_t bytes_written;
242    ssize_t rc;    int     result;
243    
244    native_fd = CONVERT_JLONG_TO_INT(fd);    native_fd   = CONVERT_JLONG_TO_INT(fd);
245    native_byte = CONVERT_JINT_TO_INT(b);    native_data = (char)(CONVERT_JINT_TO_INT(b) & 0xFF);
246    buf[0] = (char)(native_byte & 0xFF);  
247      do
248    while (rc != 1)      {
249      {        TARGET_NATIVE_FILE_WRITE(native_fd, &native_data, 1, bytes_written, result);
250        rc = write(fd, buf, 1);        if ((result != TARGET_NATIVE_OK)
251        if ((rc == -1) && (errno != EINTR))            && (TARGET_NATIVE_LAST_ERROR() != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
252          {          {
253            JCL_ThrowException(env, "java/io/IOException", strerror(errno));            JCL_ThrowException(env,
254            return(-1);                               "java/io/IOException",
255                                 TARGET_NATIVE_LAST_ERROR_STRING());
256              return(JNI_JLONG_CONST_MINUS_1);
257          }          }
258      }      }
259      while (result != TARGET_NATIVE_OK);
260    
261    return(0);    return(JNI_JLONG_CONST_0);
262  }  }
263    
264  /*************************************************************************/  /*************************************************************************/
# Line 265  Java_java_io_FileDescriptor_nativeWriteB Line 271  Java_java_io_FileDescriptor_nativeWriteB
271                                             jlong fd, jbyteArray buf,                                             jlong fd, jbyteArray buf,
272                                             jint offset, jint len)                                             jint offset, jint len)
273  {  {
274    int native_fd;    int     native_fd;
275    ssize_t rc, bytes_written = 0;    jbyte   *bufptr;
276    jbyte *bufptr;    ssize_t bytes_written;
277      ssize_t n;
278      int     result;
279    
280    native_fd = CONVERT_JLONG_TO_INT(fd);    native_fd = CONVERT_JLONG_TO_INT(fd);
281    
# Line 275  Java_java_io_FileDescriptor_nativeWriteB Line 283  Java_java_io_FileDescriptor_nativeWriteB
283    if (!bufptr)    if (!bufptr)
284      {      {
285        JCL_ThrowException(env, "java/io/IOException", "Unexpected JNI error");        JCL_ThrowException(env, "java/io/IOException", "Unexpected JNI error");
286        return(-1);        return(JNI_JLONG_CONST_MINUS_1);
287      }      }
288    
289    while (bytes_written < len)    bytes_written = 0;
290      while (bytes_written < CONVERT_JINT_TO_SSIZE_T(len))
291      {      {
292        rc = write(fd, (bufptr + offset + bytes_written), (len - bytes_written));        TARGET_NATIVE_FILE_WRITE(native_fd, (bufptr + offset + bytes_written), (len - bytes_written), n, result);
293        if ((rc == -1) && (errno != EINTR))        if ((result != TARGET_NATIVE_OK)
294              && (TARGET_NATIVE_LAST_ERROR() != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
295          {          {
296            JCL_ThrowException(env, "java/io/IOException", strerror(errno));            JCL_ThrowException(env,
297                                 "java/io/IOException",
298                                 TARGET_NATIVE_LAST_ERROR_STRING());
299            (*env)->ReleaseByteArrayElements(env, buf, bufptr, 0);            (*env)->ReleaseByteArrayElements(env, buf, bufptr, 0);
300            return(-1);            return(JNI_JLONG_CONST_MINUS_1);
301          }          }
302        bytes_written += rc;        bytes_written += n;
303      }      }
304    
305    (*env)->ReleaseByteArrayElements(env, buf, bufptr, 0);    (*env)->ReleaseByteArrayElements(env, buf, bufptr, 0);
306    return(0);  
307      return(JNI_JLONG_CONST_0);
308  }  }
309    
310  /*************************************************************************/  /*************************************************************************/
# Line 302  Java_java_io_FileDescriptor_nativeWriteB Line 315  Java_java_io_FileDescriptor_nativeWriteB
315  JNIEXPORT jint JNICALL  JNIEXPORT jint JNICALL
316  Java_java_io_FileDescriptor_nativeReadByte(JNIEnv *env, jobject obj, jlong fd)  Java_java_io_FileDescriptor_nativeReadByte(JNIEnv *env, jobject obj, jlong fd)
317  {  {
318    int native_fd;    int     native_fd;
319    jbyte b;    char    data;
320    ssize_t rc;    ssize_t bytes_read;
321      int     result;
322    
323    native_fd = CONVERT_JLONG_TO_INT(fd);    native_fd = CONVERT_JLONG_TO_INT(fd);
324    
325    while (rc != 1)    bytes_read = 0;
326      do
327      {      {
328        rc = read(fd, &b, 1);        TARGET_NATIVE_FILE_READ(native_fd, &data, 1, bytes_read, result);
329        if (rc == 0)        if ((result == TARGET_NATIVE_OK) && (bytes_read == 0))
330          return(-1); /* Signal end of file to Java */          {
331        if ((rc == -1) && (errno != EINTR))            return(-1);
332            }
333          if ((result != TARGET_NATIVE_OK)
334              && (TARGET_NATIVE_LAST_ERROR() != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
335          {          {
336            JCL_ThrowException(env, "java/io/IOException", strerror(errno));            JCL_ThrowException(env,
337                                 "java/io/IOException",
338                                 TARGET_NATIVE_LAST_ERROR_STRING());
339            return(-1);            return(-1);
340          }          }
341      }      }
342    return(b & 0xFF);    while (bytes_read != 1);
343    
344      return((jint)(data & 0xFF));
345  }  }
346    
347  /*************************************************************************/  /*************************************************************************/
# Line 332  Java_java_io_FileDescriptor_nativeReadBu Line 354  Java_java_io_FileDescriptor_nativeReadBu
354                                           jlong fd, jarray buf, jint offset,                                           jlong fd, jarray buf, jint offset,
355                                           jint len)                                           jint len)
356  {  {
357    int native_fd;    int     native_fd;
358    ssize_t rc, bytes_read = 0;    jbyte   *bufptr;
359    jbyte *bufptr;    ssize_t bytes_read;
360      ssize_t n;
361      int     result;
362    
363    native_fd = CONVERT_JLONG_TO_INT(fd);    native_fd = CONVERT_JLONG_TO_INT(fd);
364    
# Line 345  Java_java_io_FileDescriptor_nativeReadBu Line 369  Java_java_io_FileDescriptor_nativeReadBu
369        return(-1);        return(-1);
370      }      }
371    
372      bytes_read = 0;
373    while (bytes_read < len)    while (bytes_read < len)
374      {      {
375        rc = read(fd, (bufptr + offset + bytes_read), (len - bytes_read));        TARGET_NATIVE_FILE_READ(native_fd, (bufptr + offset + bytes_read), (len - bytes_read), n, result);
376          if ((result == TARGET_NATIVE_OK) && (n == 0))
       if (rc == 0)  
377          {          {
378            (*env)->ReleaseByteArrayElements(env, buf, bufptr, 0);            (*env)->ReleaseByteArrayElements(env, buf, bufptr, 0);
379            if (bytes_read == 0)            if (bytes_read == 0)
# Line 357  Java_java_io_FileDescriptor_nativeReadBu Line 381  Java_java_io_FileDescriptor_nativeReadBu
381            else            else
382              return(CONVERT_SSIZE_T_TO_JINT(bytes_read));              return(CONVERT_SSIZE_T_TO_JINT(bytes_read));
383          }          }
384          if ((result != TARGET_NATIVE_OK)
385        if ((rc == -1) && (errno != EINTR))            && (TARGET_NATIVE_LAST_ERROR() != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
386          {          {
387            JCL_ThrowException(env, "java/io/IOException", strerror(errno));            JCL_ThrowException(env,
388                                 "java/io/IOException",
389                                 TARGET_NATIVE_LAST_ERROR_STRING());
390            (*env)->ReleaseByteArrayElements(env, buf, bufptr, 0);            (*env)->ReleaseByteArrayElements(env, buf, bufptr, 0);
391            return(-1);            return(-1);
392          }          }
393        bytes_read += rc;        bytes_read += n;
394      }      }
395    
396    (*env)->ReleaseByteArrayElements(env, buf, bufptr, 0);    (*env)->ReleaseByteArrayElements(env, buf, bufptr, 0);
# Line 379  Java_java_io_FileDescriptor_nativeReadBu Line 405  Java_java_io_FileDescriptor_nativeReadBu
405  JNIEXPORT jint JNICALL  JNIEXPORT jint JNICALL
406  Java_java_io_FileDescriptor_nativeAvailable(JNIEnv *env, jobject obj, jlong fd)  Java_java_io_FileDescriptor_nativeAvailable(JNIEnv *env, jobject obj, jlong fd)
407  {  {
408  #if defined(FIONREAD) || defined(HAVE_SELECT) || defined(HAVE_FSTAT)    int   native_fd;
409    int native_fd, found = 0;    jlong bytes_available;
410    ssize_t num = 0, rc;    int   result;
   off_t cur_pos;  
   struct stat sb;  
   fd_set fds;  
   struct timeval tv;  
411    
412    native_fd = CONVERT_JLONG_TO_INT(fd);    native_fd = CONVERT_JLONG_TO_INT(fd);
413    
414  #if defined(FIONREAD)    TARGET_NATIVE_FILE_AVAILABLE(native_fd,bytes_available,result);
415    rc = ioctl(native_fd, FIONREAD, &num);    if (result != TARGET_NATIVE_OK)
   if (rc == -1) /* We don't care if this fails.  Try something else */  
     {  
       rc = 0;  
       num = 0;  
     }  
   else  
     {  
       found = 1;  
     }  
 #endif /* defined FIONREAD */  
 #if defined (HAVE_FSTAT)  
   if (!found)  
416      {      {
417        rc = fstat(native_fd, &sb);        JCL_ThrowException(env,
418        if (rc != -1) /* Don't bomb here either - just try the next method */                           "java/io/IOException",
419          {                           TARGET_NATIVE_LAST_ERROR_STRING());
420            if (S_ISREG(sb.st_mode))        return(0);
             {  
               cur_pos = lseek(native_fd, 0, SEEK_CUR);  
               if (cur_pos != 1)  
                 {  
                   num = (ssize_t)(sb.st_size - cur_pos);  
                   found = 1;  
                 }  
             }  
         }  
421      }      }
 #endif /* defined HAVE_FSTAT */  
 #if defined (HAVE_SELECT)  
   if (!found)  
     {  
       FD_ZERO(&fds);  
       FD_SET(native_fd, &fds);  
       memset(&tv, 0, sizeof(struct timeval));  
   
       rc = select(native_fd + 1, &fds, 0, 0, &tv);  
       if (rc == -1) /* Finally, we give up */  
         {  
           JCL_ThrowException(env, "java/io/IOException", strerror(errno));  
           return(-1);  
         }  
       found = 1;  
       if (rc == 0)  
         num = 0; /* Nothing to read here */  
       else  
         num = 1; /* We know there is something, but not how much */  
     }  
 #endif /* defined HAVE_SELECT */  
   
   if (!found)  
     return(0);  
   else  
     return(CONVERT_SSIZE_T_TO_JINT(num));  
422    
423  #else /* defined FIONREAD, HAVE_SELECT, HAVE_FSTAT */  // FIXME NYI ??? why only jint and not jlong?
424   /* FIXME: Probably operation isn't supported, but this exception    return(TARGET_NATIVE_MATH_INT_INT64_TO_INT32(bytes_available));
   * is too harsh as it will probably crash the program without need  
   JCL_ThrowException(env, "java/lang/UnsupportedOperationException",  
   "not implemented - can't shorten files on this platform");  
     
   This even seems rather harsh  
   JCL_ThrowException(env, "java/io/IOException",  
                      "Unable to shorten file length");  
   */  
   return(0);  
 #endif  
425  }  }
426    
427  /*************************************************************************/  /*************************************************************************/
# Line 469  Java_java_io_FileDescriptor_nativeSeek(J Line 434  Java_java_io_FileDescriptor_nativeSeek(J
434                                         jlong offset, jint whence,                                         jlong offset, jint whence,
435                                         jboolean stop_at_eof)                                         jboolean stop_at_eof)
436  {  {
437    int native_fd;    int   native_fd;
438    off_t rc, native_offset, cur_pos, file_size;    jlong file_size;
439    struct stat sb;    jlong current_offset, new_offset;
440      int   result;
441    
442    native_fd = CONVERT_JLONG_TO_INT(fd);    native_fd = CONVERT_JLONG_TO_INT(fd);
443    native_offset = CONVERT_JLONG_TO_OFF_T(offset);  
444    #if 0
445      /* Should there be such an exception? All native layer macros should
446         be accepting 64bit-values if needed. It some target is not able
447         to handle such values it should simply operate with 32bit-values
448         and convert 64bit-values appriopated. In this case I assume
449         problems should not occurre: if some specific target is not able
450         to handle 64bit-values the system is limited to 32bit at all, thus
451         the application can not do a seek() or something else beyond the
452         32bit limit. It this true?
453      */
454    
455    /* FIXME: What do we do if offset > the max value of off_t on this 32bit    /* FIXME: What do we do if offset > the max value of off_t on this 32bit
456     * system?  How do we detect that and what do we do? */     * system?  How do we detect that and what do we do? */
457    if ((jlong)native_offset != offset)      if (CONVERT_OFF_T_TO_JLONG(native_offset) != offset)  
458      {      {
459        JCL_ThrowException(env, "java/io/IOException",        JCL_ThrowException(env, "java/io/IOException",
460                           "Cannot represent position correctly on this system");                           "Cannot represent position correctly on this system");
461        return(-1);        return(JNI_JLONG_CONST_MINUS_1);
462      }      }
463    #endif
464            
465    if (stop_at_eof)    if (stop_at_eof)
466      {      {
467        rc = fstat(native_fd, &sb);        /* get file size */
468        file_size = sb.st_size;        TARGET_NATIVE_FILE_SIZE(native_fd, file_size, result);
469        if (rc == -1)        if (result != TARGET_NATIVE_OK)
470          {          {
471            JCL_ThrowException(env, "java/io/IOException", strerror(errno));            JCL_ThrowException(env,
472            return(-1);                               "java/io/IOException",
473                                 TARGET_NATIVE_LAST_ERROR_STRING());
474              return(JNI_JLONG_CONST_MINUS_1);
475          }          }
476        if (whence == SET)  
477          /* set file read/write position (seek) */
478          if      (whence == SET)
479          {          {
480            if (native_offset > file_size)            if (TARGET_NATIVE_MATH_INT_INT64_GT(offset,file_size))
481              native_offset = file_size;              offset = file_size;
482          }          }
483        else if (whence == CUR)        else if (whence == CUR)
484          {          {
485            cur_pos = lseek(native_fd, 0, SEEK_CUR);            TARGET_NATIVE_FILE_TELL(native_fd, current_offset, result);
486            if (cur_pos == -1)            if (result != TARGET_NATIVE_OK)
487              {              {
488                JCL_ThrowException(env, "java/io/IOException", strerror(errno));                JCL_ThrowException(env,
489                return(-1);                                   "java/io/IOException",
490                                     TARGET_NATIVE_LAST_ERROR_STRING());
491                  return(JNI_JLONG_CONST_MINUS_1);
492              }              }
493            if ((cur_pos + native_offset) > file_size)            if (TARGET_NATIVE_MATH_INT_INT64_GT(TARGET_NATIVE_MATH_INT_INT64_ADD(current_offset,offset),file_size))
494              {              {
495                native_offset = file_size;                offset = file_size;
496                whence = SET;                whence = SET;
497              }              }
498          }          }
499        else if (native_offset > 0) /* Default to END case */        else if (TARGET_NATIVE_MATH_INT_INT64_GT(offset,0)) /* Default to END case */
500          {          {
501            native_offset = 0;            offset = JNI_JLONG_CONST_0;
502          }          }
503      }      }
504    
505    /* Now do it */    /* Now do it */
506    rc = -1;    result = TARGET_NATIVE_ERROR;
507      new_offset = JNI_JLONG_CONST_MINUS_1;
508    if (whence == SET)    if (whence == SET)
509      rc = lseek(native_fd, native_offset, SEEK_SET);        TARGET_NATIVE_FILE_SEEK_BEGIN(native_fd, offset, new_offset, result);
510    if (whence == CUR)    if (whence == CUR)
511      rc = lseek(native_fd, native_offset, SEEK_CUR);      TARGET_NATIVE_FILE_SEEK_CURRENT(native_fd, offset, new_offset, result);
512    if (whence == END)    if (whence == END)
513      rc = lseek(native_fd, native_offset, SEEK_END);      TARGET_NATIVE_FILE_SEEK_END(native_fd, offset, new_offset, result);
514    
515    if (rc == -1)    if (result != TARGET_NATIVE_OK)
516      JCL_ThrowException(env, "java/io/IOException", strerror(errno));      {
517    return(rc);        JCL_ThrowException(env,
518                             "java/io/IOException",
519                             TARGET_NATIVE_LAST_ERROR_STRING());
520          return(JNI_JLONG_CONST_MINUS_1);
521        }
522    
523      return(new_offset);
524  }  }
525    
526  /*************************************************************************/  /*************************************************************************/
# Line 542  JNIEXPORT jlong JNICALL Line 532  JNIEXPORT jlong JNICALL
532  Java_java_io_FileDescriptor_nativeGetFilePointer(JNIEnv *env, jobject obj,  Java_java_io_FileDescriptor_nativeGetFilePointer(JNIEnv *env, jobject obj,
533                                                   jlong fd)                                                   jlong fd)
534  {  {
535    int native_fd;    int   native_fd;
536    off_t rc;    jlong current_offset;
537      int   result;
538    
539    native_fd = CONVERT_JLONG_TO_INT(fd);    native_fd = CONVERT_JLONG_TO_INT(fd);
540    
541    rc = lseek(native_fd, 0, SEEK_CUR);    TARGET_NATIVE_FILE_TELL(native_fd, current_offset, result);
542    if (rc == -1)    if (result != TARGET_NATIVE_OK)
543      JCL_ThrowException(env, "java/io/IOException", strerror(errno));      {
544          JCL_ThrowException(env,
545                             "java/io/IOException",
546                             TARGET_NATIVE_LAST_ERROR_STRING());
547          return(JNI_JLONG_CONST_MINUS_1);
548        }
549    
550    return(rc);    return(current_offset);
551  }  }
552    
553  /*************************************************************************/  /*************************************************************************/
# Line 562  Java_java_io_FileDescriptor_nativeGetFil Line 558  Java_java_io_FileDescriptor_nativeGetFil
558  JNIEXPORT jlong JNICALL  JNIEXPORT jlong JNICALL
559  Java_java_io_FileDescriptor_nativeGetLength(JNIEnv *env, jobject obj, jlong fd)  Java_java_io_FileDescriptor_nativeGetLength(JNIEnv *env, jobject obj, jlong fd)
560  {  {
561    int rc, native_fd;    int   native_fd;
562    struct stat sb;    jlong file_size;
563      int   result;
564    
565    native_fd = CONVERT_JLONG_TO_INT(fd);    native_fd = CONVERT_JLONG_TO_INT(fd);
566    
567    rc = fstat(native_fd, &sb);    TARGET_NATIVE_FILE_SIZE(native_fd, file_size, result);
568    if (rc == -1)    if (result != TARGET_NATIVE_OK)
569      {      {
570        JCL_ThrowException(env, "java/io/IOException", strerror(errno));        JCL_ThrowException(env,
571        return(-1);                           "java/io/IOException",
572                             TARGET_NATIVE_LAST_ERROR_STRING());
573          return(JNI_JLONG_CONST_MINUS_1);
574      }      }
575    
576    return(sb.st_size);    return(file_size);
577  }  }
578    
579  /*************************************************************************/  /*************************************************************************/
# Line 586  JNIEXPORT void JNICALL Line 585  JNIEXPORT void JNICALL
585  Java_java_io_FileDescriptor_nativeSetLength(JNIEnv *env, jobject obj,  Java_java_io_FileDescriptor_nativeSetLength(JNIEnv *env, jobject obj,
586                                              jlong fd, jlong len)                                              jlong fd, jlong len)
587  {  {
588    int native_fd;    int   native_fd;
589    off_t rc, native_len, save_pos;    jlong file_size;
590    struct stat sb;    int   bytes_written;
591    char c = '\0';    jlong save_offset,new_offset;
592      char  data;
593      int   result;
594    
595    native_fd = CONVERT_JLONG_TO_INT(fd);    native_fd = CONVERT_JLONG_TO_INT(fd);
596    native_len = CONVERT_JLONG_TO_OFF_T(len);  
597    #if 0
598      /* Should there be such an exception? All native layer macros should
599         be accepting 64bit-values if needed. It some target is not able
600         to handle such values it should simply operate with 32bit-values
601         and convert 64bit-values appriopated. In this case I assume
602         problems should not occurre: if some specific target is not able
603         to handle 64bit-values the system is limited to 32bit at all, thus
604         the application can not do a seek() or something else beyond the
605         32bit limit. It this true?
606      */
607    
608    /* FIXME: What do we do if len > the max value of off_t on this 32bit    /* FIXME: What do we do if len > the max value of off_t on this 32bit
609     * system?  How do we detect that and what do we do? */     * system?  How do we detect that and what do we do? */
610    if ((jlong)native_len != len)      if (CONVERT_OFF_T_TO_JLONG(native_len) != len)  
611      {      {
612        JCL_ThrowException(env, "java/io/IOException",        JCL_ThrowException(env, "java/io/IOException",
613                           "Cannot represent position correctly on this system");                           "Cannot represent position correctly on this system");
614        return;        return;
615      }      }
616        #endif
617    rc = fstat(native_fd, &sb);  
618    if (rc == -1)    /* get file size */
619      {    TARGET_NATIVE_FILE_SIZE(native_fd, file_size, result);
620        JCL_ThrowException(env, "java/io/IOException", strerror(errno));    if (result != TARGET_NATIVE_OK)
621        {
622          JCL_ThrowException(env,
623                             "java/io/IOException",
624                             TARGET_NATIVE_LAST_ERROR_STRING());
625        return;        return;
626      }      }
627    
628    /* Lucky us, perfect size */    if        (TARGET_NATIVE_MATH_INT_INT64_LT(file_size,len))
   if ((jlong)sb.st_size == len)  
     return;  
   
   /* File is too short -- seek to one byte short of where we want,  
    * then write a byte */  
   if ((jlong)sb.st_size < len)  
629      {      {
630          /* File is too short -- seek to one byte short of where we want,
631           * then write a byte */
632    
633        /* Save off current position */        /* Save off current position */
634        save_pos = lseek(native_fd, 0, SEEK_CUR);        TARGET_NATIVE_FILE_TELL(native_fd, save_offset, result);
635        if (save_pos != -1)        if (result != TARGET_NATIVE_OK)
         rc = lseek(native_fd, native_len - 1, SEEK_SET);  
       if ((save_pos == -1) || (rc == -1))  
636          {          {
637            JCL_ThrowException(env, "java/io/IOException", strerror(errno));            JCL_ThrowException(env,
638                                 "java/io/IOException",
639                                 TARGET_NATIVE_LAST_ERROR_STRING());
640              return;
641            }
642    
643          /* move to position n-1 */
644          TARGET_NATIVE_FILE_SEEK_BEGIN(native_fd, TARGET_NATIVE_MATH_INT_INT64_SUB(len,1), new_offset, result);
645          if (result != TARGET_NATIVE_OK)
646            {
647              JCL_ThrowException(env,
648                                 "java/io/IOException",
649                                 TARGET_NATIVE_LAST_ERROR_STRING());
650            return;            return;
651          }          }
652    
653        /* Note: This will fail if we somehow get here in read only mode        /* write a byte
654             Note: This will fail if we somehow get here in read only mode
655         * That shouldn't happen */         * That shouldn't happen */
656        rc = write(native_fd, &c, 1);        data='\0';
657        if (rc == -1)        TARGET_NATIVE_FILE_WRITE(native_fd, &data, 1, bytes_written, result);
658          {        if (result != TARGET_NATIVE_OK)
659            JCL_ThrowException(env, "java/io/IOException", strerror(errno));          {
660              JCL_ThrowException(env,
661                                 "java/io/IOException",
662                                 TARGET_NATIVE_LAST_ERROR_STRING());
663            return;            return;
664          }          }
665    
666        /* Reposition file pointer to where we started */        /* Reposition file pointer to where we started */
667        rc = lseek(native_fd, save_pos, SEEK_SET);        TARGET_NATIVE_FILE_SEEK_BEGIN(native_fd, save_offset, new_offset, result);
668        if (rc == -1)        if (result != TARGET_NATIVE_OK)
669          {          {
670            JCL_ThrowException(env, "java/io/IOException", strerror(errno));            JCL_ThrowException(env,
671                                 "java/io/IOException",
672                                 TARGET_NATIVE_LAST_ERROR_STRING());
673            return;            return;
674          }          }
       return;  
675      }      }
676        else if (TARGET_NATIVE_MATH_INT_INT64_GT(file_size,len))
   /* File is too long - use ftruncate if available */  
 #ifdef HAVE_FTRUNCATE  
   rc = ftruncate(native_fd, native_len);  
   if (rc == -1)  
677      {      {
678        JCL_ThrowException(env, "java/io/IOException", strerror(errno));              /* File is too long - use ftruncate if available */
679        return;  #ifdef HAVE_FTRUNCATE
680      }        TARGET_NATIVE_FILE_TRUNCATE(native_fd, len, result);
681          if (result != TARGET_NATIVE_OK)
682          {
683            JCL_ThrowException(env,
684                               "java/io/IOException",
685                               TARGET_NATIVE_LAST_ERROR_STRING());
686            return;
687          }
688  #else /* HAVE_FTRUNCATE */  #else /* HAVE_FTRUNCATE */
689    /* FIXME: Probably operation isn't supported, but this exception        /* FIXME: Probably operation isn't supported, but this exception
690     * is too harsh as it will probably crash the program without need         * is too harsh as it will probably crash the program without need
691    JCL_ThrowException(env, "java/lang/UnsupportedOperationException",        JCL_ThrowException(env, "java/lang/UnsupportedOperationException",
692      "not implemented - can't shorten files on this platform");          "not implemented - can't shorten files on this platform");
693    */        */
694    JCL_ThrowException(env, "java/io/IOException",        JCL_ThrowException(env, "java/io/IOException",
695                       "Unable to shorten file length");                           "Unable to shorten file length");
696  #endif /* HAVE_FTRUNCATE */  #endif /* HAVE_FTRUNCATE */
697        }
698  }  }
699    
700  /*************************************************************************/  /*************************************************************************/
# Line 673  Java_java_io_FileDescriptor_nativeSetLen Line 704  Java_java_io_FileDescriptor_nativeSetLen
704  JNIEXPORT jboolean JNICALL  JNIEXPORT jboolean JNICALL
705  Java_java_io_FileDescriptor_nativeValid(JNIEnv *env, jobject obj, jlong fd)  Java_java_io_FileDescriptor_nativeValid(JNIEnv *env, jobject obj, jlong fd)
706  {  {
707    int rc, native_fd;    int native_fd;
708    struct stat sb;    int result;
709    
710    native_fd = CONVERT_JLONG_TO_INT(fd);    native_fd = CONVERT_JLONG_TO_INT(fd);
711    
712    rc = fstat(native_fd, &sb);    TARGET_NATIVE_FILE_VALID_FILE_DESCRIPTOR(native_fd, result);
713    if (rc == -1)  
714      return JNI_FALSE;    return((result == TARGET_NATIVE_OK)?JNI_TRUE:JNI_FALSE);
   else  
     return JNI_TRUE;  
715  }  }
716    
717  /*************************************************************************/  /*************************************************************************/
# Line 693  Java_java_io_FileDescriptor_nativeValid( Line 722  Java_java_io_FileDescriptor_nativeValid(
722  JNIEXPORT void JNICALL  JNIEXPORT void JNICALL
723  Java_java_io_FileDescriptor_nativeSync(JNIEnv *env, jobject obj, jlong fd)  Java_java_io_FileDescriptor_nativeSync(JNIEnv *env, jobject obj, jlong fd)
724  {  {
725    int rc, native_fd;    int native_fd;
726      int result;
727    
728    native_fd = CONVERT_JLONG_TO_INT(fd);    native_fd = CONVERT_JLONG_TO_INT(fd);
729    
730  #ifdef HAVE_FSYNC  #ifdef HAVE_FSYNC
731    rc = fsync(native_fd);    TARGET_NATIVE_FILE_FSYNC(native_fd, result);
732    /* FIXME: gcj does not throw an exception on EROFS or EINVAL.    /* FIXME: gcj does not throw an exception on EROFS or EINVAL.
733     * Should we emulate? */     * Should we emulate? */
734    if (rc == -1)    if (result != TARGET_NATIVE_OK)
735      JCL_ThrowException(env, "java/io/SyncFailedException", strerror(errno));    {
736        JCL_ThrowException(env,
737                           "java/io/SyncFailedException",
738                           TARGET_NATIVE_LAST_ERROR_STRING());
739      }
740  #else  #else
741    JCL_ThrowException(env, "java/io/SyncFailedException",    JCL_ThrowException(env, "java/io/SyncFailedException",
742                       "Sync not supported");                       "Sync not supported");

Legend:
Removed from v.1.11  
changed lines
  Added in v.1.12

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26