Как мне узнать имя окна полноэкранного интернет-контента (например, Flash)?

TL; DR: родительский объект ДОЛЖЕН использовать небуферизованный ввод-вывод, если последующий процесс должен читать именно с того места, где родитель остановился.

При небуферизованном вводе-выводе программа ведет себя правильно:

#include <stdio.h>
#include <string.h>
#include <unistd.h>

char buf[3];

int main(int argc, char *argv[])
{
    read(STDIN_FILENO, buf, 2);
    printf("%s '%s'\n", *argv, buf);
    if (strcmp(*argv, "./childtu") == 0) return 0;
    execl("./readtwo", "./childtu", (char *) 0);
}

При запуске через

$ make readtwo            
cc     readtwo.c   -o readtwo
$ echo abcdefg | ./readtwo
./readtwo 'ab'
./childtu 'cd'
$ 

Буферизованный ввод-вывод (через fgets ) в родительском элементе возникает проблема, поскольку дочерний элемент может только читать из стандартного ввода, если ввод больше, чем то, что родитель считывает заранее:

#include <stdio.h>
#include <string.h>
#include <unistd.h>

char buf[3];

int main(int argc, char *argv[])
{
    fgets(buf, 3, stdin);
    printf("%s '%s'\n", *argv, buf);
    if (strcmp(*argv, "./childtu") == 0) return 0;
    execl("./readtwo", "./childtu", (char *) 0);
}

Если любопытно, можно выполнить двоичный поиск точного размера буфера или посмотреть, что установлено в ядре:

$ perl -e 'print(("a")x99999)' | ./readtwo
./readtwo 'aa'
./childtu 'aa'
$ 

С strace (или аналогичный), мы можем наблюдать, сколько родительский процесс читает s из стандартного ввода (fd 0):

$ echo asdf | strace -o blah ./readtwo
./readtwo 'as'
./childtu ''
$ fgrep 'read(0' blah
read(0, "asdf\n", 4096)                 = 5
read(0, "", 4096)                       = 0
$

Здесь родительский процесс хотел 4096 байт (но получил только пять), а процесс exec получил ноль, так как ничего не осталось. Поэтому не используйте буферизованное чтение в родительском процессе, если это проблема.

1
26.12.2015, 21:03
0 ответов

Теги

Похожие вопросы