Opened 13 years ago

Closed 12 years ago

#42 closed enhancement (fixed)

don't read stdin when running in a noninteractive shell

Reported by: taeuber Owned by:
Priority: wish Component: ffmpeg
Version: git Keywords: noninteractive shell stdin
Cc: Blocked By:
Blocking: Reproduced by developer: yes
Analyzed by developer: yes

Description

ffmpeg reads stdin also when on a noninteractive shell:

See: https://lists.ffmpeg.org/pipermail/ffmpeg-user/2011-April/000252.html

Or is the reason for this behaviour a different one?

Thanks

Change History (11)

comment:1 by Michael Niedermayer, 13 years ago

If someone tells me how to detect "running in a noninteractive shell" halfway portably then this is
trivial to implement

comment:2 by taeuber, 13 years ago

Hi michael,

I'm not sure but this seems to be it:

$ man 4 tty
$ man tcgetpgrp
$ man getpgid

int am_I_interactive()
{

int fd = open ("/dev/tty", O_RDONLY);
int interactive = (tcgetpgrp(fd) == getpgid());
close (fd);
return interactive;

}

This is stolen from:
http://www.perlmonks.org/?node_id=472070

I understand this as following:

If I'm the process group leader I am interactive otherwise I'm noninteractive. (only on posix systems)

Thanks
Lars

comment:3 by Michael Niedermayer, 13 years ago

Owner: Michael Niedermayer removed
Status: newopen

Now someone just needs to add checks for errors (like file not found) and configure checks for the posix functions unless they are available everywhere.

And thanks for the hint.

comment:4 by taeuber, 13 years ago

Hi Michael,

this is how I would implement it:

int interactive()
{
    int fd, interactive;

    fd = open ("/dev/tty", O_RDONLY);
    if (fd < 0)
        return fd;

    interactive = (tcgetpgrp(fd) == getpgid(0));
    close (fd);
    return interactive;
}

I have no idea about autoconf tools.

But this doesn't solve the problem. It only tests foreground or background processing.
Maybe an additional command line option would be the solution of choice?

Lars

comment:5 by taeuber, 13 years ago

Hi Michael,

i found the correct solution:

inline int interactive()
{
    return isatty(0);
}

When STDIN is a terminal it is interactive otherwise not.

Yes, so simple!!

Best regards
Lars

Last edited 13 years ago by taeuber (previous) (diff)

in reply to:  5 ; comment:6 by Michael Niedermayer, 13 years ago

Replying to taeuber:

Hi Michael,

Hi lars

i found the correct solution:

inline int interactive()
{
    return isatty(0);

i wish it was so simple
but isatty is true for a command like
ffmpeg -i abc.avi def.avi &

and that will then still get stuck without </dev/null

in reply to:  6 comment:7 by taeuber, 13 years ago

Replying to michael:

Replying to taeuber:

Hi Michael,

Hi lars

i found the correct solution:

inline int interactive()
{
    return isatty(0);

i wish it was so simple
but isatty is true for a command like
ffmpeg -i abc.avi def.avi &

and that will then still get stuck without </dev/null

In this case we should check for being a foreground process.
I think this is what my first solution does:

int foreground_process()
{
    int fd, foreground;

    fd = open ("/dev/tty", O_RDONLY);
    if (fd < 0)
        return fd;

    foreground = (tcgetpgrp(fd) == getpgid(0));
    close (fd);
    return foreground;
}

Lars

Last edited 13 years ago by taeuber (previous) (diff)

comment:8 by taeuber, 13 years ago

We need to check for being a foreground process only if we are an interactive process.

int accept_stdin_commands = 0;
if interactive()
    if foreground_process()
        accept_stdin_commands = 1;

But being a foreground process can change during execution!
So we should expect the user to be smart enough to know the implications about background processes.

Lars

comment:9 by pfalcon, 12 years ago

This is crazy, internets are full of question how to disable this flaming interactive mode, and years thru, it's still not solved, and now there's discussion "how to detect it". Being smarter than a user is highly optional, so just let user tell what one wants with -non-interactive. Don't forget that being non-interactive means not only not reading from stdin, but also not outputting that stupid progress indicator which otherwise doesn't allow to capture clean and nice log, and instead non-deterministically intersperses itself with it:

[mpeg1video @ 0x813c710]ac-tex damaged at 21 17
[mpeg1video @ 0x813c710]Warning MVs not available
[mpeg1video @ 0x813c710]concealing 22 DC, 22 AC, 22 MV errors
frame=  932 fps=  0 q=0.0 size=      -0kB time=37.28 bitrate=  -0.0kbits/s dup=1 drop=0    ^M[mpeg1video @ 0x813c710]Warning MVs not a
[mpeg1video @ 0x813c710]concealing 22 DC, 22 AC, 22 MV errors
frame= 1841 fps=1839 q=0.0 size=      -0kB time=73.64 bitrate=  -0.0kbits/s dup=1 drop=0    ^M[mpeg1video @ 0x813c710]ac-tex damaged a

Thanks for thinking with perspective on how users can use your software!

in reply to:  9 comment:10 by Clément Bœsch, 12 years ago

Replying to pfalcon:

This is crazy, internets are full of question how to disable this flaming interactive mode, and years thru, it's still not solved, and now there's discussion "how to detect it". Being smarter than a user is highly optional, so just let user tell what one wants with -non-interactive.

The -d option (run as daemon) might be what you are looking for.

comment:11 by Stefano Sabatini, 12 years ago

Analyzed by developer: set
Reproduced by developer: set
Resolution: fixed
Status: openclosed

Should be addressed in:

commit 0fe8acf2d69bf4bce620128e48b62a957421a106
Author: Nicolas George <nicolas.george@normalesup.org>
Date:   Wed Jul 11 21:10:17 2012 +0200

    ffmpeg: add -(no)stdin option.
    
    Allows to disable interaction from standard input.
    Useful, for example, if ffmpeg is in the background process group.
    Roughly the same result can be achieved with "ffmpeg ... < /dev/null"
    but it requires a shell.

The -nostdin option will disable reading from stdin mode, and seems more robust than try to be more clever than the user and auto-detect interactive mode.
Together with -nostats should allow what pfalcon asks.

Note: See TracTickets for help on using tickets.