OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [java/] [io/] [natFilePosix.cc] - Blame information for rev 758

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 758 jeremybenn
// natFile.cc - Native part of File class for POSIX.
2
 
3
/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006, 2008
4
   Free Software Foundation
5
 
6
   This file is part of libgcj.
7
 
8
This software is copyrighted work licensed under the terms of the
9
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
10
details.  */
11
 
12
#include <config.h>
13
 
14
#include <stdio.h>
15
#include <errno.h>
16
#include <sys/param.h>
17
#include <sys/stat.h>
18
#include <sys/types.h>
19
#include <fcntl.h>
20
#ifdef HAVE_UNISTD_H
21
#include <unistd.h>
22
#endif
23
#include <stdlib.h>
24
#ifdef HAVE_DIRENT_H
25
#include <dirent.h>
26
#endif
27
#include <string.h>
28
#include <utime.h>
29
 
30
#include <gcj/cni.h>
31
#include <jvm.h>
32
#include <java/io/File.h>
33
#include <java/io/IOException.h>
34
#include <java/util/ArrayList.h>
35
#include <java/lang/String.h>
36
#include <java/io/FilenameFilter.h>
37
#include <java/io/FileFilter.h>
38
#include <java/lang/System.h>
39
 
40
jboolean
41
java::io::File::_access (jint query)
42
{
43
  char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
44
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
45
  buf[total] = '\0';
46
  JvAssert (query == READ || query == WRITE || query == EXISTS
47
            || query == EXEC);
48
#ifdef HAVE_ACCESS
49
  int mode;
50
  if (query == READ)
51
    mode = R_OK;
52
  else if (query == WRITE)
53
    mode = W_OK;
54
  else if (query == EXISTS)
55
    mode = F_OK;
56
  else
57
    mode = X_OK;
58
  return ::access (buf, mode) == 0;
59
#else
60
  return false;
61
#endif
62
}
63
 
64
jboolean
65
java::io::File::_stat (jint query)
66
{
67
  if (query == ISHIDDEN)
68
    return getName()->charAt(0) == '.';
69
 
70
#ifdef HAVE_STAT
71
  char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
72
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
73
  buf[total] = '\0';
74
 
75
  struct stat sb;
76
  if (::stat (buf, &sb))
77
    return false;
78
 
79
  JvAssert (query == DIRECTORY || query == ISFILE);
80
  jboolean r = S_ISDIR (sb.st_mode);
81
  return query == DIRECTORY ? r : ! r;
82
#else
83
  return false;
84
#endif
85
}
86
 
87
jlong
88
java::io::File::attr (jint query)
89
{
90
  char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
91
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
92
  buf[total] = '\0';
93
 
94
#ifdef HAVE_STAT
95
  struct stat sb;
96
  // FIXME: not sure about return value here.
97
  if (::stat (buf, &sb))
98
    return 0;
99
 
100
  JvAssert (query == MODIFIED || query == LENGTH);
101
  return query == MODIFIED ? (jlong)sb.st_mtime * 1000 : sb.st_size;
102
#else
103
  // There's no good choice here.
104
  return 23;
105
#endif
106
}
107
 
108
// These two methods are used to maintain dynamically allocated
109
// buffers for getCanonicalPath without the overhead of calling
110
// realloc every time a buffer is modified.  Buffers are sized
111
// at the smallest multiple of CHUNKSIZ that is greater than or
112
// equal to the desired length.  The default CHUNKSIZ is 256,
113
// longer than most paths, so in most cases a getCanonicalPath
114
// will require only one malloc per buffer.
115
 
116
#define CHUNKLOG 8
117
#define CHUNKSIZ (1 << CHUNKLOG)
118
 
119
static int
120
nextChunkSize (int size)
121
{
122
  return ((size >> CHUNKLOG) + ((size & (CHUNKSIZ - 1)) ? 1 : 0)) << CHUNKLOG;
123
}
124
 
125
static char *
126
maybeGrowBuf (char *buf, int *size, int required)
127
{
128
  if (required > *size)
129
    {
130
      *size = nextChunkSize (required);
131
      buf = (char *) _Jv_Realloc (buf, *size);
132
    }
133
  return buf;
134
}
135
 
