Я пишу программу, похожую на оболочку Linux, на C.
Среди прочего, я реализую две встроенные команды: jobs, history.
В jobs
я печатаю список работающих в данный момент команд (в фоновом режиме). В history
я печатаю список всей истории команд до сих пор, указывая для каждой команды, ВЫПОЛНЯЕТСЯ она или ВЫПОЛНЕНА.
Чтобы реализовать их, моя идея состояла в том, чтобы иметь список команд, сопоставляя имя команды с их PID. Как только вызывается команда jobs/history, я просматриваю их, проверяю, какие из них выполняются или выполняются, и соответствующим образом печатаю.
Я читал в Интернете, что функция: waitpid(pid, &status, WNOHANG)
может определить по PID, выполняется ли процесс или завершен, без остановки процесса. Работает хорошо, кроме вот этого:
Когда программа жива, функция возвращает ее. Когда программа завершена, первый раз, когда я вызываю ее, возвращается значение done, а затем при повторном вызове с тем же PID она возвращает -1 (ОШИБКА).
Например, это будет выглядеть так: (команда & символизирует фон)
$ sleep 3 &
$ jobs
sleep ALIVE
$ jobs (withing the 3 seconds)
sleep ALIVE
$ jobs (after 3 seconds)
sleep DONE
$ jobs
sleep ERROR
$ jobs
sleep ERROR
....
Кроме того, на них не влияют другие вызовы команд, которые я мог бы выполнить до или после, кажется, что описанное выше поведение не зависит от других команд.
Я прочитал в Интернете различные причины, по которым waitpid
может возвращать -1, но я не смог определить причину в моем случае. Так же пытался искать как понять что это за ошибка waitpid
, но опять безуспешно.
Мои вопросы:
- Как вы думаете, почему такое поведение происходит
- Если у вас есть решение (в идеале, чтобы оно продолжало возвращать DONE)
- Если у вас есть лучшее представление о том, как реализовать команду jobs/history,
Одним из решений этой проблемы является то, что как только я получаю DONE, я подписываю команду как DONE и больше не выполняю waitid
перед ее печатью. Это решило бы проблему, но я бы остался в неведении относительно того, ПОЧЕМУ это происходит.