Этот тип поведения определяется стандартом? - PullRequest
3 голосов
/ 01 июля 2011
#include <unistd.h>
int main(int argc, char* argv[])
{
  char buf[500];
  read(0, buf, 5);
  return 0;
}

Вышеуказанные read 5 символов из stdin, но если я введу больше, чем 5:

12345morethan5
[root@ test]# morethan5
-bash: morethan5: command not found

Остальные символы будут выполняться как команды оболочки.

Этот тип поведения определяется стандартом?

Ответы [ 2 ]

5 голосов
/ 01 июля 2011

Сортировка: -)

Ваша программа читает 5 символов, и все. Не меньше, не больше. Остальные остаются в буфере терминала и отправляются в вашу оболочку после завершения вашей программы на С.

Поскольку вы используете read(), который является необработанным системным вызовом, вместо какой-либо альтернативы буферизации в C stdio, такое поведение не просто ожидается, а требуется .

Из стандарта POSIX на read():

Функция read () должна пытаться читать байты из файла связанный с открытым файлом дескриптор, fildes, в буфер указал на буф.

...

После успешного завершения, где nbyte больше 0, read () пометить для обновления поле st_atime файл, и должен вернуть номер прочитанных байтов. Этот номер никогда не должен быть больше чем nbyte.

...

После успешного завершения прочитайте () [XSI] [Option Start] и pread () [Option End] должен вернуть неотрицательное целое число, указывающее количество байтов на самом деле прочитано.

т.е. read() должен никогда читать больше байтов из дескриптора файла, чем запрошено.

Из связанной части на клеммах:

Однако читать не обязательно целая строка сразу; любое количество байты, даже один, могут быть запрошены в читать () без потери информации.

...

Процесс last для закрытия файла оконечного устройства должен привести к тому, что любой вывод будет отправлен на устройство, а любой ввод будет отброшен.

Примечание: обычно ваша оболочка все еще будет иметь дескриптор открытого файла для терминала, пока вы не закончите сеанс.

0 голосов
/ 01 июля 2011

Это не имеет никакого отношения к какому-либо стандарту, это зависит от времени выполнения, что писать в stdin.Ваша среда выполнения делает стандартный ввод доступным для вашей программы, которая читает некоторые байты из нее и завершает работу, а затем оставшиеся байты обрабатываются самой средой выполнения - если вы можете настроить его для очистки всех файловых дескрипторов после разветвления процесса, выможет предотвратить такое поведение, но это может серьезно помешать большинству стандартных рабочих процессов командной строки, которые полагаются на присоединение ввода одного процесса к выводу другого процесса ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...