Thread: Problem with execl() and redirection.

  1. #1
    Registered User
    Join Date
    Apr 2006
    Posts
    36

    Problem with execl() and redirection.

    Hi,

    I am trying to execute the program "upper" (code in upper.c) from "useupper" (code in useupper.c) with input redirection for "upper".
    Both the codes compile fine. But when I am running "useupper", the program waits for input and does not convert and show in uppercase the contents of "new.txt" (in which I have put some lowercase text).

    linux:~/prog # gcc -o useupper useupper.c
    linux:~/prog # gcc -o upper upper.c
    linux:~/prog #./useupper new.txt
    ... waits for some input here ...

    Code:
    // useupper.c
    
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    
    int main(int argc, char* argv[])
    {
         if(argc != 2){
              fprintf(stderr,"usage: useupper file\n");
              exit(1);
         }
         execl("./upper", "upper", "<", argv[1], 0);
         perror("could not exec ./upper");
         exit(3);
    }
    Code:
    // upper.c
    
    #include <stdio.h>
    #include <ctype.h>
    #include <stdlib.h>
    
    
    int main()
    {
         int ch;
         while((ch = getchar()) != EOF)
              putchar(toupper(ch));
         exit(0);
    }
    "upper" itself works fine.

    linux:~/prog # ./upper<new.txt
    THIS TEXT WAS IN LOWERCASE IN FILE.
    linux:~/prog #


    Why is the text in "new.txt" not converted to uppercase when "upper" is run with execl() and redirection by "useupper"?

    Thanks and regards,

    Arun

  2. #2
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    What happens if you do?
    Code:
         execl("./upper", "upper", "<new.txt", 0);

  3. #3
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Using < for redirection is a shell feature; execl() knows nothing about it. You'll need to do the dirty work by hand. Look at fork() and pipe() and dup2() (and, if you're not familiar with them, open() and read() and write()).

    If you don't want to do all that, you can just use system(), which will spawn a shell and so your < character will do what you expect. You'll just have to build up the string using snprintf().

    In addition, you should use (char *)0 (or (char *)NULL) to terminate the list you pass to execl(), not just a plain zero.

  4. #4
    Registered User
    Join Date
    Apr 2006
    Posts
    36
    Hi,

    Thanks for the responses and clarifying.

    Regards,

    Arun

  5. #5
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >Using < for redirection is a shell feature; execl() knows nothing about it.
    Just curious ... would this work?
    Code:
         execl("sh <new.txt", "./upper", "upper", (char *) 0);

  6. #6
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Quote Originally Posted by swoopy View Post
    >Using < for redirection is a shell feature; execl() knows nothing about it.
    Just curious ... would this work?
    Code:
         execl("sh <new.txt", "./upper", "upper", (char *) 0);
    No; that would look for a program called "sh <new.txt". You could do:
    Code:
    execl("/bin/sh", "sh", "-c", "./upper < new.txt", (char *)NULL);
    This is like using system() except, of course, execl() won't return on success.

  7. #7
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Ah ok, thanks.

Popular pages Recent additions subscribe to a feed