Initial revision
[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 >= 0) {
203                 s4 r = close (this->fd->fd);
204                 this->fd->fd = -1;
205                 if (r<0) 
206                         exceptionptr = native_new_and_init (class_java_io_IOException);
207                 }
208 }
209
210
211
212 /************************** java.io.File **************************************/
213
214 s4 java_io_File_exists0 (struct java_io_File* this)
215 {
216         struct stat buffer;
217         char *path;
218         int err;
219         
220         path = javastring_tochar( (java_objectheader*) (this->path));
221         
222         err = stat (path, &buffer);
223         if (err==0) return 1;
224         return 0;
225 }       
226
227 s4 java_io_File_canWrite0 (struct java_io_File* this) 
228 {
229         int err;
230         err = access (javastring_tochar( (java_objectheader*) (this->path)), W_OK);
231         if (err==0) return 1;
232         return 0;
233 }
234
235 s4 java_io_File_canRead0 (struct java_io_File* this)
236 {
237         int err;
238         err = access (javastring_tochar( (java_objectheader*) (this->path)), R_OK);
239         if (err==0) return 1;
240         return 0;
241 }
242
243 s4 java_io_File_isFile0 (struct java_io_File* this)
244 {
245         struct stat buffer;
246         char *path;
247         int err;
248         
249         path = javastring_tochar( (java_objectheader*) (this->path));
250         
251         err = stat (path, &buffer);
252         if (err!=0) return 0;
253         if (S_ISREG(buffer.st_mode)) return 1;
254         return 0;
255 }
256
257 s4 java_io_File_isDirectory0 (struct java_io_File* this)
258 {
259         struct stat buffer;
260         char *path;
261         int err;
262         
263         path = javastring_tochar( (java_objectheader*) (this->path));
264         
265         err = stat (path, &buffer);
266         if (err!=0) return 0;
267         if (S_ISDIR(buffer.st_mode)) return 1;
268         return 0;
269 }
270  
271 s8 java_io_File_lastModified0 (struct java_io_File* this) 
272 {
273         struct stat buffer;
274         int err;
275         err = stat (javastring_tochar( (java_objectheader*) (this->path)),  &buffer);
276         if (err!=0) return builtin_i2l(0);
277         return builtin_lmul (builtin_i2l(buffer.st_mtime), builtin_i2l(1000) );
278 }
279
280 s8 java_io_File_length0 (struct java_io_File* this)
281 {
282         struct stat buffer;
283         int err;
284         err = stat (javastring_tochar( (java_objectheader*) (this->path)),  &buffer);
285         if (err!=0) return builtin_i2l(0);
286         return builtin_i2l(buffer.st_size);
287 }
288
289 s4 java_io_File_mkdir0 (struct java_io_File* this) 
290
291         char *name = javastring_tochar ( (java_objectheader*) (this->path) );
292         int err = mkdir (name, 0777);
293         if (err==0) return 1;
294         return 0;
295 }
296
297 s4 java_io_File_renameTo0 (struct java_io_File* this, struct java_io_File* new) 
298
299 #define MAXPATHLEN 200
300         char newname[MAXPATHLEN];
301         char *n = javastring_tochar ( (java_objectheader*) (new->path) );
302         int err;
303         
304         if (strlen(n)>=MAXPATHLEN) return 0;
305         strcpy (newname, n);
306         n = javastring_tochar ( (java_objectheader*) (this->path) );
307         err = rename (n, newname);
308         if (err==0) return 1;
309         return 0;
310 }
311
312 s4 java_io_File_delete0 (struct java_io_File* this) 
313
314         int err;
315         err = remove (javastring_tochar ( (java_objectheader*) (this->path) ) );
316         if (err==0) return 1;
317         return 0; 
318 }
319
320 java_objectarray* java_io_File_list0 (struct java_io_File* this) 
321
322         char *name;
323         DIR *d;
324         int i,len, namlen;
325         java_objectarray *a;
326         struct dirent *ent;
327         struct java_lang_String *n;
328         char entbuffer[257];
329         
330         name = javastring_tochar ( (java_objectheader*) (this->path) );
331         d = opendir(name);
332         if (!d) return NULL;
333         
334         len=0;
335         while (readdir(d) != NULL) len++;
336         rewinddir (d);
337         
338         a = builtin_anewarray (len, class_java_lang_String);
339         if (!a) {
340                 closedir(d);
341                 return NULL;
342                 }
343                 
344         for (i=0; i<len; i++) {
345                 if ( (ent = readdir(d)) != NULL) {
346                         namlen = strlen(ent->d_name);
347                         memcpy (entbuffer, ent->d_name, namlen);
348                         entbuffer[namlen] = '\0';
349                         
350                         n = (struct java_lang_String*) 
351                                 javastring_new_char (entbuffer);
352                         
353                         a -> data[i] = (java_objectheader*) n;
354                         }
355                 }
356
357
358         closedir(d);
359         return a;
360 }
361
362 s4 java_io_File_isAbsolute (struct java_io_File* this) 
363
364         char *name = javastring_tochar ( (java_objectheader*) (this->path) );
365         if (name[0] == '/') return 1;
366         return 0;
367 }
368
369
370
371
372 /********************** java.io.RandomAccessFile *****************************/
373
374 void java_io_RandomAccessFile_open (struct java_io_RandomAccessFile* this, 
375                struct java_lang_String* name, s4 writeable)
376 {
377         s4 fd;
378         char *fname = javastring_tochar ((java_objectheader*)name);
379         
380         if (writeable) fd = open (fname, O_RDWR, 0);
381         else           fd = open (fname, O_RDONLY, 0);
382         if (fd==-1) goto fail;
383
384         threadedFileDescriptor(fd);
385         
386         this->fd->fd = fd;
387         return;
388
389         fail:
390                 exceptionptr = native_new_and_init (class_java_io_IOException);
391                 return;
392 }
393
394 s4 java_io_RandomAccessFile_read (struct java_io_RandomAccessFile* this)
395
396         s4 r;
397         u1 buffer[1];
398         r = threadedRead (this->fd->fd, (char *) buffer, 1);    
399         if (r>0) return buffer[1];
400         if (r==0) return -1;
401         exceptionptr = native_new_and_init (class_java_io_IOException);
402         return 0;
403 }
404
405 s4 java_io_RandomAccessFile_readBytes (struct java_io_RandomAccessFile* this, 
406      java_bytearray* buffer, s4 start, s4 len)
407 {
408         s4 r = threadedRead (this->fd->fd, (char *) buffer->data+start, len);
409         if (r>0) return r;
410         if (r==0) return -1;
411         exceptionptr = native_new_and_init (class_java_io_IOException);
412         return 0;
413 }
414
415 void java_io_RandomAccessFile_write 
416        (struct java_io_RandomAccessFile* this, s4 byte)
417
418         u1 buffer[1];
419         int r;
420         buffer[1] = byte;
421         r = write (this->fd->fd, buffer, 1);
422         if (r<0) {
423                 exceptionptr = native_new_and_init (class_java_io_IOException);
424                 }
425 }
426
427 void java_io_RandomAccessFile_writeBytes (struct java_io_RandomAccessFile* this, 
428                             java_bytearray* buffer, s4 start, s4 len)
429 {
430         s4 o;
431         if (len == 0)
432                 return;
433         o = threadedWrite (this->fd->fd, (char *) buffer->data+start, len);
434         if (o!=len) exceptionptr = native_new_and_init (class_java_io_IOException);
435 }
436                
437 s8 java_io_RandomAccessFile_getFilePointer 
438         (struct java_io_RandomAccessFile* this)
439 {
440         s4 p = lseek (this->fd->fd, 0, SEEK_CUR);
441         if (p>=0) return builtin_i2l(p);
442         exceptionptr = native_new_and_init (class_java_io_IOException);
443         return builtin_i2l(0);
444 }
445
446 void java_io_RandomAccessFile_seek 
447            (struct java_io_RandomAccessFile* this, s8 offset)
448 {
449         s4 p = lseek (this->fd->fd, builtin_l2i(offset), SEEK_SET); 
450         if (p<0) {
451                 exceptionptr = native_new_and_init (class_java_io_IOException);
452                 }
453 }
454
455 s8 java_io_RandomAccessFile_length (struct java_io_RandomAccessFile* this)
456 {
457         struct stat buffer;
458         s4 r = fstat(this->fd->fd, &buffer);
459         if (r>=0) return builtin_i2l(buffer.st_size);
460         exceptionptr = native_new_and_init (class_java_io_IOException);
461         return builtin_i2l(0);
462 }
463
464 void java_io_RandomAccessFile_close (struct java_io_RandomAccessFile* this)
465 {       
466         if (this->fd->fd >= 0) {
467                 s4 r = close (this->fd->fd);
468                 this->fd->fd = -1;
469                 if (r<0) 
470                         exceptionptr = native_new_and_init (class_java_io_IOException);
471                 }
472 }
473