0

I want to redirect a content of input.txt file to stdin.

I tried:

int RunCompiledFile(char *path, char * input, char *thirdLine, char* name){

    int fdFile = open(input, O_RDONLY), exitStatus, check,
    fdFileOutput = open("newOutput.txt", O_RDWR|O_CREAT, 0777), status;
    char* args[] = {"comp.out", "newOutput.txt", thirdLine};
    char buffer[100];
    pid_t  pid;


    dup2(0, fdFile);
    dup2(fdFileOutput , 1);
    getcwd(buffer, 95);
    i = strlen(buffer);
    buffer[i] = '/';
    buffer[++i] = '\0';
    check = execv(buffer,"a.out");
    close(fdFileOutput);

    //if ((pid = fork()) == 0){
        check = execvp("comp.out", args);
      //  return 5;}

    wait(&status);
    exitStatus = WEXITSTATUS(status);

    switch (exitStatus){
        case 1:
            result("0", name, BADOUTPUT);
            unlink("newOutput.txt");
            return 1;
        case 2:
            if (depth){
                char buffer[5];
                sprintf(buffer, "%d", 100 - (10 * depth));
                result(buffer, name, WRONGDIRECTORY);}
            else
                result("100", name, GREATJOB);
                unlink("newOutput.txt");
            return 1;
        case 3:
            result("80", name, SIMILLAROUTPUT);
            unlink("newOutput.txt");
            return 1;
    }

    return fdFileOutput;
}

But becuase of all the forks it's hard to debbug. the execv - after the "getcwd" returns -1. a.out is a program the gets input via scanf(), and then does something and printf the answer.

I am supposed to get a file, turn it to stdin for the fgets of a.out, and then open a new file for the output of a.out.

it's still doesn't work, I tried your fixes:

    dup2(fdFile, STDIN_FILENO);
    dup2(fdFileOutput, STDOUT_FILENO);
    getcwd(buffer, 95);
    i = strlen(buffer);
    buffer[i] = '/';
    buffer[++i] = 'a';
    buffer[++i] = '.';
    buffer[++i] = 'o';
    buffer[++i] = 'u';
    buffer[++i] = 't';
    buffer[++i] = '\0';
    close(fdFileOutput);
    close(fdFile);
    check = execv(buffer,"a.out");

but the return from execv is still -1. the a.out is working on different users (my friends tried it before).

Shay Chercavsky
  • 47
  • 2
  • 12
  • Can you please post a [Minimal, Complete and Verifiable Example](http://stackoverflow.com/help/mcve). – Box Box Box Box Apr 09 '16 at 05:55
  • Please show your complete code and explain what problems you are having with that code. – kaylum Apr 09 '16 at 05:55
  • I think it goes the other way around: `dup2( fd_input, STDIN_FILENO );` – user3386109 Apr 09 '16 at 06:00
  • First try to redirect a file without forks. Easier to debug, easier for ithers to help. – Walter A Apr 09 '16 at 06:31
  • That is what I do now, and how I got the return of the exec. – Shay Chercavsky Apr 09 '16 at 06:32
  • What does `thirdLine` point to? – kaylum Apr 09 '16 at 06:38
  • `exec` doesn't return if it succeeds, so if `exec` returned you have a bug in your program. In this case, the bug is that you passed the current-working-directory as the first argument to `execv`. The first argument to `execv` should be the full pathname of the executable file. – user3386109 Apr 09 '16 at 06:39
  • Your formatting stinks. You may want to adopt a better formatting style, perhaps resort those provided by IDEs. – Sнаđошƒаӽ Apr 09 '16 at 06:46
  • Are you sure that a.out is an executable program. Have you tried its function independently and set the permissions ? – ralf htp Apr 09 '16 at 06:55
  • it has to be `int check = execv("a.out",buffer);` according to this https://support.sas.com/documentation/onlinedoc/sasc/doc/lr2/execv.htm `int execv(const char *file, char *const argv[]);` and *a.out* has to be located in the same directory as the calling program. – ralf htp Apr 09 '16 at 07:00
  • buffer has the path to the file. – Shay Chercavsky Apr 09 '16 at 11:09

1 Answers1

0

From In C how do you redirect stdin/stdout/stderr to files when making an execvp() or similar call?:

The right way to do it is to replace the file descriptors STDIN_FILENO, STDOUT_FILENO and STDERR_FILENO with the opened files using dup2(). You should also then close the original files in the child process:

else if (pid == 0)
{
    dup2(fileno(someopenfile), STDIN_FILENO);
    dup2(fileno(someotherfile), STDOUT_FILENO);
    dup2(fileno(somethirdopenfile), STDERR_FILENO);
    fclose(someopenfile);
    fclose(someotheropenfile);
    fclose(somethirdopenfile);
    execvp(args[0], args);
    // handle error ...
}

So open input and output files, create the childprocess (fork()) and then dup2() and rest of the code above

Beside this you can use freopen() (Rerouting stdin and stdout from C)

freopen("newin", "r", stdin); (without assignment to file handle [!])

These links are also interesting because they give information about the system functions like fork(), dup2(),...

How to execute a shell script from C in Linux?

Bash: read stdin from file and write stdout to file

Community
  • 1
  • 1
ralf htp
  • 9,149
  • 4
  • 22
  • 34
  • I can't use freopen(). I tried your fix - look up. and it's still returns -1. – Shay Chercavsky Apr 09 '16 at 11:09
  • It has to be **`int check = execv("a.out",buffer);`** not **`check = execv(buffer,"a.out");`** (https://support.sas.com/documentation/onlinedoc/sasc/doc/lr2/execv.htm) `int execv(const char *file, char *const argv[]);` and *a.out* has to be located in the same directory as the calling program or give the full path on your computer in the `execv()` command (at least now for testing), read this https://support.sas.com/documentation/onlinedoc/sasc/doc/lr2/execv.htm – ralf htp Apr 09 '16 at 11:24
  • Use a debugger (gdb) – ralf htp Apr 09 '16 at 11:27
  • I place the int check before (on the top). I am using a debugger, that is how I know what returns from execvp – Shay Chercavsky Apr 09 '16 at 11:40
  • No, i mean that you have to change the ordering of the arguments in the *execv* function **`int check = execv("a.out",buffer);`** not **`int check = execv(buffer,"a.out");`**. And give the full path (from root) to *a.out* on your computer in the execv-command. Have you ever tried to compile this try -v and -Wall options in the compiler and see the errors... – ralf htp Apr 09 '16 at 11:44
  • For debugging after a `fork()` see this https://sourceware.org/gdb/onlinedocs/gdb/Forks.html or seach engine with 'execv gdb' or 'fork gdb' – ralf htp Apr 09 '16 at 11:47
  • I am debugging with Code::blocks. I tried execv("a.out", buffer). Still -1. – Shay Chercavsky Apr 09 '16 at 12:06
  • see this on how to use execv() http://stackoverflow.com/questions/12575826/using-execv-c-language-to-run-commands-from-a-linux-command-prompt – ralf htp Apr 09 '16 at 12:50