"Karol Zielonko" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] > -------------------------------------------------------------------------- - > > I need to invoke a perl script (SPAMASSASSIN FWIW) from a C program with command > line parameters and input and output re-direction. Currently from my 'C' program > I call LIB$SPAWN with a PERL command such as: > > perl spamassassin. -e2160 < SAMPLE-SPAM.TXT > KZSAMPLE-SPAM-OUT.TXT > > This works but incurs LIB$SPAWN's process creation overhead in addition to > re-compilation of the perl scripts each time around (and this set of scripts > takes five to ten seconds to compile). This is more overhead than I'd like and > I'm looking to cut out as much of it as possible. Ideally it would be done > without creating a sub process and with only one loading of the perl interpreter > and one compilation of the scripts for the life of a server process. (The server > process will invoke SPAMASSASSIN many times in its life, once for each mail > message processed.) > > I have tried some of the techniques described in PERLEMBED.POD but none of them > seem to allow me to do exactly what I need to do. The perl_run() stuff sounded > promising but > > 1) I couldn't get output re-direction to work at all. No matter what I did > when I called perl_run() to invoke the SPAMASSASSIN script it sent its output > to the terminal, not the file > > - Tried redefining sys$output varying access mode and logical name table. > - Tried playing with stdout. > > 2) I could only get input re-direction to work (by calling crelnm to > DEFINE/USER SYS$INPUT to the input file) for the first input file but on > subsequent calls to perl_run() I couldn't get it to read a different file. I > also tried playing with stdin with no success. > > 3) I couldn't figure out how to pass command line options (aka. invocation > options?) to the SPAMASSASSIN script. > > I'll spare you all the details (unless anyone wants 'em of course) of all the > iterations I went through trying this and that hack to solve these problems. > > I played around with call_argv() but I'm not sure that's what I need anyway > because it requires (apparently) the name of a subroutine to call in a script > but I don't want a subroutine *in* a script I want *the* script. The main > SPAMASSASSIN script has a few use statements and some variable declarations and > a BEGIN {} block and then the main blob of code which is one huge eval{} block. > I tried modifying the spamassassin script, encasing the entire script in a > "dummy" subroutine and called that. That worked but I still don't know how to > get command line options into it. (If I understand the SPAMASSASSIN code it is > using a package called "Getopt" to parse CLI options.) Nor could I figure out > how to redirect stdin and stdout to/from files. > > Preferably the solution would not involve changes to the SPAMASSASSIN script > itself as this is open source sw and changes would have to be folded back in. I > guess that is possible but I'd also guess it would requre more work > logistically. Although if SPAMASSASSIN is to be made usable on VMS as delievered > from the open source kit then there are already a list of changes that need to > be made in the open source build anyway... > > So can anyone help me? Maybe a pointer to some working examples or a perldoc POD > that I missed?
Depending on what version of VMS you are on you should be able to use popen() or vfork() and exec(). If you go here: http://h71000.www7.hp.com/doc/731FINAL/5763/5763PRO.HTML you'll get the recent C RTL docs for VMS. Also you may want to look at the decc$set_child_standard_streams function. If all you need is standard in or standard out of the perl script then I'd go with popen() as I believe it works pretty well but be aware that standard out from a child process will be buffered and there is no way of unbuffering it from the parent using popen. Hope that helps.
