File D:\maven-qcr-plugin-testsunitaires\qcr4java\jenkins-master\target\site\qc\core\src\main\java\jenkins\slaves\StandardOutputSwapper.java.html

1 package jenkins.slaves;
2
3 import hudson.Extension;
4 import hudson.FilePath;
5 import hudson.model.Computer;
6 import hudson.model.TaskListener;
7 import hudson.remoting.Callable;
8 import hudson.remoting.Channel;
9 import hudson.remoting.StandardOutputStream;
10 import hudson.slaves.ComputerListener;
11 import hudson.util.jna.GNUCLibrary;
12
13 import java.io.File;
14 import java.io.FileDescriptor;
15 import java.io.FileOutputStream;
16 import java.io.IOException;
17 import java.io.OutputStream;
18 import java.lang.reflect.Constructor;
19 import java.util.logging.Logger;
20
21 /**
22 * @author Kohsuke Kawaguchi
23 */
24 @Extension
25 public class StandardOutputSwapper extends ComputerListener {
26 @Override
27 public void preOnline(Computer c, Channel channel, FilePath root, TaskListener listener) {
28 if (disabled) return;
29
30 try {
31 if (channel.call(new ChannelSwapper()))
32 listener.getLogger().println("Evacuated stdout");
33 } catch (Throwable e) {
34 LOGGER.fine("Fatal problem swapping file descriptors " + c.getName());
35 }
36 }
37
38 private static final class ChannelSwapper implements Callable<Boolean,Exception> {
39 public Boolean call() throws Exception {
40 if (File.pathSeparatorChar==';') return false; // Windows
41
42 OutputStream o = Channel.current().getUnderlyingOutput();
43 if (o instanceof StandardOutputStream) {
44 StandardOutputStream stdout = (StandardOutputStream)o;
45
46 // duplicate the OS file descriptor and create FileOutputStream around it
47 int out = GNUCLibrary.LIBC.dup(1);
48 if (out<0) throw new IOException("Failed to dup(1)");
49 Constructor<FileDescriptor> c = FileDescriptor.class.getDeclaredConstructor(int.class);
50 c.setAccessible(true);
51 FileOutputStream fos = new FileOutputStream(c.newInstance(out));
52
53 // swap it into channel so that it'll use the new file descriptor
54 stdout.swap(fos);
55
56 // close fd=1 (stdout) and duplicate fd=2 (stderr) into fd=1 (stdout)
57 GNUCLibrary.LIBC.close(1);
58 GNUCLibrary.LIBC.dup2(2,1);
59 return true;
60 }
61 return false;
62 }
63 }
64
65 private static final Logger LOGGER = Logger.getLogger(StandardOutputSwapper.class.getName());
66 public static boolean disabled = Boolean.getBoolean(StandardOutputSwapper.class.getName()+".disabled");
67 }
68