136
// Return a canonical representation of the pathname of this file.  On
137
// the GNU system this involves the removal of redundant separators,
138
// references to "." and "..", and symbolic links.
139
//
140
// The conversion proceeds on a component-by-component basis: symbolic
141
// links and references to ".."  are resolved as and when they occur.
142
// This means that if "/foo/bar" is a symbolic link to "/baz" then the
143
// canonical form of "/foo/bar/.." is "/" and not "/foo".
144
//
145
// In order to mimic the behaviour of proprietary JVMs, non-existant
146
// path components are allowed (a departure from the normal GNU system
147
// convention).  This means that if "/foo/bar" is a symbolic link to
148
// "/baz", the canonical form of "/non-existant-directory/../foo/bar"
149
// is "/baz".
150
 
151
jstring
152
java::io::File::getCanonicalPath (void)
153
{
154
  jstring path = getAbsolutePath ();
155
 
156
  int len = JvGetStringUTFLength (path);
157
  int srcl = nextChunkSize (len + 1);
158
  char *src = (char *) _Jv_Malloc (srcl);
159
  JvGetStringUTFRegion (path, 0, path->length(), src);
160
  src[len] = '\0';
161
  int srci = 1;
162
 
163
  int dstl = nextChunkSize (2);
164
  char *dst = (char *) _Jv_Malloc (dstl);
165
  dst[0] = '/';
166
  int dsti = 1;
167
 
168
  bool fschecks = true;
169
 
170
  while (src[srci] != '\0')
171
    {
172
      // Skip slashes.
173
      while (src[srci] == '/')
174
        srci++;
175
      int tmpi = srci;
176
      // Find next slash.
177
      while (src[srci] != '/' && src[srci] != '\0')
178
        srci++;
179
      if (srci == tmpi)
180
        // We hit the end.
181
        break;
182
      len = srci - tmpi;
183
 
184
      // Handle "." and "..".
185
      if (len == 1 && src[tmpi] == '.')
186
        continue;
187
      if (len == 2 && src[tmpi] == '.' && src[tmpi + 1] == '.')
188
        {
189
          while (dsti > 1 && dst[dsti - 1] != '/')
190
            dsti--;
191
          if (dsti != 1)
192
            dsti--;
193
          // Reenable filesystem checking if disabled, as we might
194
          // have reversed over whatever caused the problem before.
195
          // At least one proprietary JVM has inconsistencies because
196
          // it does not do this.
197
          fschecks = true;
198
          continue;
199
        }
200
 
201
      // Handle real path components.
202
      dst = maybeGrowBuf (dst, &dstl, dsti + (dsti > 1 ? 1 : 0) + len + 1);
203
      int dsti_save = dsti;
204
      if (dsti > 1)
205
        dst[dsti++] = '/';
206
      strncpy (&dst[dsti], &src[tmpi], len);
207
      dsti += len;
208
      if (fschecks == false)
209
        continue;
210
 
211
#if defined (HAVE_LSTAT) && defined (HAVE_READLINK)
212
      struct stat sb;
213
      dst[dsti] = '\0';
214
      if (::lstat (dst, &sb) == 0)
215
        {
216
          if (S_ISLNK (sb.st_mode))
217
            {
218
              int tmpl = CHUNKSIZ;
219
              char *tmp = (char *) _Jv_Malloc (tmpl);
220
 
221
              while (1)
222
                {
223
                  tmpi = ::readlink (dst, tmp, tmpl);
224
                  if (tmpi < 1)
225
                    {
226
                      _Jv_Free (src);
227
                      _Jv_Free (dst);
228
                      _Jv_Free (tmp);
229
                      throw new IOException (
230
                        JvNewStringLatin1 ("readlink failed"));
231
                    }
232
                  if (tmpi < tmpl)
233
                    break;
234
                  tmpl += CHUNKSIZ;
235
                  tmp = (char *) _Jv_Realloc (tmp, tmpl);
236
                }
237
 
238
              // Prepend the link's path to src.
239
              tmp = maybeGrowBuf (tmp, &tmpl, tmpi + strlen (&src[srci]) + 1);
240
              strcpy(&tmp[tmpi], &src[srci]);
241
              _Jv_Free (src);
242
              src = tmp;
243
              srcl = tmpl;
244
              srci = 0;
245
 
246
              // Either replace or append dst depending on whether the
247
              // link is relative or absolute.
248
              dsti = src[0] == '/' ? 1 : dsti_save;
249
            }
250
        }
251
      else
252
        {
253
          // Something doesn't exist, or we don't have permission to
254
          // read it, or a previous path component is a directory, or
255
          // a symlink is looped.  Whatever, we can't check the
256
          // filesystem any more.
257
          fschecks = false;
258
        }
259
#endif // HAVE_LSTAT && HAVE_READLINK
260
    }
261
  dst[dsti] = '\0';
262
 
263
  // FIXME: what encoding to assume for file names?  This affects many
264
  // calls.
265
  path = JvNewStringUTF (dst);
266
  _Jv_Free (src);
267
  _Jv_Free (dst);
268
  return path;
269
}
270
 
