[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