1
1
/*
2
- * Copyright (c) 2018, 2021 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2018, 2024 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
26
26
import static com .oracle .truffle .espresso .libjavavm .Arguments .abort ;
27
27
import static com .oracle .truffle .espresso .libjavavm .Arguments .abortExperimental ;
28
28
import static com .oracle .truffle .espresso .libjavavm .arghelper .ArgumentsHandler .isBooleanOption ;
29
- import static java .nio .file .StandardOpenOption .APPEND ;
30
- import static java .nio .file .StandardOpenOption .CREATE ;
31
- import static java .nio .file .StandardOpenOption .CREATE_NEW ;
32
- import static java .nio .file .StandardOpenOption .WRITE ;
33
29
34
- import java .io .BufferedOutputStream ;
35
30
import java .io .IOException ;
36
- import java .io .OutputStream ;
37
- import java .nio .channels .FileChannel ;
38
- import java .nio .channels .OverlappingFileLockException ;
39
- import java .nio .file .FileAlreadyExistsException ;
40
- import java .nio .file .Files ;
41
- import java .nio .file .LinkOption ;
42
- import java .nio .file .NoSuchFileException ;
43
31
import java .nio .file .Path ;
44
32
import java .nio .file .Paths ;
45
33
import java .util .ArrayList ;
50
38
import java .util .Map ;
51
39
import java .util .logging .Level ;
52
40
53
- import org .graalvm .collections . Pair ;
41
+ import org .graalvm .launcher . Launcher ;
54
42
import org .graalvm .options .OptionCategory ;
55
43
import org .graalvm .options .OptionDescriptor ;
56
44
import org .graalvm .options .OptionDescriptors ;
@@ -90,7 +78,7 @@ void argumentProcessingDone() {
90
78
}
91
79
if (logFile != null ) {
92
80
try {
93
- builder .logHandler (newLogStream (logFile ));
81
+ builder .logHandler (Launcher . newLogStream (logFile ));
94
82
} catch (IOException ioe ) {
95
83
throw abort (ioe .toString ());
96
84
}
@@ -161,18 +149,15 @@ void parsePolyglotOption(String group, String key, String value, String arg, boo
161
149
162
150
private OptionDescriptor findOptionDescriptor (String group , String key ) {
163
151
OptionDescriptors descriptors = null ;
164
- switch (group ) {
165
- case "engine" :
166
- descriptors = getTempEngine ().getOptions ();
167
- break ;
168
- default :
169
- Engine engine = getTempEngine ();
170
- if (engine .getLanguages ().containsKey (group )) {
171
- descriptors = engine .getLanguages ().get (group ).getOptions ();
172
- } else if (engine .getInstruments ().containsKey (group )) {
173
- descriptors = engine .getInstruments ().get (group ).getOptions ();
174
- }
175
- break ;
152
+ if (group .equals ("engine" )) {
153
+ descriptors = getTempEngine ().getOptions ();
154
+ } else {
155
+ Engine engine = getTempEngine ();
156
+ if (engine .getLanguages ().containsKey (group )) {
157
+ descriptors = engine .getLanguages ().get (group ).getOptions ();
158
+ } else if (engine .getInstruments ().containsKey (group )) {
159
+ descriptors = engine .getInstruments ().get (group ).getOptions ();
160
+ }
176
161
}
177
162
if (descriptors == null ) {
178
163
return null ;
@@ -231,7 +216,7 @@ static final class PrintableOption implements Comparable<PrintableOption> {
231
216
final String option ;
232
217
final String description ;
233
218
234
- protected PrintableOption (String option , String description ) {
219
+ private PrintableOption (String option , String description ) {
235
220
this .option = option ;
236
221
this .description = description ;
237
222
}
@@ -243,21 +228,12 @@ public int compareTo(PrintableOption o) {
243
228
}
244
229
245
230
private static String optionsTitle (String kind , OptionCategory optionCategory ) {
246
- String category ;
247
- switch (optionCategory ) {
248
- case USER :
249
- category = "User " ;
250
- break ;
251
- case EXPERT :
252
- category = "Expert " ;
253
- break ;
254
- case INTERNAL :
255
- category = "Internal " ;
256
- break ;
257
- default :
258
- category = "" ;
259
- break ;
260
- }
231
+ String category = switch (optionCategory ) {
232
+ case USER -> "User " ;
233
+ case EXPERT -> "Expert " ;
234
+ case INTERNAL -> "Internal " ;
235
+ default -> "" ;
236
+ };
261
237
return category + kind + " options:" ;
262
238
}
263
239
@@ -291,9 +267,7 @@ private static PrintableOption asPrintableOption(OptionDescriptor descriptor) {
291
267
StringBuilder key = new StringBuilder ("--" );
292
268
key .append (descriptor .getName ());
293
269
Object defaultValue = descriptor .getKey ().getDefaultValue ();
294
- if (defaultValue instanceof Boolean && defaultValue == Boolean .FALSE ) {
295
- // nothing to print
296
- } else {
270
+ if (defaultValue != Boolean .FALSE ) {
297
271
key .append ("=<" );
298
272
key .append (descriptor .getKey ().getType ().getName ());
299
273
key .append (">" );
@@ -320,155 +294,4 @@ private static List<Instrument> sortedInstruments(Engine engine) {
320
294
return instruments ;
321
295
}
322
296
323
- /**
324
- * Creates a new log file. The method uses a supplemental lock file to determine the file is
325
- * still opened for output; in that case, it creates a different file, named `path'1, `path`2,
326
- * ... until it finds a free name. Files not locked (actively written to) are overwritten.
327
- *
328
- * @param path the desired output for log
329
- * @return the OutputStream for logging
330
- * @throws IOException in case of I/O error opening the file
331
- * @since 20.0
332
- */
333
- protected static OutputStream newLogStream (Path path ) throws IOException {
334
- Path usedPath = path ;
335
- Path fileNamePath = path .getFileName ();
336
- String fileName = fileNamePath == null ? "" : fileNamePath .toString ();
337
- Path lockFile = null ;
338
- FileChannel lockFileChannel = null ;
339
- for (int unique = 0 ;; unique ++) {
340
- StringBuilder lockFileNameBuilder = new StringBuilder (fileName );
341
- if (unique > 0 ) {
342
- lockFileNameBuilder .append (unique );
343
- usedPath = path .resolveSibling (lockFileNameBuilder .toString ());
344
- }
345
- lockFileNameBuilder .append (".lck" );
346
- lockFile = path .resolveSibling (lockFileNameBuilder .toString ());
347
- Pair <FileChannel , Boolean > openResult = openChannel (lockFile );
348
- if (openResult != null ) {
349
- lockFileChannel = openResult .getLeft ();
350
- if (lock (lockFileChannel , openResult .getRight ())) {
351
- break ;
352
- } else {
353
- // Close and try next name
354
- lockFileChannel .close ();
355
- }
356
- }
357
- }
358
- assert lockFile != null && lockFileChannel != null ;
359
- boolean success = false ;
360
- try {
361
- OutputStream stream = new LockableOutputStream (
362
- new BufferedOutputStream (Files .newOutputStream (usedPath , WRITE , CREATE , APPEND )),
363
- lockFile ,
364
- lockFileChannel );
365
- success = true ;
366
- return stream ;
367
- } finally {
368
- if (!success ) {
369
- LockableOutputStream .unlock (lockFile , lockFileChannel );
370
- }
371
- }
372
- }
373
-
374
- private static Pair <FileChannel , Boolean > openChannel (Path path ) throws IOException {
375
- FileChannel channel = null ;
376
- for (int retries = 0 ; channel == null && retries < 2 ; retries ++) {
377
- try {
378
- channel = FileChannel .open (path , CREATE_NEW , WRITE );
379
- return Pair .create (channel , true );
380
- } catch (FileAlreadyExistsException faee ) {
381
- // Maybe a FS race showing a zombie file, try to reuse it
382
- if (Files .isRegularFile (path , LinkOption .NOFOLLOW_LINKS ) && isParentWritable (path )) {
383
- try {
384
- channel = FileChannel .open (path , WRITE , APPEND );
385
- return Pair .create (channel , false );
386
- } catch (NoSuchFileException x ) {
387
- // FS Race, next try we should be able to create with CREATE_NEW
388
- } catch (IOException x ) {
389
- return null ;
390
- }
391
- } else {
392
- return null ;
393
- }
394
- }
395
- }
396
- return null ;
397
- }
398
-
399
- private static boolean isParentWritable (Path path ) {
400
- Path parentPath = path .getParent ();
401
- if (parentPath == null && !path .isAbsolute ()) {
402
- parentPath = path .toAbsolutePath ().getParent ();
403
- }
404
- return parentPath != null && Files .isWritable (parentPath );
405
- }
406
-
407
- private static boolean lock (FileChannel lockFileChannel , boolean newFile ) {
408
- boolean available = false ;
409
- try {
410
- available = lockFileChannel .tryLock () != null ;
411
- } catch (OverlappingFileLockException ofle ) {
412
- // VM already holds lock continue with available set to false
413
- } catch (IOException ioe ) {
414
- // Locking not supported by OS
415
- available = newFile ;
416
- }
417
- return available ;
418
- }
419
-
420
- private static final class LockableOutputStream extends OutputStream {
421
-
422
- private final OutputStream delegate ;
423
- private final Path lockFile ;
424
- private final FileChannel lockFileChannel ;
425
-
426
- LockableOutputStream (OutputStream delegate , Path lockFile , FileChannel lockFileChannel ) {
427
- this .delegate = delegate ;
428
- this .lockFile = lockFile ;
429
- this .lockFileChannel = lockFileChannel ;
430
- }
431
-
432
- @ Override
433
- public void write (int b ) throws IOException {
434
- delegate .write (b );
435
- }
436
-
437
- @ Override
438
- public void write (byte [] b ) throws IOException {
439
- delegate .write (b );
440
- }
441
-
442
- @ Override
443
- public void write (byte [] b , int off , int len ) throws IOException {
444
- delegate .write (b , off , len );
445
- }
446
-
447
- @ Override
448
- public void flush () throws IOException {
449
- delegate .flush ();
450
- }
451
-
452
- @ Override
453
- public void close () throws IOException {
454
- try {
455
- delegate .close ();
456
- } finally {
457
- unlock (lockFile , lockFileChannel );
458
- }
459
- }
460
-
461
- private static void unlock (Path lockFile , FileChannel lockFileChannel ) {
462
- try {
463
- lockFileChannel .close ();
464
- } catch (IOException ioe ) {
465
- // Error while closing the channel, ignore.
466
- }
467
- try {
468
- Files .delete (lockFile );
469
- } catch (IOException ioe ) {
470
- // Error while deleting the lock file, ignore.
471
- }
472
- }
473
- }
474
297
}
0 commit comments