271
jboolean
272
java::io::File::isAbsolute (void)
273
{
274
  return path->length() > 0 && path->charAt(0) == '/';
275
}
276
 
277
jobjectArray
278
java::io::File::performList (java::io::FilenameFilter *filter,
279
                             java::io::FileFilter *fileFilter,
280
                             java::lang::Class *result_type)
281
{
282
  /* Some systems have dirent.h, but no directory reading functions like
283
     opendir.  */
284
#if defined(HAVE_DIRENT_H) && defined(HAVE_OPENDIR)
285
  char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
286
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
287
  buf[total] = '\0';
288
 
289
  DIR *dir = opendir (buf);
290
  if (! dir)
291
    return NULL;
292
 
293
  java::util::ArrayList *list = new java::util::ArrayList ();
294
  struct dirent *d;
295
  while ((d = readdir (dir)) != NULL)
296
    {
297
      // Omit "." and "..".
298
      if (d->d_name[0] == '.'
299
          && (d->d_name[1] == '\0'
300
              || (d->d_name[1] == '.' && d->d_name[2] == '\0')))
301
        continue;
302
 
303
      jstring name = JvNewStringUTF (d->d_name);
304
      if (filter && ! filter->accept(this, name))
305
        continue;
306
 
307
      if (result_type == &java::io::File::class$)
308
        {
309
          java::io::File *file = new java::io::File (this, name);
310
          if (fileFilter && ! fileFilter->accept(file))
311
            continue;
312
 
313
          list->add(file);
314
        }
315
      else
316
        list->add(name);
317
    }
318
 
319
  closedir (dir);
320
 
321
  jobjectArray ret = JvNewObjectArray (list->size(), result_type, NULL);
322
  list->toArray(ret);
323
  return ret;
324
#else /* HAVE_DIRENT_H && HAVE_OPENDIR */
325
  return NULL;
326
#endif /* HAVE_DIRENT_H && HAVE_OPENDIR */
327
}
328
 
329
jboolean
330
java::io::File::performMkdir (void)
331
{
332
  char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
333
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
334
  buf[total] = '\0';
335
 
336
#ifdef HAVE_MKDIR
337
  return ::mkdir (buf, 0755) == 0;
338
#else
339
  return false;
340
#endif
341
}
342
 
343
jboolean
344
java::io::File::setFilePermissions (jboolean enable,
345
                                    jboolean ownerOnly,
346
                                    jint permissions)
