在管道命名程序中执行exec()函数

时间:2014-11-11 16:01:08

标签: c linux pipe exec

我的exec()函数有问题。 我的程序应该通过终端输入类似“./a.out from message”的内容并打印“from:to:message”作为执行来调用。 我不知道,如何实现exec()函数,允许我输入“./a.out from message”并打印出结果。 在程序中,我必须使用命名管道来读写“消息”。 怎么解决?

我的一段代码:

int main(int argc, char* argv[]) {

 int i = 0;
 char* fr0m[MAX], t0[MAX], message[MAX];

 execve("./a.out", "./a.out", "from.txt", fr0m, "t0.txt", t0, "message.txt", message, NULL);
 puts(strerror(errno));

 int File1 = mkfifo("opened.txt", 0666);
 int File2 = mkfifo("saved.txt", 0666);

 int Opened = open("opened.txt", O_CREAT | O_WRONLY | O_TRUNC, 0777);
 int Saved = open("saved.txt", O_CREAT | O_RDONLY | O_TRUNC, 0777);

 int File1Process = fork();

 int Scanner; 

 if( File1Process == 0 ) {

    char c;
    read( Opened, message, sizeof(message) );
    while( ( Scanner = read( Opened, &c, sizeof(message) ) ) > 0 )
            printf( "%i", message[i] );

    close( Opened );    
 }

 if( File1Process != 0 ) {
    write( Saved, message, sizeof(message) );
    close( Saved );

    printf("<");
    for(i=0; i<sizeof(fr0m); i++) printf( "%c", fr0m[i]);
    printf("> : "); 
}

[...]

1 个答案:

答案 0 :(得分:0)

这里有很多问题。在我看来,这个任务是编写一个程序,当执行时,它接受三个参数,然后用一个空格冒号空间序列将它们回到屏幕,分隔输出中的参数和一个换行符。结束。该程序将从终端窗口运行:

$ ./a.out source target 'what was said'
source : target : what was said
$

虽然您可以编写第二个程序来执行其输出显示的程序,但是没有明确的需要。

在您的代码中,您有:

int main(int argc, char* argv[]) {

 int i = 0;
 char* fr0m[MAX], t0[MAX], message[MAX];

 execve("./a.out", "./a.out", "from.txt", fr0m, "t0.txt", t0, "message.txt", message, NULL);
 puts(strerror(errno));

这个片段中有很多问题:

  • 如果execve()返回,则表示失败。
  • 您正在呼叫execve(),就好像它是execle()
  • 您正在将未初始化的指针传递给execve()
  • 您有char *的数组,而不是char的数组。
  • 最好在标准错误上报告错误消息,而不是标准输出。

如果execve()失败,程序将继续创建一对FIFO,然后尝试打开它们。很可能没有其他进程让FIFO打开,所以第一次打开将无限期阻止。无论它做了什么,其余的代码似乎与问题中所述的任务的任何合理解释完全无关。

您的代码应该非常简单。

#include <stdio.h>

int main(int argc, char **argv)
{
    if (argc == 4)
        printf("%s : %s : %s\n", argv[1], argv[2], argv[3]);
    else
        fprintf(stderr, "Usage: %s from to 'message'\n", argv[0]);
    return 0;
}

主要缺陷是它在打印使用错误消息时报告“成功”,这很容易修复。

如果您想要一个程序来执行该程序,那么:

#include <unistd.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    char *envp[] =
    {
        "HOME=/home/user",
        "PATH=/bin:/usr/bin",
        "TZ=UTC0"
        0
    };
    if (argc != 4)
    {
        fprintf(stderr, "Usage: %s from to 'message'\n", argv[0]);
        return 1;
    }
    argv[0] = "./a.out";
    printf("About to execute %s\n", argv[0]);
    execve(argv[0], argv, envp);
    fprintf(stderr, "Failed to execute %s\n", argv[0]);
    return 1;
}

不要将此代码编译为a.out;你将最终得到一个永久执行自己的程序。 printf()之前的execve()会让您知道正在发生的事情;你必须打断它才能阻止它。