Skip to content

Commit b14d6c9

Browse files
committed
Fix using stat on Linux.
1 parent 4098735 commit b14d6c9

File tree

1 file changed

+21
-103
lines changed

1 file changed

+21
-103
lines changed

byte-buddy-agent/src/main/java/net/bytebuddy/agent/VirtualMachine.java

Lines changed: 21 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ public void close() throws IOException {
685685
}
686686

687687
/**
688-
* Implements a connection for a Posix socket in JNA.
688+
* Implements a connection for a POSIX socket in JNA.
689689
*/
690690
class ForJnaPosixSocket extends OnPersistentByteChannel<Integer> {
691691

@@ -700,7 +700,7 @@ class ForJnaPosixSocket extends OnPersistentByteChannel<Integer> {
700700
private final File socket;
701701

702702
/**
703-
* Creates a connection for a virtual posix socket implemented in JNA.
703+
* Creates a connection for a virtual POSIX socket implemented in JNA.
704704
*
705705
* @param library The JNA library to use.
706706
* @param socket The POSIX socket.
@@ -752,7 +752,7 @@ public void close() {
752752
}
753753

754754
/**
755-
* A JNA library binding for Posix sockets.
755+
* A JNA library binding for POSIX sockets.
756756
*/
757757
protected interface PosixLibrary extends Library {
758758

@@ -2081,26 +2081,22 @@ class ForJnaPosixEnvironment implements Dispatcher {
20812081
private final PosixLibrary library;
20822082

20832083
/**
2084-
* The posix owner to use.
2084+
* The POSIX owner provider to use.
20852085
*/
2086-
private final PosixOwner posixOwner;
2086+
private final PosixOwnerProvider provider;
20872087

20882088
/**
2089-
* Creates a new connector for a POSIX enviornment using JNA.
2089+
* Creates a new connector for a POSIX environment using JNA.
20902090
*
20912091
* @param attempts The maximum amount of attempts for checking the result of a foreign process.
20922092
* @param pause The pause between two checks for another process to return.
20932093
* @param timeUnit The time unit of the pause time.
20942094
*/
20952095
@SuppressWarnings("deprecation")
20962096
public ForJnaPosixEnvironment(int attempts, long pause, TimeUnit timeUnit) {
2097-
if (Platform.isMac()) {
2098-
posixOwner = new PosixOwner.ForMacEnvironment(attempts, pause, timeUnit);
2099-
} else if (Platform.isAIX()) {
2100-
posixOwner = new PosixOwner.ForAixEnvironment(attempts, pause, timeUnit);
2101-
} else {
2102-
posixOwner = new PosixOwner.ForLinuxEnvironment(attempts, pause, timeUnit);
2103-
}
2097+
provider = Platform.isAIX()
2098+
? new PosixOwnerProvider.UsingIStat(attempts, pause, timeUnit)
2099+
: new PosixOwnerProvider.UsingStat(attempts, pause, timeUnit);
21042100
library = Native.loadLibrary("c", PosixLibrary.class);
21052101
}
21062102

@@ -2144,7 +2140,7 @@ public boolean isExistingProcess(int processId) {
21442140
*/
21452141
@SuppressFBWarnings(value = "OS_OPEN_STREAM", justification = "The stream life-cycle is bound to its process.")
21462142
public int getOwnerIdOf(File file) {
2147-
return posixOwner.getOwnerIdOf(file);
2143+
return provider.getOwnerIdOf(file);
21482144
}
21492145

21502146
/**
@@ -2347,9 +2343,9 @@ protected List<String> getFieldOrder() {
23472343
}
23482344

23492345
/**
2350-
* Represents a system that supports posix.
2346+
* Represents a system that supports POSIX ownership.
23512347
*/
2352-
protected interface PosixOwner {
2348+
protected interface PosixOwnerProvider {
23532349

23542350
/**
23552351
* Returns the user id of the owner of the supplied file.
@@ -2360,9 +2356,9 @@ protected interface PosixOwner {
23602356
int getOwnerIdOf(File file);
23612357

23622358
/**
2363-
* An implementation of a posix owner for Linux.
2359+
* An implementation of reading POSIX ownership using {@code stat}.
23642360
*/
2365-
class ForLinuxEnvironment implements PosixOwner {
2361+
class UsingStat implements PosixOwnerProvider {
23662362

23672363
/**
23682364
* The maximum amount of attempts for checking the result of a foreign process.
@@ -2380,13 +2376,13 @@ class ForLinuxEnvironment implements PosixOwner {
23802376
private final TimeUnit timeUnit;
23812377

23822378
/**
2383-
* Creates a new connector for a Linux POSIX enviornment using stat.
2379+
* Creates a new provider where an owner is derived using the {@code stat} command.
23842380
*
23852381
* @param attempts The maximum amount of attempts for checking the result of a foreign process.
23862382
* @param pause The pause between two checks for another process to return.
23872383
* @param timeUnit The time unit of the pause time.
23882384
*/
2389-
public ForLinuxEnvironment(int attempts, long pause, TimeUnit timeUnit) {
2385+
public UsingStat(int attempts, long pause, TimeUnit timeUnit) {
23902386
this.attempts = attempts;
23912387
this.pause = pause;
23922388
this.timeUnit = timeUnit;
@@ -2400,7 +2396,7 @@ public int getOwnerIdOf(File file) {
24002396
// The binding for 'stat' is very platform dependant. To avoid the complexity of binding the correct method,
24012397
// stat is called as a separate command. This is less efficient but more portable.
24022398
Process process = Runtime.getRuntime().exec(new String[]{"stat",
2403-
"-f",
2399+
Platform.isMac() ? "-f" : "-c",
24042400
"%u",
24052401
file.getAbsolutePath()});
24062402
int attempts = this.attempts;
@@ -2438,9 +2434,9 @@ public int getOwnerIdOf(File file) {
24382434
}
24392435

24402436
/**
2441-
* An implementation for a posix owner that represents AIX.
2437+
* An implementation for reading a POSIX owner using {@code istat}.
24422438
*/
2443-
class ForAixEnvironment implements PosixOwner {
2439+
class UsingIStat implements PosixOwnerProvider {
24442440

24452441
/**
24462442
* A pattern to represent the owner on the console output.
@@ -2463,13 +2459,13 @@ class ForAixEnvironment implements PosixOwner {
24632459
private final TimeUnit timeUnit;
24642460

24652461
/**
2466-
* Creates a new connector for an AIX POSIX enviornment using stat.
2462+
* Creates a new provider for reading a POSIX owner using {@code istat}.
24672463
*
24682464
* @param attempts The maximum amount of attempts for checking the result of a foreign process.
24692465
* @param pause The pause between two checks for another process to return.
24702466
* @param timeUnit The time unit of the pause time.
24712467
*/
2472-
public ForAixEnvironment(int attempts, long pause, TimeUnit timeUnit) {
2468+
public UsingIStat(int attempts, long pause, TimeUnit timeUnit) {
24732469
this.attempts = attempts;
24742470
this.pause = pause;
24752471
this.timeUnit = timeUnit;
@@ -2524,84 +2520,6 @@ public int getOwnerIdOf(File file) {
25242520
}
25252521
}
25262522
}
2527-
2528-
/**
2529-
* An implementation for a posix owner that represents MacOS.
2530-
*/
2531-
class ForMacEnvironment implements PosixOwner {
2532-
2533-
/**
2534-
* The maximum amount of attempts for checking the result of a foreign process.
2535-
*/
2536-
private final int attempts;
2537-
2538-
/**
2539-
* The pause between two checks for another process to return.
2540-
*/
2541-
private final long pause;
2542-
2543-
/**
2544-
* The time unit of the pause time.
2545-
*/
2546-
private final TimeUnit timeUnit;
2547-
2548-
/**
2549-
* Creates a new connector for a Mac POSIX enviornment using stat.
2550-
*
2551-
* @param attempts The maximum amount of attempts for checking the result of a foreign process.
2552-
* @param pause The pause between two checks for another process to return.
2553-
* @param timeUnit The time unit of the pause time.
2554-
*/
2555-
public ForMacEnvironment(int attempts, long pause, TimeUnit timeUnit) {
2556-
this.attempts = attempts;
2557-
this.pause = pause;
2558-
this.timeUnit = timeUnit;
2559-
}
2560-
2561-
/**
2562-
* {@inheritDoc}
2563-
*/
2564-
public int getOwnerIdOf(File file) {
2565-
try {
2566-
// The binding for 'stat' is very platform dependant. To avoid the complexity of binding the correct method,
2567-
// stat is called as a separate command. This is less efficient but more portable.
2568-
Process process = Runtime.getRuntime().exec(new String[]{"stat",
2569-
"-f",
2570-
"%u",
2571-
file.getAbsolutePath()});
2572-
int attempts = this.attempts;
2573-
String line = null;
2574-
do {
2575-
try {
2576-
if (process.exitValue() != 0) {
2577-
throw new IllegalStateException("Error while executing stat");
2578-
}
2579-
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
2580-
try {
2581-
line = reader.readLine();
2582-
} finally {
2583-
reader.close();
2584-
}
2585-
break;
2586-
} catch (IllegalThreadStateException ignored) {
2587-
try {
2588-
Thread.sleep(timeUnit.toMillis(pause));
2589-
} catch (InterruptedException exception) {
2590-
Thread.currentThread().interrupt();
2591-
throw new IllegalStateException(exception);
2592-
}
2593-
}
2594-
} while (--attempts > 0);
2595-
if (line == null) {
2596-
process.destroy();
2597-
throw new IllegalStateException("Command for stat did not exit in time");
2598-
}
2599-
return Integer.parseInt(line);
2600-
} catch (IOException exception) {
2601-
throw new IllegalStateException("Unable to execute stat command", exception);
2602-
}
2603-
}
2604-
}
26052523
}
26062524
}
26072525

0 commit comments

Comments
 (0)