347
{
348
  char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
349
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
350
  buf[total] = '\0';
351
  JvAssert (permissions == READ || permissions == WRITE || permissions == EXEC);
352
#if defined (HAVE_STAT) && defined (HAVE_CHMOD)
353
  mode_t mode = 0;
354
 
355
  struct stat sb;
356
  if (::stat (buf, &sb))
357
    return false;
358
 
359
  if (ownerOnly)
360
    {
361
      if (permissions == READ)
362
        mode |= S_IRUSR;
363
      else if (permissions == WRITE)
364
        mode |= S_IWUSR;
365
      else if (permissions == EXEC)
366
        mode |= S_IXUSR;
367
    }
368
  else
369
    {
370
      if (permissions == READ)
371
        mode |= (S_IRUSR | S_IRGRP | S_IROTH);
372
      else if (permissions == WRITE)
373
        mode |= (S_IWUSR | S_IWGRP | S_IWOTH);
374
      else if (permissions == EXEC)
375
        mode |= (S_IXUSR | S_IXGRP | S_IXOTH);
376
    }
377
 
378
  if (enable)
379
    mode = sb.st_mode | mode;
380
  else
381
    mode = sb.st_mode & ~mode;
382
 
383
  if (::chmod(buf, mode) < 0)
384
    return false;
385
  return true;
386
#else
387
  return false;
388
#endif
389
}
390
 
391
jboolean
392
java::io::File::performSetReadOnly (void)
393
{
394
  char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
395
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
396
  buf[total] = '\0';
397
 
398
#if defined (HAVE_STAT) && defined (HAVE_CHMOD)
399
  struct stat sb;
400
  if (::stat (buf, &sb))
401
    return false;
402
 
403
  if (::chmod(buf, sb.st_mode & 0555))
404
    return false;
405
  return true;
406
#else
407
  return false;
408
#endif
409
}
410
 
411
JArray< ::java::io::File *>*
412
java::io::File::performListRoots ()
413
{
414
  ::java::io::File *f = new ::java::io::File (JvNewStringLatin1 ("/"));
415
  JArray<java::io::File *> *unixroot
416
    = reinterpret_cast <JArray<java::io::File *>*>
417
          (JvNewObjectArray (1, &java::io::File::class$, f));
418
  elements (unixroot) [0] = f;
419
  return unixroot;
420
}
421
 
422
jboolean
423
java::io::File::performRenameTo (File *dest)
424
{
425
  char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
426
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
427
  buf[total] = '\0';
428
  char *buf2
429
    = (char *) __builtin_alloca (JvGetStringUTFLength (dest->path) + 1);
430
  total = JvGetStringUTFRegion (dest->path, 0, dest->path->length(), buf2);
431
  buf2[total] = '\0';
432
 
433
#ifdef HAVE_RENAME
434
  return ::rename (buf, buf2) == 0;
435
#else
436
  return false;
437
#endif
438
}
439
 
440
jboolean
441
java::io::File::performSetLastModified (jlong time)
442
{
443
#ifdef HAVE_UTIME
444
  utimbuf tb;
445
 
446
  char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
447
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
448
  buf[total] = '\0';
449
 
450
  tb.actime = time / 1000;
451
  tb.modtime = time / 1000;
452
  return (::utime (buf, &tb) == 0);
453
#else
454
  return false;
455
#endif
456
}
457
 
458
jboolean
459
java::io::File::performCreate (void)
460
{
461
  char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
462
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
463
  buf[total] = '\0';
464
 
465
  int fd = ::open (buf, O_CREAT | O_EXCL, 0644);
466
 
467
  if (fd < 0)
468
    {
469
      if (errno == EEXIST)
470
        return false;
471
      throw new IOException (JvNewStringLatin1 (strerror (errno)));
472
    }
473
  else
474
    {
475
      ::close (fd);
476
      return true;
477
    }
478
}
479
 
480
jboolean
481
java::io::File::performDelete (void)
482
{
483
  char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
484
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
485
  buf[total] = '\0';
486
 
487
#ifdef HAVE_UNLINK
488
#ifdef HAVE_RMDIR
489
  if (! ::rmdir (buf))
490
    return true;
491
  if (errno == ENOTDIR)
492
#endif // HAVE_RMDIR
493
    return ::unlink (buf) == 0;
494
#endif // HAVE_UNLINK
495
  return false;
496
}
497
 
498
void
499
java::io::File::init_native ()
500
{
501
#ifdef MAXPATHLEN
502
  maxPathLen = MAXPATHLEN;
503
#else
504
  /* Some systems do not have a limit on the length of a file name,
505
     the GNU system is one such example.  */
506
  maxPathLen = 0;
507
#endif
508
  caseSensitive = true;
509
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.