wpa_cli: Don't buffer stdout.

Submitted by Ben Greear on June 8, 2017, 8:21 p.m.

Details

Message ID 1496953269-28926-1-git-send-email-greearb@candelatech.com
State New
Headers show

Commit Message

Ben Greear June 8, 2017, 8:21 p.m.
From: Ben Greear <greearb@candelatech.com>

I am trying to read from a wpa_cli process using a perl script,
and it appears that wpa_cli was buffering output and so my script
would not see events properly.  This patch apepars to fix it.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 wpa_supplicant/wpa_cli.c | 5 +++++
 1 file changed, 5 insertions(+)

Comments

Slava Monich June 9, 2017, 12:46 p.m.
On 08/06/17 23:21, greearb@candelatech.com wrote:
> From: Ben Greear <greearb@candelatech.com>
>
> I am trying to read from a wpa_cli process using a perl script,
> and it appears that wpa_cli was buffering output and so my script
> would not see events properly.  This patch apepars to fix it.
>
> Signed-off-by: Ben Greear <greearb@candelatech.com>

Another way to fix this problem is to allocate a pty (pseudo terminal) 
and connect the output of the child process to that, to turn on line 
buffering in the stdio library [1]. Don't know how to do that from perl 
though...

It's a bit more complicated but once you learn how to do that, you no 
longer need to modify the program you are spawning in order to pull the 
output from it line by line.

[1]: http://rachid.koucha.free.fr/tech_corner/pty_pdip.html

Cheers,
-Slava


> ---
>   wpa_supplicant/wpa_cli.c | 5 +++++
>   1 file changed, 5 insertions(+)
>
> diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
> index 4cdc4fb..510f385 100644
> --- a/wpa_supplicant/wpa_cli.c
> +++ b/wpa_supplicant/wpa_cli.c
> @@ -4410,6 +4410,11 @@ int main(int argc, char *argv[])
>   		}
>   	}
>   
> +	/* Don't buffer stdout, we need to see events immediately as they
> +	 * happen.
> +	 */
> +	setbuf(stdout, NULL);
> +
>   	interactive = (argc == optind) && (action_file == NULL);
>   
>   	if (interactive)
Ben Greear June 9, 2017, 1:27 p.m.
On 06/09/2017 05:46 AM, Slava Monich wrote:
> On 08/06/17 23:21, greearb@candelatech.com wrote:
>> From: Ben Greear <greearb@candelatech.com>
>>
>> I am trying to read from a wpa_cli process using a perl script,
>> and it appears that wpa_cli was buffering output and so my script
>> would not see events properly.  This patch apepars to fix it.
>>
>> Signed-off-by: Ben Greear <greearb@candelatech.com>
>
> Another way to fix this problem is to allocate a pty (pseudo terminal) and connect the output of the child process to that, to turn on line buffering in the stdio library [1]. Don't know how to do that from perl though...
>
> It's a bit more complicated but once you learn how to do that, you no longer need to modify the program you are spawning in order to pull the output from it line by line.
>
> [1]: http://rachid.koucha.free.fr/tech_corner/pty_pdip.html

My fix seems a whole lot simpler than what you propose, but thanks for the suggestion!

Thanks,
Ben

>
> Cheers,
> -Slava
>
>
>> ---
>>   wpa_supplicant/wpa_cli.c | 5 +++++
>>   1 file changed, 5 insertions(+)
>>
>> diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
>> index 4cdc4fb..510f385 100644
>> --- a/wpa_supplicant/wpa_cli.c
>> +++ b/wpa_supplicant/wpa_cli.c
>> @@ -4410,6 +4410,11 @@ int main(int argc, char *argv[])
>>           }
>>       }
>>   +    /* Don't buffer stdout, we need to see events immediately as they
>> +     * happen.
>> +     */
>> +    setbuf(stdout, NULL);
>> +
>>       interactive = (argc == optind) && (action_file == NULL);
>>         if (interactive)
>
Ben Greear June 9, 2017, 4:55 p.m.
On 06/09/2017 09:21 AM, Paul Stewart wrote:
> On Fri, Jun 9, 2017 at 6:27 AM, Ben Greear <greearb@candelatech.com <mailto:greearb@candelatech.com>> wrote:
>
>
>
>     On 06/09/2017 05:46 AM, Slava Monich wrote:
>
>         On 08/06/17 23:21, greearb@candelatech.com <mailto:greearb@candelatech.com> wrote:
>
>             From: Ben Greear <greearb@candelatech.com <mailto:greearb@candelatech.com>>
>
>             I am trying to read from a wpa_cli process using a perl script,
>             and it appears that wpa_cli was buffering output and so my script
>             would not see events properly.  This patch apepars to fix it.
>
>             Signed-off-by: Ben Greear <greearb@candelatech.com <mailto:greearb@candelatech.com>>
>
>
>         Another way to fix this problem is to allocate a pty (pseudo terminal) and connect the output of the child process to that, to turn on line buffering in
>         the stdio library [1]. Don't know how to do that from perl though...
>
>         It's a bit more complicated but once you learn how to do that, you no longer need to modify the program you are spawning in order to pull the output
>         from it line by line.
>
>         [1]: http://rachid.koucha.free.fr/tech_corner/pty_pdip.html <http://rachid.koucha.free.fr/tech_corner/pty_pdip.html>
>
>
>     My fix seems a whole lot simpler than what you propose, but thanks for the suggestion!
>
>
> How about running "stdbuf -oL wpa_cli ...?"  Since you're running an exec from perl, that seems like an even more trivial change.

Well, my patch is already in my tree, so I'm OK either way.  I posted the patch more
to help other people in the future who may be more constrained on the tools they
can use and/or have no idea something like stdbuf exists.

I've never heard of stdbuf before, so that is another good trick to try to remember
next time something like this happens.

Thanks,
Ben

Patch hide | download patch | download mbox

diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 4cdc4fb..510f385 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -4410,6 +4410,11 @@  int main(int argc, char *argv[])
 		}
 	}
 
+	/* Don't buffer stdout, we need to see events immediately as they
+	 * happen.
+	 */
+	setbuf(stdout, NULL);
+
 	interactive = (argc == optind) && (action_file == NULL);
 
 	if (interactive)