UNIX pipes and dead children question.

bleyman

Есть такая прожраммка, gqlplus, которая запускает оракловскую sqlplus и передаёт ей юзерский инпут, добавляя по пути историю команд. Прожраммка не поддерживается лет пять уже кажется, так что сама по себе мне не очень важна, однако она совершенно удивительно глючит, так, как по моим представлениям глючить не может ничто!
Суть токова: я её запускаю, жму ctrl-c (который она перехватывает и вызвает kill(sqlplus, SIGINT та срочно превращается в зомби жму например enter, возвращается read с консоли, она чего-то пишет в пайп (наверняка неудачно, но она не проверяет после чего вызывает read на своём конце и там висит! Как так может быть! После того, как sqlplus сдохла, все её дескрипторы должны автоматически закрыться, и тогда все наши операции должны возвращать либо -1, либо 0! Как ему удалось это сломать!
(на самом деле у него там баг, он не проверяет возвращаемое значение на 0, но я его поправил а так же обложил всё отладочной печатью — нет, он висит в read. Алсо, я посмотрел, вроде свою часть чужой стороны пайпа он закрывает сразу после форка. Правда, не закрывает в дите, но это же должно быть неважно?)

zorin29

а сам sqlplus не форкается еще раз? может, по SIGKILL он не убивает какого-то своего ребеночка, и тот держит открытый дескриптор пайпа?
Это я с суконным рылом лезу в калашный ряд, конечно: мои познания тут в объеме 2-го курса вмк :)

vall

если это linux то посмотри в ls -l /proc/*/fd оба конца пайпа там имеют одинаковый инодный номер в квадратных скобках, может он правда куда-то утёк.
lsof тоже должен его показывать.

bleyman

Ок, завтра посмотрю, спасибо, не знал про lsof.
Кстати, какой смысл в том, что lsof ставится в какую-то жопу типа /usr/sbin, и следует ли мне добавить её в path?

okis

Это вопрос организации твоего дистра, у меня он в path.

Papazyan

после чего вызывает read на своём конце и там висит! Как так может быть! После того, как sqlplus сдохла, все её дескрипторы должны автоматически закрыться, и тогда все наши операции должны возвращать либо -1, либо 0! Как ему удалось это сломать!
Не в курсе как конкретно реализовано это в линуксе, но чисто логически файл открыт в обоих процессах и то, что его закрыли в одном из них, погоды не делает - второй дескриптор все равно валидный.

bleyman

Это же не файл, а пайп! Когда его с той стороны закрывают, как минимум EOF должно прийти.

bleyman

О, посмотрел, обнаружил, что утекает, почитал ещё раз код внимательно и обнаружил, что он действительно лишний дескриптор у пайпа для записи закрыл, а у пайпа для чтения — забыл.
Так что никакой удивительной мистики :(
Оставить комментарий
Имя или ник:
Комментарий: