cstein@jarthur.claremont.edu (Clifford Stein) (12/10/90)
I'm trying to laser print a file from an ada program by calling the program enscript with the execl function. I've been having problems, though. Sometimes I can print a file, other times I cannot (if it doesn't print, it [enscript] will give me a file not found message). When enscript does print, however, it prints garbage which doesn't resemble my file at all, and it [enscript] won't even print a filename at the top of the printout like it usually does. I've included the source code here, does anyone have any suggestions? (I'm using VADS serial on a Sequent running Dynix) If I compile this program the way it is right now I will get a "/hmc2/guest/lsdada/cliffie/hello4: file not found" even though hello does exist. Please respond via email. Thank you for any help. Clifford Stein with c_strings; use c_strings; with a_strings;use a_strings; with unix_prcs; use unix_prcs; with text_io; use text_io; procedure print is status:integer; name:string(1..23); argv:string(1..33); a_name:c_string; the_name:a_string; nll:character; begin argv(1..33):="/hmc2/guests/lsdada/cliffie/hello"; nll:=ascii.nul; name:="/usr/local/bin/enscript"; status:=execl(name'address,argv'address,nll'address); if status/=0 then put_line("True."); else put_line("False"); end if; end print;
emery@linus.mitre.org (David Emery) (12/10/90)
I suspect the problem is that Unix is running off the end of your string and/or your parameter list. Try the following: with system; -- assumed to provide the object "null_address" -- (also known as "address_zero" or "no_addr" on some compilers) with text_io; procedure print function execl (name : system.address; arg0 : system.address; arg1 : system.address) -- all we need return integer; -- assumed to be the same size as C "int" pragma interface (C, execl); program_name : constant string := "/usr/local/bin/enscript" & Ascii.nul; file_name : constant string := "/hmc2/guests/lsdada/cliffie/hello" & Ascii.nul; status : integer; begin status := execl (name => program_name(program_name'first)'address, arg0 => file_name(file_name'first)'address, arg1 => system.null_address); if status/=0 then put_line("True."); else put_line("False"); end if; end print; Remember, that in C strings are null-terminated, and represented by the address of the first element. Also, from the C definition of the parameters for execl, the last parameter is of type "address", with value 0, not the address of an object with value 0. There's a subtle difference, in that the former is "0", and the latter is not "0", but some (non-zero) address. Here are the changes to print a user-supplied file. Append a null to the end of the user-supplied string, and pass this to C: procedure print (file_to_print : string) is ... file_name : constant string := file_to_print & Ascii.nul; ... end print; dave emery emery@aries.mitre.org <for more tricks like this, see my paper in Tri-Ada on the POSIX Ada binding prototype.>