[vlc-devel] [PATCH] logger/android: add an option to print stdout/stderr
Thomas Guillem
thomas at gllm.fr
Tue Apr 21 15:22:15 CEST 2015
Please ignore this patch, it belongs in android port.
On Thu, Apr 16, 2015, at 16:27, Thomas Guillem wrote:
> By default, stdout/stderr are deactivated, i.e. they are opened on
> /dev/null.
> If "androidlog-std" is true, stdout and stderr fd will be duplicated on a
> write
> end of a pipe. A thread will be cloned and will print the read end of the
> pipe.
>
> Standard output will be printed with "VLC-std" TAG with debug priority.
> Standard error will be printed with "VLC-std" TAG with error priority.
>
> It's not activated by default since we don't want to mess up with the
> application file descriptors.
> ---
> modules/logger/android.c | 176
> +++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 172 insertions(+), 4 deletions(-)
>
> diff --git a/modules/logger/android.c b/modules/logger/android.c
> index a89eb86..bddee2e 100644
> --- a/modules/logger/android.c
> +++ b/modules/logger/android.c
> @@ -34,6 +34,18 @@
> #include <vlc_common.h>
> #include <vlc_plugin.h>
>
> +typedef struct
> +{
> + int verbosity;
> +
> + int stop_pipe[2];
> + int stdout_pipe[2];
> + int stderr_pipe[2];
> + int old_stdout, old_stderr;
> +
> + vlc_thread_t stdthread;
> +} vlc_logger_sys_t;
> +
> static const int ptr_width = 2 * /* hex digits */ sizeof (uintptr_t);
>
> static void AndroidPrintMsg(void *opaque, int type, const vlc_log_t
> *p_item,
> @@ -41,9 +53,9 @@ static void AndroidPrintMsg(void *opaque, int type,
> const vlc_log_t *p_item,
> {
> int prio;
> char *format2;
> - int verbose = (intptr_t)opaque;
> + vlc_logger_sys_t *sys = opaque;
>
> - if (verbose < type)
> + if (sys->verbosity < type)
> return;
>
> int canc = vlc_savecancel();
> @@ -71,23 +83,179 @@ static void AndroidPrintMsg(void *opaque, int type,
> const vlc_log_t *p_item,
> vlc_restorecancel(canc);
> }
>
> +static ssize_t StdPrint(int fd, int prio)
> +{
> + char buf[1024 + 1];
> + ssize_t ret;
> +
> + ret = read(fd, buf, 1024);
> + if (ret <= 0)
> + return ret;
> +
> + buf[ret] = '\0';
> + __android_log_print(prio, "VLC-std", "%s", buf);
> +
> + return ret;
> +}
> +
> +static void *StdThread(void *arg)
> +{
> + vlc_logger_sys_t *sys = arg;
> +
> + while (true)
> + {
> + fd_set rfds;
> + int ret, nfds;
> +
> + FD_ZERO(&rfds);
> +
> + FD_SET(sys->stop_pipe[0], &rfds);
> + nfds = sys->stop_pipe[0];
> +
> + FD_SET(sys->stdout_pipe[0], &rfds);
> + if (sys->stdout_pipe[0] > nfds)
> + nfds = sys->stdout_pipe[0];
> +
> + FD_SET(sys->stderr_pipe[0], &rfds);
> + if (sys->stderr_pipe[0] > nfds)
> + nfds = sys->stderr_pipe[0];
> +
> + ret = select(nfds + 1, &rfds, NULL, NULL, NULL);
> +
> + if (ret == -1)
> + break;
> + else if (ret == 0)
> + continue;
> +
> + if (FD_ISSET(sys->stop_pipe[0], &rfds))
> + break;
> +
> + if (FD_ISSET(sys->stdout_pipe[0], &rfds)
> + && StdPrint(sys->stdout_pipe[0], ANDROID_LOG_DEBUG) <= 0)
> + break;
> +
> + if (FD_ISSET(sys->stderr_pipe[0], &rfds)
> + && StdPrint(sys->stderr_pipe[0], ANDROID_LOG_ERROR) <= 0)
> + break;
> + }
> + return NULL;
> +}
> +
> +static void ClosePipe(int *pipe)
> +{
> + if (pipe[0] != -1)
> + {
> + close(pipe[0]);
> + pipe[0] = -1;
> + }
> + if (pipe[1] != -1)
> + {
> + close(pipe[1]);
> + pipe[1] = -1;
> + }
> +}
> +
> +static void CleanUp(vlc_logger_sys_t *sys)
> +{
> + if (sys->stop_pipe[1] != -1)
> + {
> + write(sys->stop_pipe[1], '\0', 1);
> + close(sys->stop_pipe[1]);
> + sys->stop_pipe[1] = -1;
> + vlc_join(sys->stdthread, NULL);
> + }
> + ClosePipe(sys->stop_pipe);
> + ClosePipe(sys->stdout_pipe);
> + ClosePipe(sys->stderr_pipe);
> +
> + if (sys->old_stdout != -1 && sys->old_stderr != -1) {
> + dup2(sys->old_stdout, STDOUT_FILENO);
> + dup2(sys->old_stderr, STDERR_FILENO);
> + close(sys->old_stdout);
> + close(sys->old_stderr);
> + sys->old_stdout = sys->old_stderr = -1;
> + }
> +}
> +
> static vlc_log_cb Open(vlc_object_t *obj, void **sysp)
> {
> + vlc_logger_sys_t *sys = NULL;
> int verbosity = var_InheritInteger(obj, "verbose");
>
> if (verbosity < 0)
> return NULL;
>
> - *sysp = (void *)(uintptr_t)verbosity;
> + sys = calloc(1, sizeof (vlc_logger_sys_t));
> + if (!sys)
> + return NULL;
> +
> + sys->verbosity = verbosity;
> + sys->stop_pipe[0] = sys->stop_pipe[1] =
> + sys->stdout_pipe[0] = sys->stdout_pipe[1] =
> + sys->old_stdout = sys->old_stderr = -1;
> + *sysp = sys;
> +
> + /* By default, stdout/stderr are deactivated, i.e. they are opened
> on
> + * /dev/null. If androidlog-std is true, stdout and stderr fd will
> be
> + * duplicated on a write end of a pipe. A thread will be cloned and
> will
> + * print the read end of the pipe. */
> + if (!var_InheritBool(obj, "androidlog-std"))
> + return AndroidPrintMsg;
> +
> + /* save the old stdout/stderr fd to restore it when logged is closed
> */
> + sys->old_stdout = dup(STDOUT_FILENO);
> + sys->old_stderr = dup(STDERR_FILENO);
> + if (sys->old_stdout == -1 || sys->old_stderr == -1)
> + goto bailout;
> +
> + /* duplicate stdout */
> + if (pipe(sys->stdout_pipe) == -1)
> + goto bailout;
> + if (dup2(sys->stdout_pipe[1], STDOUT_FILENO) == -1)
> + goto bailout;
>
> + /* duplicate stderr */
> + if (pipe(sys->stderr_pipe) == -1)
> + goto bailout;
> + if (dup2(sys->stderr_pipe[1], STDERR_FILENO) == -1)
> + goto bailout;
> +
> + /* pipe to signal the thread to stop */
> + if (pipe(sys->stop_pipe) == -1)
> + goto bailout;
> +
> + if (vlc_clone(&sys->stdthread, StdThread, sys,
> VLC_THREAD_PRIORITY_LOW))
> + {
> + ClosePipe(sys->stop_pipe);
> + goto bailout;
> + }
> +
> + return AndroidPrintMsg;
> +bailout:
> + CleanUp(sys);
> return AndroidPrintMsg;
> }
>
> +static void Close(void *opaque)
> +{
> + vlc_logger_sys_t *sys = opaque;
> + CleanUp(sys);
> + free(sys);
> +}
> +
> +#define ANDROIDLOG_STD_TEXT N_("Log stdout/stderr")
> +#define ANDROIDLOG_STD_LONGTEXT N_( \
> + "On android, stdout and stderr are deactivated by default." \
> + "If set to true, the standard output and error will be printed " \
> + "via logcat with the 'VLC-std' TAG.")
> +
> vlc_module_begin()
> set_shortname(N_("Android log"))
> set_description(N_("Android log using logcat"))
> set_category(CAT_ADVANCED)
> set_subcategory(SUBCAT_ADVANCED_MISC)
> set_capability("logger", 30)
> - set_callbacks(Open, NULL)
> + set_callbacks(Open, Close)
> + add_bool("androidlog-std", false, ANDROIDLOG_STD_TEXT,
> + ANDROIDLOG_STD_LONGTEXT, true)
> vlc_module_end ()
> --
> 2.1.3
>
More information about the vlc-devel
mailing list