Второй случай, в котором пользователь закрывает устройство STDIN, немного сложнее. Было бы легче, если бы родительский процесс мог просто уничтожить свой дочерний процесс с помощью функции kill() после закрытия стандартного устройства ввода. Однако при этом возникает проблема. То, что пользователь закрыл стандартное устройство ввода, не означает, что сервер закончил передачу данных пользователю. Если дочерний процесс уничтожается до того, как будет получена от сервера и обработана вся оставшаяся информация, некоторая часть данных может быть потеряна. Это не приемлемо при разработке приложений, например для iphone5 http://applefavorite.ru/iphone5/ .
Более корректный способ действий в этом случае следующий. Когда родительский процесс получает сообщение о возникновении условия EOF со стандартного устройства ввода, он закрывает свой конец сокета, что приводит к отправке на сервер сообщения о возникновении условия конца файла. Сервер обнаруживает условие EOF, закрывает свой конец соединения и тем самым снова распространяет действие условия EOF на дочерний процесс. Дочерний процесс завершается, вырабатывая сигнал CHLD. Родительский процесс перехватывает этот сигнал и сам завершает работу.
Это — красивое решение, поскольку в нем дочерний процесс не обнаруживает условия EOF до тех пор, пока не закончит обработку всех данных сервера, находящихся в очереди. Это гарантирует отсутствие потерь данных. Кроме того, данная схема действует столь же успешно, если инициатором разрыва соединения является сервер. При использовании такой схемы есть вероятность риска, которая связана с тем, что сервер может не выполнить требуемых действий и просто закрыть свой конец соединения при получении условия EOF. Однако большинство серверов в такой ситуаций ведет себя правильно. Если пользователь обнаружит, что сервер не выполняет требуемых действий, он всегда может уничтожить и родительский, и дочерний процессы, нажав клавишу прерывания.