c - 系统执行
static pid_t child_pid;
static void kill_child(int sig)
{
kill(child_pid, SIGKILL);
}
/**
* @brief 使用fork执行系统命令,返回从stdout读取到长度值
*
* @param cmd 需要执行的命令
* @param buf 读取到数据存在的buf
* @param count buf参数的最大长度
* @param wstatus 返回执行状态0才代表成功
* @return int 读取到的stdout的长度
*/
int fork_with_result(const char *cmd, void *buf, size_t count, int *wstatus)
{
int status, fds[2];
if (pipe(fds)) {
loge("Failed to spawn pipe.\n");
return -1;
}
signal(SIGALRM, (void (*)(int))kill_child);
switch ((child_pid = fork())) {
case -1:
close(fds[0]);
close(fds[1]);
loge("Failed to fork process.\n");
return -1;
case 0:
dup2(fds[1], 1);
dup2(fds[1], 2);
close(fds[0]);
close(fds[1]);
if (execl("/bin/sh", "sh", "-c", cmd, (char *)0) < 0) {
loge("Failed execl\n");
exit(-1);
}
exit(0);
default:
/* 子进程默认最多允许执行60秒钟 */
alarm(60);
/* 关闭写入端 */
close(fds[1]);
int wpid;
while ((wpid = wait(&status)) > 0)
;
int len = 0;
if (buf && count)
len = read(fds[0], buf, count);
if (wstatus) {
/*分析返回值*/
if (WIFEXITED(status)) {
*wstatus = WEXITSTATUS(status);
logd("Exited, status=%d.\n", *wstatus);
} else {
loge("Abornaml exited.\n");
*wstatus = -1;
if (WIFSIGNALED(status)) {
logd("Killed by signal %d\n", WTERMSIG(status));
} else if (WIFSTOPPED(status)) {
logd("Stopped by signal %d\n", WSTOPSIG(status));
} else if (WIFCONTINUED(status)) {
logd("Continued\n");
}
}
}
close(fds[0]);
return len;
}
return 0;
}