Функция имеет еще одну специфическую форму вызова, когда в качестве command
NULL. По коду возврата это позволяет выяснить, присутствует ли (и доступен ли) командный интерпретатор в системе (возвращается 0, если интерпретатор доступен).На время выполнения вызова system()
system() может анализироваться макросом WEXITSTATUS(), определенным в файле . Например:#include
int main(void) {
int rc = system("ls");
if (rc == -1) cout << "shell could not be run" << endl;
else
cout << "result of running command is " << WEXITSTATUS(rc) << endl;
return EXIT_SUCCESS;
}
Эта функция использует вызов spawnlp()
spawnlp() всегда использует вызов /bin/sh, независимо от конкретного вида интерпретатора, устанавливаемого переменной окружения SHELL (ksh, bash…). Это обеспечивает независимость поведения родительского приложения от конкретных установок системы, в которой это приложение выполняется.Вызов system()
• Используя копию командного интерпретатора, вызов system()
• Остановка родительского процесса в ожидании завершения порожденного также легко разрешается: просто запускайте дочерний процесс из отдельного потока[11]
:#include
void* process(void* command) {
system((char*)command);
delete command;
return NULL;
}
int main(int argc, char *argv[]) {
...
char* comstr = "ls -l";
pthread_create(NULL, NULL, strdup(comstr), &process);
...
}
• Часто в качестве недостатка этого способа отмечают «автономность» и невозможность взаимодействия родительского и порожденного процессов.
Но для расширения возможностей взаимосвязи процессов можно прежде всего воспользоваться вызовом popen()
system(). Возможности popen() часто упускаются из виду, так как в описаниях этот вызов относится не к области создания процессов, а к области программных каналов (pipe). Синтаксис этого вызова таков:FILE* popen(const char* command, const char* mode);
где command
system(); mode — режим создаваемого программного канала со стороны порождающего процесса: ввод (mode = «r») или вывод (mode = «w»). Любые другие значения, указанные для mode, дают непредсказуемый результат.