У нас есть многопоточное встроенное приложение, которое из-за аппаратных ограничений, слишком обыденных для обсуждения здесь, должно перемонтировать свою файловую систему на RW, когда она выводит в файл.
В настоящее время мы делаем это через system()
позвонить, и запустить mount
команда. Однако время от времени этот вызов блокируется, и приложение попадает в тупик.
Во время отладки я поместил system(NULL)
до оригинала system()
звоните, и это, кажется, иногда блокирует также.
Вообще говоря, при каких обстоятельствах system()
блок на всю вечность?
Это Linux? В glibc под Linux system () блокирует SIGCHLD, изменяет пару обработчиков сигналов, разветвляется, ждет, когда ребенок умрет, а затем исправляет то, что он сделал с маской сигналов. В дочернем процессе, он отменяет изменения маски сигнала и исполняет оболочку для запуска вашей команды.
Это даже происходит, когда вы звоните system(NULL)
— единственная разница в том, что вызываемая оболочка называется как sh -c exit 0.
В общем, вы порождаете процесс, загружаете оболочку (и все связанные с ней библиотеки) и ждете, когда оболочка умрет. Вы, вероятно, укушены при загрузке оболочки.
system()
блокирует до тех пор, пока вызываемая команда не завершится, поэтому, если mount
команда никогда не заканчивается system()
никогда не вернется.
Я предполагаю, что если вы запускаете mount, то вам нужны права root, так что, возможно, это ваш случай (выдержка из man system
в Linux):
Do not use system() from a program with set-user-ID or set-group-ID privileges, because strange values for some environment
variables might be used to subvert system integrity. Use the exec(3) family of functions instead, but not execlp(3) or
execvp(3). system() will not, in fact, work properly from programs with set-user-ID or set-group-ID privileges on systems on
which /bin/sh is bash version 2, since bash 2 drops privileges on startup. (Debian uses a modified bash which does not do
this when invoked as sh.)