Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从文件中重定向了stdin的execve()_C_Linux_Stdin - Fatal编程技术网

从文件中重定向了stdin的execve()

从文件中重定向了stdin的execve(),c,linux,stdin,C,Linux,Stdin,要将stdin重定向到execve()中的文件。所以程序应该像这样执行,我的意思是这就是我在shell中执行它的方式,它是这样工作的: /opt/prog < in.txt /opt/prog

要将stdin重定向到execve()中的文件。所以程序应该像这样执行,我的意思是这就是我在shell中执行它的方式,它是这样工作的:

/opt/prog < in.txt
/opt/prog
下面是我写的代码,但它似乎不起作用。in.txt是二进制文件,我想在执行的程序中将它重定向到stdin

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main(void)
{
    int fd[2];
    pid_t pid;


    FILE *f = fopen("in.txt", "rb");

    if (pipe(fd) < 0)
        return EXIT_FAILURE;

    if ((pid = fork()) < 0)
        return EXIT_FAILURE;
    else if (pid != 0) { /* father */
        close(fd[1]);
        dup2(fd[0], STDIN_FILENO);
        execlp("/opt/prog", "prog", (char *)0);
        printf("done\n");
    } else { /* son */

        fseek(f, 0, SEEK_END);
        long fsize = ftell(f);
        fseek(f, 0, SEEK_SET);

        char *string = malloc(fsize + 1);
        fread(string, fsize, 1, f);
        fclose(f);
        close(fd[0]);
        write(fd[1], string, 11);
    }

    return EXIT_SUCCESS;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
内部主(空)
{
int-fd[2];
pid_t pid;
文件*f=fopen(“in.txt”、“rb”);
如果(管道(fd)<0)
返回退出失败;
如果((pid=fork())<0)
返回退出失败;
如果(pid!=0){/*父*/
关闭(fd[1]);
dup2(fd[0],标准文件号);
execlp(“/opt/prog”,“prog”,“char*)0);
printf(“完成”\n);
}else{/*子*/
fseek(f,0,SEEK_END);
长fsize=ftell(f);
fseek(f,0,SEEK_集);
char*string=malloc(fsize+1);
fread(string,fsize,1,f);
fclose(f);
关闭(fd[0]);
写入(fd[1],字符串,11);
}
返回退出成功;
}
更新1:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main(void)
{
    int fd[2];
    pid_t pid;

    FILE *f = fopen("in.txt", "rb");

    if (pipe(fd) < 0)
        return EXIT_FAILURE;

    if ((pid = fork()) < 0)
        return EXIT_FAILURE;
    else if (pid != 0) { /* father */
        fseek(f, 0, SEEK_END);
        long fsize = ftell(f);
        fseek(f, 0, SEEK_SET);

        char *string = malloc(fsize + 1);
        fread(string, fsize, 1, f);
        fclose(f);
        close(fd[0]);
        write(fd[1], string, 11);

    } else { /* son */
        close(fd[1]);
        dup2(fd[0], STDIN_FILENO);
        execlp("/opt/prog", "prog", (char *)0);
        printf("done\n");

    }

    return EXIT_SUCCESS;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
内部主(空)
{
int-fd[2];
pid_t pid;
文件*f=fopen(“in.txt”、“rb”);
如果(管道(fd)<0)
返回退出失败;
如果((pid=fork())<0)
返回退出失败;
如果(pid!=0){/*父*/
fseek(f,0,SEEK_END);
长fsize=ftell(f);
fseek(f,0,SEEK_集);
char*string=malloc(fsize+1);
fread(string,fsize,1,f);
fclose(f);
关闭(fd[0]);
写入(fd[1],字符串,11);
}else{/*子*/
关闭(fd[1]);
dup2(fd[0],标准文件号);
execlp(“/opt/prog”,“prog”,“char*)0);
printf(“完成”\n);
}
返回退出成功;
}

如果您只想让进程从文件中读取,则不需要
管道
:只要
dup2
文件描述符在
STDIN\u FILENO
上即可。此外,您还希望在父项中执行
execlp
,因为否则当您的孩子退出时,
prog
会得到意外的
SIGCHLD

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>

int main(void)
{
    pid_t pid;
    int fd;

    fd = open("in.txt", O_RDONLY);
    if (fd < 0) {
        perror("open");
        return EXIT_FAILURE;
    }

    if ((pid = fork()) < 0) {
        perror("fork");
        return EXIT_FAILURE;
    } else if (! pid) { /* child */
        dup2(fd, STDIN_FILENO);
        close(fd);
        execlp("/opt/prog", "prog", (char *)0);
        perror("exec");
        return EXIT_FAILURE;
    } else { /* parent */
        close(fd);
        printf("Parent waiting\n");
        getchar();
    }

    return EXIT_SUCCESS;
}
#包括
#包括
#包括
#包括
#包括
#包括
内部主(空)
{
pid_t pid;
int-fd;
fd=打开(“in.txt”,仅限ordu);
如果(fd<0){
佩罗(“公开”);
返回退出失败;
}
如果((pid=fork())<0){
佩罗尔(“福克”);
返回退出失败;
}如果(!pid){/*child*/
dup2(fd,标准文件号);
关闭(fd);
execlp(“/opt/prog”,“prog”,“char*)0);
perror(“执行董事”);
返回退出失败;
}else{/*父项*/
关闭(fd);
printf(“正在等待的家长”);
getchar();
}
返回退出成功;
}

我喜欢上面的解决方案,但如果您只想执行execve,并在完成后退出。您必须在父进程中使用wait,直到子进程退出

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

    int main(int argc, char **argv) {
      int fd, status;
      pid_t child_pid;
      char c;
      char *args[2] = {"/opt/prog", NULL};

      if (argc != 2)
        exit(1);
      fd = open(argv[1], O_RDONLY);
      child_pid = fork();
      if (child_pid == 0) {
        if (dup2(fd, STDIN_FILENO) == -1) {
          perror("dup2");
          return (EXIT_FAILURE);
        }
        close(fd);
        execve(args[0], args, NULL);
      }
      if (child_pid != 0) {
        close(fd);
        wait(&status);
      }
      return (EXIT_SUCCESS);
    }
#包括
#包括
#包括
#包括
int main(int argc,字符**argv){
int fd,状态;
pid_t child_pid;
字符c;
char*args[2]={“/opt/prog”,NULL};
如果(argc!=2)
出口(1);
fd=打开(argv[1],仅限Ordu);
child_pid=fork();
如果(子项pid==0){
如果(dup2(fd,标准文件号)=-1){
perror(“dup2”);
返回(退出失败);
}
关闭(fd);
execve(args[0],args,NULL);
}
如果(子pid!=0){
关闭(fd);
等待(&状态);
}
返回(退出成功);
}

您不需要管道。使用
dup2
。您正在向后分叉,您应该在子进程中执行
exec