/* * 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-2016 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> for no redirection of stdout * @param errorTo new stderr file name, or <code>null</code> for no redirection of stderr */ 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 <code>true</code> if the stream was successfully redirected; <code>false</code> otherwise */ 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 <code>true</code> if the stream was successfully redirected; <code>false</code> otherwise */ 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); } } }