93d6842d3a0e95a9daa168f5a41ac2c5c16cbd40
[cacao.git] / nat / io.c
1 /****************************** nat/io.c ***************************************
2
3         Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
4
5         See file COPYRIGHT for information on usage and disclaimer of warranties
6
7         Contains the native functions for class java.io.
8
9         Authors: Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
10                  Mark Probst         EMAIL: cacao@complang.tuwien.ac.at
11
12         Last Change: 1997/10/22
13
14 *******************************************************************************/
15
16 #include <fcntl.h>
17 #include <dirent.h>
18 #include <sys/types.h>
19 #ifdef _OSF_SOURCE 
20 #include <sys/mode.h>
21 #endif
22 #include <sys/stat.h>
23
24 #include "../threads/threadio.h"                    /* schani */
25
26 /*
27  * io is performed through the threaded... functions, since io operations may
28  * block and the corresponding thread must, in this case, be suspended.
29  *
30  * schani
31  */
32
33 /********************* java.io.FileDescriptor ********************************/
34
35 s4 java_io_FileDescriptor_valid (struct java_io_FileDescriptor* this)
36 {
37         if (this->fd >= 0) return 1;
38         return 0;
39 }
40
41 struct java_io_FileDescriptor* java_io_FileDescriptor_initSystemFD 
42         (struct java_io_FileDescriptor* fd, s4 handle)
43 {
44         switch (handle) {
45         case 0:  fd -> fd = fileno(stdin); 
46                  break;
47         case 1:  fd -> fd = fileno(stdout);
48                  break;
49         case 2:  fd -> fd = fileno(stderr);
50                  break;
51         default: panic ("Invalid file descriptor number");
52         }
53
54         threadedFileDescriptor(fd->fd);
55
56         return fd;
57 }
58
59
60 /************************* java.io.FileInputStream ***************************/
61
62
63 void java_io_FileInputStream_open 
64        (struct java_io_FileInputStream* this, struct java_lang_String* name)
65 {
66         s4 fd;
67         char *fname = javastring_tochar ((java_objectheader*)name);
68
69         if (!fname) goto fail;
70
71         fd = open (fname, O_RDONLY, 0);
72         if (fd<0) goto fail;
73         
74         threadedFileDescriptor(fd);
75
76         this->fd->fd = fd;
77         return;
78
79         fail:
80                 exceptionptr = native_new_and_init (class_java_io_IOException);
81                 return;
82 }
83
84 s4 java_io_FileInputStream_read (struct java_io_FileInputStream* this)
85 {
86         s4 r;
87         u1 buffer[1];
88         r = threadedRead (this->fd->fd, (char *) buffer, 1);    
89
90         if (r>0) return buffer[0];
91         if (r==0) return -1;
92         
93         exceptionptr = native_new_and_init (class_java_io_IOException);
94         return 0;
95 }
96
97
98 s4 java_io_FileInputStream_readBytes (struct java_io_FileInputStream* this, 
99      java_bytearray* buffer, s4 start, s4 len)
100 {
101         s4 ret = threadedRead (this->fd->fd, (char *) buffer->data+start, len);
102         if (ret>0) return ret;
103         if (ret==0) return -1;
104         
105         exceptionptr = native_new_and_init (class_java_io_IOException);
106         return 0;
107 }
108
109
110 s8 java_io_FileInputStream_skip 
111        (struct java_io_FileInputStream* this, s8 numbytes)
112 {
113         s4 ret = lseek (this->fd->fd, builtin_l2i(numbytes), SEEK_CUR);
114         if (ret>0) return builtin_i2l(ret);
115         if (ret==0) return builtin_i2l(-1);
116         
117         exceptionptr = native_new_and_init (class_java_io_IOException);
118         return builtin_i2l(0);
119 }
120
121 s4 java_io_FileInputStream_available (struct java_io_FileInputStream* this)
122 {
123         struct stat buffer;
124         s4 r1,r2;
125         
126         r1 = fstat (this->fd->fd, &buffer);
127         r2 = lseek(this->fd->fd, 0, SEEK_CUR);
128         
129         if ( (r1 >= 0) && (r2 >= 0) )  
130                 return buffer.st_size - r2; 
131
132         exceptionptr = native_new_and_init (class_java_io_IOException);
133         return 0;
134 }
135
136 void java_io_FileInputStream_close (struct java_io_FileInputStream* this)
137 {
138         if (this->fd->fd >= 0) {
139                 s4 r = close (this->fd->fd);
140                 this->fd->fd = -1;
141                 if (r < 0) 
142                         exceptionptr = native_new_and_init (class_java_io_IOException);
143         }
144 }
145
146
147
148
149
150 /*************************** java.io.FileOutputStream ************************/
151
152
153 void java_io_FileOutputStream_open (struct java_io_FileOutputStream* this, 
154                                   struct java_lang_String* name)
155 {
156         s4 fd;
157         char *fname = javastring_tochar ((java_objectheader*)name);
158         if (!fname) goto fail;
159         
160         fd = creat (fname, 0666);
161         if (fd<0) goto fail;
162         
163         threadedFileDescriptor(fd);
164
165         this->fd->fd = fd;
166         return;
167
168         fail:
169                 exceptionptr = native_new_and_init (class_java_io_IOException);
170                 return;
171 }
172
173                                 
174 void java_io_FileOutputStream_write
175           (struct java_io_FileOutputStream* this, s4 byte)
176 {
177         u1 buffer[1];
178         s4 l;
179
180         buffer[0] = byte;
181         l = threadedWrite (this->fd->fd, (char *) buffer, 1);
182
183         if (l<1) {
184                 exceptionptr = native_new_and_init (class_java_io_IOException);
185                 }
186 }
187         
188 void java_io_FileOutputStream_writeBytes (struct java_io_FileOutputStream* this,
189                             java_bytearray* buffer, s4 start, s4 len)
190 {
191         s4 o;
192
193         if (len == 0)
194                 return;
195         o = threadedWrite (this->fd->fd, (char *) buffer->data+start, len);
196         if (o!=len) 
197                 exceptionptr = native_new_and_init (class_java_io_IOException);
198 }
199                             
200 void java_io_FileOutputStream_close (struct java_io_FileOutputStream* this)
201 {
202         if (this->fd->fd == 1)  /* don't close stderr!!! -- phil. */
203                 return;
204
205         if (this->fd->fd >= 0) {
206                 s4 r = close (this->fd->fd);
207                 this->fd->fd = -1;
208                 if (r<0) 
209                         exceptionptr = native_new_and_init (class_java_io_IOException);
210                 }
211 }
212
213
214
215 /************************** java.io.File **************************************/
216
217 s4 java_io_File_exists0 (struct java_io_File* this)
218 {
219         struct stat buffer;
220         char *path;
221         int err;
222         
223         path = javastring_tochar( (java_objectheader*) (this->path));
224         
225         err = stat (path, &buffer);
226         if (err==0) return 1;
227         return 0;
228 }       
229
230 s4 java_io_File_canWrite0 (struct java_io_File* this) 
231 {
232         int err;
233         err = access (javastring_tochar( (java_objectheader*) (this->path)), W_OK);
234         if (err==0) return 1;
235         return 0;
236 }
237
238 s4 java_io_File_canRead0 (struct java_io_File* this)
239 {
240         int err;
241         err = access (javastring_tochar( (java_objectheader*) (this->path)), R_OK);
242         if (err==0) return 1;
243         return 0;
244 }
245
246 s4 java_io_File_isFile0 (struct java_io_File* this)
247 {
248         struct stat buffer;
249         char *path;
250         int err;
251         
252         path = javastring_tochar( (java_objectheader*) (this->path));
253         
254         err = stat (path, &buffer);
255         if (err!=0) return 0;
256         if (S_ISREG(buffer.st_mode)) return 1;
257         return 0;
258 }
259
260 s4 java_io_File_isDirectory0 (struct java_io_File* this)
261 {
262         struct stat buffer;
263         char *path;
264         int err;
265         
266         path = javastring_tochar( (java_objectheader*) (this->path));
267         
268         err = stat (path, &buffer);
269         if (err!=0) return 0;
270         if (S_ISDIR(buffer.st_mode)) return 1;
271         return 0;
272 }
273  
274 s8 java_io_File_lastModified0 (struct java_io_File* this) 
275 {
276         struct stat buffer;
277         int err;
278         err = stat (javastring_tochar( (java_objectheader*) (this->path)),  &buffer);
279         if (err!=0) return builtin_i2l(0);
280         return builtin_lmul (builtin_i2l(buffer.st_mtime), builtin_i2l(1000) );
281 }
282
283 s8 java_io_File_length0 (struct java_io_File* this)
284 {
285         struct stat buffer;
286         int err;
287         err = stat (javastring_tochar( (java_objectheader*) (this->path)),  &buffer);
288         if (err!=0) return builtin_i2l(0);
289         return builtin_i2l(buffer.st_size);
290 }
291
292 s4 java_io_File_mkdir0 (struct java_io_File* this) 
293
294         char *name = javastring_tochar ( (java_objectheader*) (this->path) );
295         int err = mkdir (name, 0777);
296         if (err==0) return 1;
297         return 0;
298 }
299
300 s4 java_io_File_renameTo0 (struct java_io_File* this, struct java_io_File* new) 
301
302 #define MAXPATHLEN 200
303         char newname[MAXPATHLEN];
304         char *n = javastring_tochar ( (java_objectheader*) (new->path) );
305         int err;
306         
307         if (strlen(n)>=MAXPATHLEN) return 0;
308         strcpy (newname, n);
309         n = javastring_tochar ( (java_objectheader*) (this->path) );
310         err = rename (n, newname);
311         if (err==0) return 1;
312         return 0;
313 }
314
315 s4 java_io_File_delete0 (struct java_io_File* this) 
316
317         int err;
318         err = remove (javastring_tochar ( (java_objectheader*) (this->path) ) );
319         if (err==0) return 1;
320         return 0; 
321 }
322
323 java_objectarray* java_io_File_list0 (struct java_io_File* this) 
324
325         char *name;
326         DIR *d;
327         int i,len, namlen;
328         java_objectarray *a;
329         struct dirent *ent;
330         struct java_lang_String *n;
331         char entbuffer[257];
332         
333         name = javastring_tochar ( (java_objectheader*) (this->path) );
334         d = opendir(name);
335         if (!d) return NULL;
336         
337         len=0;
338         while (readdir(d) != NULL) len++;
339         rewinddir (d);
340         
341         a = builtin_anewarray (len, class_java_lang_String);
342         if (!a) {
343                 closedir(d);
344                 return NULL;
345                 }
346                 
347         for (i=0; i<len; i++) {
348                 if ( (ent = readdir(d)) != NULL) {
349                         namlen = strlen(ent->d_name);
350                         memcpy (entbuffer, ent->d_name, namlen);
351                         entbuffer[namlen] = '\0';
352                         
353                         n = (struct java_lang_String*) 
354                                 javastring_new_char (entbuffer);
355                         
356                         a -> data[i] = (java_objectheader*) n;
357                         }
358                 }
359
360
361         closedir(d);
362         return a;
363 }
364
365 s4 java_io_File_isAbsolute (struct java_io_File* this) 
366
367         char *name = javastring_tochar ( (java_objectheader*) (this->path) );
368         if (name[0] == '/') return 1;
369         return 0;
370 }
371
372
373
374
375 /********************** java.io.RandomAccessFile *****************************/
376
377 void java_io_RandomAccessFile_open (struct java_io_RandomAccessFile* this, 
378                struct java_lang_String* name, s4 writeable)
379 {
380         s4 fd;
381         char *fname = javastring_tochar ((java_objectheader*)name);
382         
383         if (writeable) fd = open (fname, O_RDWR, 0);
384         else           fd = open (fname, O_RDONLY, 0);
385         if (fd==-1) goto fail;
386
387         threadedFileDescriptor(fd);
388         
389         this->fd->fd = fd;
390         return;
391
392         fail:
393                 exceptionptr = native_new_and_init (class_java_io_IOException);
394                 return;
395 }
396
397 s4 java_io_RandomAccessFile_read (struct java_io_RandomAccessFile* this)
398
399         s4 r;
400         u1 buffer[1];
401         r = threadedRead (this->fd->fd, (char *) buffer, 1);    
402         if (r>0) return buffer[1];
403         if (r==0) return -1;
404         exceptionptr = native_new_and_init (class_java_io_IOException);
405         return 0;
406 }
407
408 s4 java_io_RandomAccessFile_readBytes (struct java_io_RandomAccessFile* this, 
409      java_bytearray* buffer, s4 start, s4 len)
410 {
411         s4 r = threadedRead (this->fd->fd, (char *) buffer->data+start, len);
412         if (r>0) return r;
413         if (r==0) return -1;
414         exceptionptr = native_new_and_init (class_java_io_IOException);
415         return 0;
416 }
417
418 void java_io_RandomAccessFile_write 
419        (struct java_io_RandomAccessFile* this, s4 byte)
420
421         u1 buffer[1];
422         int r;
423         buffer[1] = byte;
424         r = write (this->fd->fd, buffer, 1);
425         if (r<0) {
426                 exceptionptr = native_new_and_init (class_java_io_IOException);
427                 }
428 }
429
430 void java_io_RandomAccessFile_writeBytes (struct java_io_RandomAccessFile* this, 
431                             java_bytearray* buffer, s4 start, s4 len)
432 {
433         s4 o;
434         if (len == 0)
435                 return;
436         o = threadedWrite (this->fd->fd, (char *) buffer->data+start, len);
437         if (o!=len) exceptionptr = native_new_and_init (class_java_io_IOException);
438 }
439                
440 s8 java_io_RandomAccessFile_getFilePointer 
441         (struct java_io_RandomAccessFile* this)
442 {
443         s4 p = lseek (this->fd->fd, 0, SEEK_CUR);
444         if (p>=0) return builtin_i2l(p);
445         exceptionptr = native_new_and_init (class_java_io_IOException);
446         return builtin_i2l(0);
447 }
448
449 void java_io_RandomAccessFile_seek 
450            (struct java_io_RandomAccessFile* this, s8 offset)
451 {
452         s4 p = lseek (this->fd->fd, builtin_l2i(offset), SEEK_SET); 
453         if (p<0) {
454                 exceptionptr = native_new_and_init (class_java_io_IOException);
455                 }
456 }
457
458 s8 java_io_RandomAccessFile_length (struct java_io_RandomAccessFile* this)
459 {
460         struct stat buffer;
461         s4 r = fstat(this->fd->fd, &buffer);
462         if (r>=0) return builtin_i2l(buffer.st_size);
463         exceptionptr = native_new_and_init (class_java_io_IOException);
464         return builtin_i2l(0);
465 }
466
467 void java_io_RandomAccessFile_close (struct java_io_RandomAccessFile* this)
468 {       
469   if (this->fd->fd >= 0) {
470     s4 r = close (this->fd->fd);
471                 this->fd->fd = -1;
472                 if (r<0) 
473                         exceptionptr = native_new_and_init (class_java_io_IOException);
474                 }
475 }
476
477
478
479
480 /*
481  * These are local overrides for various environment variables in Emacs.
482  * Please do not remove this and leave it at the end of the file, where
483  * Emacs will automagically detect them.
484  * ---------------------------------------------------------------------
485  * Local variables:
486  * mode: c
487  * indent-tabs-mode: t
488  * c-basic-offset: 4
489  * tab-width: 4
490  * End:
491  */
492