0

I have looked all over the internet and die.net and can't see to make my code work. My problem is that I am able to redirect the output to a file, but have trouble bringing it back to standard out, I have tried using dup, dup2 and close, but maybe I am using them wrong. Any help would be appreciated, thank you

. My problem begins at the if(myargc >= 3) block when I am trying to redirect the output.

main()
{
    int i, myargc =0, background, newfile, file, stdout2, read  = 0, write = 0;
    pid_t pid;
    char input[512], *myargv[60];


while(1)
{
    background = 1;
    printf("Myshell>");
    gets(input);
    //scanf("%s", input);
    myargc = parser(input, myargv);

    if(strcmp(*myargv, "exit") == 0)
    {
        exit(0);
    }

    if(strcmp(myargv[myargc-1], "&") == 0)
    {
        background = 0;
        myargv[myargc-1] = '\0';
        myargc--;
    }

    if(myargc >= 3)
    {
        if(strcmp(myargv[myargc-2], ">") == 0)
        {
            write = 1;
            file = creat(myargv[myargc-1], S_IWUSR);
            myargv[myargc-2] = '\0';

            if(file < 0)
            {
                printf("File could not be created.\n");
            }
            printf("Redirecting output to file %s.\n", myargv[myargc-1]);
            fflush(stdout);
            stdout2 = dup(STDOUT_FILENO);
            //fclose(stdout);  // fclose() for type FILE*
            newfile = dup2(file, 1);  // uses lowest number descriptor (1, since just                         
                                      // closed stdout)
            close(file); // closes old file descriptor duplicate, close() uses int
            myargc = myargc-2;
        }
    }
    if ((pid = fork()) == -1 )
    {
        // if fork fails, print error and exit
        perror("Fork failed");
        exit(-1);
    }
    else if (pid == 0) { // child process

        if (read == 0 && write == 0)
        {
            printf("This is the child ready to execute: ");
            fflush(stdout);
            for (i =0; i < myargc; i++)
            {
                printf("%s ", myargv[i]);
                fflush(stdout);
            }
            printf("\n");
        }
        if (execvp(*myargv,myargv) < 0);
        {
            printf("Execution failed.");
        }/* error exit - exec returned */
        close(newfile);
        dup2(stdout2, STDIN_FILENO);

        //close(file);
        //if (close(file) == 0)
       //{
            //dup2(newfile, STDOUT_FILENO);
            //close(newfile);
            //close(stdout2);
        //    printf("Reopened stdout\n");
       // }
        perror("Exec returned");
        exit(-1);
    }
    close(newfile);
    if (background == 1) { /* this is the parent -- wait for child to terminate */
        wait(pid,0,0);
        printf("The parent is exiting now\n");
    }else{
        waitpid(pid, NULL, WNOHANG); //returns immediately, no wait
    }

    //test for correct parsing
    printf("myargv:\n");
    for (i = 0; i < myargc; i++)
    {
        printf("%s\n", myargv[i]);
    }
    printf("myargc: %d\n", myargc);



    // clear out buffers
    memset(&myargv[0], 0, sizeof(myargv));
    memset(&input[0], 0, sizeof(input));
    }

 }
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Standard output is for output, not input. You can't redirect input to output. – Barmar Oct 13 '13 at 21:29
  • alright i fixed the typo, i accidentally wrote input not output in the description – Kailee Kerr Oct 13 '13 at 21:34
  • One option is not to redirect standard output until you're in a forked subshell, so the original shell's standard output is not touched. The other main option is to `dup()` (plain old `dup()`, not `dup2()`) the current (original) standard output to some file descriptor, then redirect standard output to a file; in the child, remember to close the duplicate of the original standard output; in the parent, use `dup2()` to reinstate the original standard output. Make sure you don't leak file descriptors doing this. Pipes must be created before the `fork()`, but file redirection can be done after. – Jonathan Leffler Oct 13 '13 at 21:38
  • thank you! i revised my code and now it will allow me to type commands after and it's actually printing output to the console again! but I'm still having trouble getting Myshell> prompt to be printed again – Kailee Kerr Oct 13 '13 at 21:56
  • Why don't you show your revised code? – Armali Sep 23 '14 at 12:04

0 Answers0