/
NativeStreams.java
140 lines (125 loc) · 3.92 KB
/
NativeStreams.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
* This file is part of VLCJ.
*
* VLCJ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VLCJ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VLCJ. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2009, 2010, 2011, 2012, 2013, 2014 Caprica Software Limited.
*/
package uk.co.caprica.vlcj.runtime.streams;
import uk.co.caprica.vlcj.binding.LibC;
import com.sun.jna.Pointer;
/**
* Provide a way to redirect the native process standard output and error streams.
* <p>
* This can be useful with LibVLC because VLC and its various plugins can generate noisy and
* superfluous log messages to the native process standard error stream.
* <p>
* The normal Java redirection of System.out and System.err can not redirect the native process
* streams.
* <p>
* This should be used immediately at the start of your application.
*
* <strong>This class is experimental and may not work on all platforms!</strong>
*/
public final class NativeStreams {
/**
* File descriptor for stdout.
*/
private static final int STDOUT_FD = 1;
/**
* File descriptor for stdin.
*/
private static final int STDERR_FD = 2;
/**
* Open files in write mode.
*/
private static final String STREAM_MODE = "w";
/**
* The stdout stream.
*/
private Pointer outputStream;
/**
* The redirected stdout stream.
*/
private Pointer redirectedOutputStream;
/**
* The stderr stream.
*/
private Pointer errorStream;
/**
* The redirected stderr stream.
*/
private Pointer redirectedErrorStream;
/**
* Redirect native streams to files.
*
* @param outputTo new stdout file name, or <code>null</code>
* @param errorTo new stderr file name, or <code>null</code>
*/
public NativeStreams(String outputTo, String errorTo) {
if (outputTo != null) {
if (!redirectOutputTo(outputTo)) {
throw new IllegalStateException("Failed to redirect stdout");
}
}
if (errorTo != null) {
if (!redirectErrorTo(errorTo)) {
throw new IllegalStateException("Failed to redirect stderr");
}
}
}
/**
* Redirect the native process standard output stream to a file.
*
* @param target file
* @return
*/
private boolean redirectOutputTo(String target) {
outputStream = LibC.INSTANCE.fdopen(STDOUT_FD, STREAM_MODE);
if (outputStream != null) {
redirectedOutputStream = LibC.INSTANCE.freopen(target, STREAM_MODE, outputStream);
return redirectedOutputStream != null;
}
else {
return false;
}
}
/**
* Redirect the native process standard error stream to a file.
*
* @param target file
* @return
*/
private boolean redirectErrorTo(String target) {
errorStream = LibC.INSTANCE.fdopen(STDERR_FD, STREAM_MODE);
if (errorStream != null) {
redirectedErrorStream = LibC.INSTANCE.freopen(target, STREAM_MODE, errorStream);
return redirectedErrorStream != null;
}
else {
return false;
}
}
/**
* Close the redirected files.
*/
public void release() {
if (redirectedOutputStream != null) {
LibC.INSTANCE.fclose(redirectedOutputStream);
}
if (redirectedErrorStream != null) {
LibC.INSTANCE.fclose(redirectedErrorStream);
}
}
}