suaveant has asked for the wisdom of the Perl Monks concerning the following question:

I know that qmail does something like this with their password stuff for pop3...

How (assuming it can be done) would one going about opening a filehandle read-write in C, and then passing it along to an exec'd or system'd perl script? I believe qmail puts its authentication info on file descriptor 3, and then calls a sub process to handle the authentication. How would I do that? Can it be done? I assume qmail uses pipes, not actual files, but is there really a difference?

                - Ant

Replies are listed 'Best First'.
Re: Passing a filehandle from C to perl
by VSarkiss (Monsignor) on Jul 31, 2001 at 22:47 UTC

    It can be done, but I've found tricks like this to be error-prone and non-portable in the past. You're much better off passing the file name instead, and let each program open its own descriptor. That said, here's what you can do, presuming you're on something unix-like.

    Your C program has to use a file descriptor not used by the shell; let's say you use lucky seven:

    int fd = open("/some/file", O_RDWR); dup2(fd, 7); close(fd);
    Of course, you need to test that all the calls succeed.

    With that, you can take advantage of the fact that fork will take along open file descriptors:

    int pid = fork(); if (pid == 0) { execl("/the/perl/program", "program", "arg1", "etc"); _exit("URK!"); } close(7);
    Again with tests inserted appropriate places.

    In the Perl program, you take advantage of funny syntax in open being equivalent to a C fdopen, as documented in perlfunc:

    open FH, '+<=7'; my $line = <FH>; # or whatever
    This presumes the C program and the Perl program agree on file descriptor 7 being the "magic" one.

    Note, I haven't tested this code; takes way too long to set up a reasonable test....

Re: Passing a filehandle from C to perl
by tachyon (Chancellor) on Jul 31, 2001 at 22:08 UTC

    This is a complex question. Perl is written in C so does this for you all the time to allow you to use files. Have a look at perlman:perlxs and perlman:perlguts for a free overview of all the nitty gritty. There is a new Manning book on Perl and C in the works but this will be a few months probably. If you search this site for 'XS' you will find some interesting threads that may be helpful.

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      Yes, but I just want to pass the filehandle on to basically a child process... either by a system("/usr/bin/perl test.pl"); or with exec in C, and be able to grab onto that filehandle and read from it. I mean, in the end this doesn't have to have anything to do with C and Perl, it could be Scheme and Python or whatnot (although I have no idea in the slightest what to do there).

      Basically what I want to do is have a C prog that sets it uid to the owner, opens a protected file, set itself back to its original UID and then runs a perl script, but allow that perl script access to the protected filehandle... am I crazy, or is this possible?

                      - Ant

        I don't know if you are crazy :-) and I am sure it is possible but I don't understand the logic for it, why not just do it all from Perl?

        cheers

        tachyon

        s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: Passing a filehandle from C to perl
by John M. Dlugosz (Monsignor) on Jul 31, 2001 at 22:46 UTC
    You know what you want is in file descriptor 3, you say? See perlfunc:open, If you specify '<&=N', where N is a number, then Perl will do an equivalent of C's fdopen() of that file descriptor;