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.
...