C 无趣加上一点性能损失,但适用于对话框的所有组件,如清单和菜单等
您可以控制将存储在脚本文件中的脚本的所有细节,并且总体操作和流控制非常简单。我使用了第一个选项,它工作得非常出色。非常感谢。请使用C 无趣加上一点性能损失,但适用于对话框的所有组件,如清单和菜单等,c,linux,C,Linux,您可以控制将存储在脚本文件中的脚本的所有细节,并且总体操作和流控制非常简单。我使用了第一个选项,它工作得非常出色。非常感谢。请使用fgets(inbuf,sizeof(inbuf),dialog)而不是sizeof(inbuf)-1。请阅读手册以了解更多信息fgets@user102008-即使我知道它可能是sizeof(inbuf)我仍然会使用sizeof(inbuf)-1来防止fgets中的实现错误。这是一个相当简单的解决方案。一种可能的增强方法是unlink()从文件系统中取消fd的链接,
fgets(inbuf,sizeof(inbuf),dialog)
而不是sizeof(inbuf)-1
。请阅读手册以了解更多信息fgets@user102008-即使我知道它可能是sizeof(inbuf)
我仍然会使用sizeof(inbuf)-1
来防止fgets
中的实现错误。这是一个相当简单的解决方案。一种可能的增强方法是unlink()
从文件系统中取消fd的链接,以便只有子级和父级可以访问它,并使用`mkstemp()将使用的文件名随机化
pid_t pid;
char cmd[] = "dialog";
char *args[] = {"dialog", "--menu", NULL};
int status;
int fd;
if((pid = fork()) == 0)
{
/* child */
/* I believe dialog prints to stderr the answer chosen
* also you should check the return value of open()
*/
fd = open("some_file_name", O_WRONLY | O_CREAT | O_TRUNC, 0);
close(STDERR_FILENO);
dup(fd);
execvp(cmd, args);
perror("execvp()");
exit(1);
}
else if(pid < 0)
{
perror("fork()");
exit(1);
}
else
{
/* parent */
/* you should also check the return of waitpid()
* this is just for example
*/
waitpid(pid, &status, 0);
/* if everything was ok then status has the return value
* also the file "some_file_name" should have the output
*/
}
FILE *dialog = popen("(dialog --menu plus other arguments >/dev/tty) 2>&1");
#include <stdio.h>
#include <stddef.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
int main(int argc, const char *argv[])
{
const char *dia_args[] = {
"dialog",
"--output-fd",
NULL,
"--menu",
"Hi there",
"60", "15", "15",
"t1", "i1",
"t2", "i2",
"t3", "i3",
"t4", "i4",
"t5", "i5",
NULL
};
int pipefds[2];
if (pipe(pipefds) < 0) {
perror("pipe failed");
return 1;
} else {
const pid_t child = fork();
if (child < 0) {
perror("fork failed");
return 1;
} else if (child == 0) {
char pipefdstr[60];
close(pipefds[0]);
if (snprintf(pipefdstr, sizeof(pipefdstr) - 1, "%u", pipefds[1]) < 0) {
perror("snprintf failed");
return 1;
} else {
pipefdstr[sizeof(pipefdstr) - 1] = '\0'; /* Protect against bugs in snprintf */
dia_args[2] = pipefdstr;
execvp(dia_args[0], dia_args);
perror("Unable to exec dialog command");
return 1;
}
} else { /* child > 0 */
FILE *dialog = fdopen(pipefds[0], "r");
char inbuf[200];
int waitresult = 0;
if (dialog == NULL) {
perror("Unable to fdopen");
kill(child, SIGKILL);
return 1;
}
close(pipefds[1]);
while (fgets(inbuf, sizeof(inbuf) - 1, dialog)) {
inbuf[sizeof(inbuf) - 1] = '\0';
printf("Got [%s] from dialog.\n", inbuf);
}
fclose(dialog);
if (waitpid(child, &waitresult, 0) < 0) {
perror("waitpid failed");
return 1;
}
if (!WIFEXITED(waitresult) || (WEXITSTATUS(waitresult) != 0)) {
fprintf(stderr, "dialog exited abnormally.");
return 1;
}
}
}
return 0;
}
fp = fopen(SCRIPT_FILE, "w+");
fprintf(fp,
"#!/bin/sh\\n\\n"
"dialog --clear --title \""BRAND_INFO"\""
" --inputbox \""TITLE"\\n\\n"
"Please input the name[/tmp/input]:\" "
BOX_HEIGHT" "BOX_WIDTH" 2> "RESULT_FILE"\n");
fclose(fp);
system("bash "SCRIPT_FILE);
fp = fopen(RESULT_FILE, "rt");
// here read the results from the RESULT_FILE
// into which dialog had written the results.
...