valdi@rhi.hi.is (Thorvaldur Sigurdsson) (03/20/90)
Subject: Unix (HP-UX) system call from ADA Newsgroups: comp.sys.hp,comp.lang.ada Keywords: ADA Problem : Making unix system calls within Ada code Background : HP-UX 6.5, HP 9000/300 series, Alsys 4.35 Ada compiler Error message : ld: Undefined external - _ll _clear ld: output file still contains undefined symbols ld: (Warning) did not generate an output file ada: Errors detected Manual : Reference Manual for the Ada Programming Language, Appendix F, page F-5, chapter F 1.1.4 Additional Information on INTERFACE and INTERFACE_NAME : "When you want to call an HP-UX system call from Ada code, you should use a pragma INTERFACE with C as the language name. It is not necassary to provide the C object file to the binder, because it will be found automatically when the linker searches the system library". Question : Is the manual wrong concerning automatic linking or am I doing something wrong in the code ? Source code : main.ada, system.ads main.ada : The following source is the main procedure -- ************************************************ -- * ABSTRACT: Main program * -- ************************************************ procedure MAIN is begin UNIX_SYSTEM_CALL.clear; UNIX_SYSTEM_CALL.ll; end MAIN; system.ads : The following source is the unix_system_call package -- ************************************************ -- * ABSTRACT: Package specification * -- ************************************************ package UNIX_SYSTEM_CALL is procedure clear; procedure ll; private pragma INTERFACE (C, clear); -- clear display pragma INTERFACE (C, ll); -- long list end UNIX_SYSTEM_CALL; -- package specification P.S. : I tried also implementing the usage of INTERFACE_NAME without results. ------------------------------------------------------------------------ Thorvaldur Egill Sigurdsson | Engineering Research Institute | Internet: valdi@kerfi.hi.is University of ICELAND | Hjardarhagi 2-6 | Phone: 354-1-694699 107 Reykjavik, ICELAND | ------------------------------------------------------------------------
karl@grebyn.com (Karl A. Nyberg) (03/21/90)
In article <1587@krafla.rhi.hi.is> valdi@rhi.hi.is (Thorvaldur Sigurdsson) writes:
%Problem : Making unix system calls within Ada code
%Background : HP-UX 6.5, HP 9000/300 series, Alsys 4.35 Ada compiler
%Error message :
% ld: Undefined external -
% _ll
% _clear
% ld: output file still contains undefined symbols
% ld: (Warning) did not generate an output file
% ada: Errors detected
%
% "When you want to call an HP-UX system call from Ada
% code, you should use a pragma INTERFACE with C as the
% language name. It is not necassary to provide the C
% object file to the binder, because it will be found
% automatically when the linker searches the system
% library".
%
%Question : Is the manual wrong concerning automatic linking or
% am I doing something wrong in the code ?
%
My guess is you are trying to use not SYSTEM calls, but calls to units in
some particular libraries (e.g. curses?). In those cases, you will need to
include the C object file to the binder (possibly the archive file?) to
resolve those names.
Or, are you trying to use the shell commands "clear" and "ls -l"? In which
case you're asking an entirely different set of questions, for which the
answer is a convoluted use of either the "system" call (if it exists on your
machine) or getting an interface to fork and/or exec.
-- Karl --
defaria@hpclapd.HP.COM (Andy DeFaria) (03/22/90)
>/ hpclapd:comp.lang.ada / valdi@rhi.hi.is (Thorvaldur Sigurdsson) / 7:57 am Mar 20, 1990 / >Problem : Making unix system calls within Ada code >Background : HP-UX 6.5, HP 9000/300 series, Alsys 4.35 Ada compiler >Error message : > ld: Undefined external - > _ll > _clear > ld: output file still contains undefined symbols > ld: (Warning) did not generate an output file > ada: Errors detected Your problem is that ll and clear are not system calls but commands. If you want to execute commands then you want to call the system(3C) system call which can be accomplished like this: package UNIX_SYSTEM_CALL is procedure EXECUTE_UNIX_COMMAND (COMMAND : STRING); end UNIX_SYSTEM_CALL; package body UNIX_SYSTEM_CALL is type C_STRING is access CHARACTER; type A_STRING is access STRING; type STATUS_T is new INTEGER; -- Note that SYSTEM is a reserved word in Ada because of the package -- named SYSTEM therefore we'll change it to C_SYSTEM. This then requires -- that we use pragma INTERFACE_NAME so that the linker will search for the -- proper external. function C_SYSTEM (COMMAND : C_STRING) return STATUS_T; pragma INTERFACE (C, C_SYSTEM); pragma INTERFACE_NAME (C_SYSTEM, "system"); function CONVERT_TO_C (SRC : STRING) return C_STRING is function C_STRING_CONVERT is new UNCHECKED_CONVERSION (SOURCE => SYSTEM'ADDRESS, TARGET => C_STRING); C_STORAGE : A_STRING := new STRING'(SRC & ASCII.NUL); begin -- CONVERT_TO_C return C_STRING_CONVERT (C_STORAGE.all (C_STORAGE.all'FIRST)'ADDRESS); end CONVERT_TO_C; procedure EXECUTE_UNIX_COMMAND (COMMAND : STRING) is begin -- EXECUTE_UNIX_COMMAND STATUS := C_SYSTEM (CONVERT_TO_C ("clear")); if STATUS = -1 then raise PROGRAM_ERROR; end if; end EXECUTE_UNIX_COMMAND; end UNIX_SYSTEM_CALL; -- package specification Notes: HP_UX system calls are written in C and thereby expect strings to be in "C" format (null terminated). This is accomplished with the CONVERT_TO_C routine which allocates a new string, null terminated, then UNCHECKED_CONVERSION's it to a type called C_STRING; The above implementation hides this from the Ada user by only requiring an Ada string on the EXECUTE_UNIX_COMMAND call and performing the conversion in the package body. Since SYSTEM is a reserved word in Ada C_SYSTEM is used instead, requiring that we inform the linker of the real external function name via a pragma INTERFACE_NAME. No extra libraries need to be specified for the link phase for a system(3C) call. If, however, you tried to call a curses(3X) call then you would need to specify the curses library for the link. This is no different than what the C programmer would have to do. Most system calls return a status that should be checked. Here I simply raised PROGRAM_ERROR if the system(3C) call fails. You may want to return the error or do something else. Rather than write to specific calls for two different HP_UX commands I choose to code a more general call that executes the HP_UX command that is passed in. Your main program can now call these two commands, or any other HP_UX commands, like so: procedure MAIN is begin UNIX_SYSTEM_CALL.EXECUTE_UNIX_COMMAND ("clear"); UNIX_SYSTEM_CALL.EXECURE_UNIX_COMMAND ("ll"); end MAIN; Hope this was helpful. =============================================================================== I know you believe you understand what you think I | Andrew DeFaria said but I'm not sure you realize that what you heard| Hewlett Packard is not what I meant! | California Langauge Labs ===============================================================================
defaria@hpclapd.HP.COM (Andy DeFaria) (03/22/90)
I have notice a few minor problems with my previous posting. I reference the package SYSTEM and the generic UNCHECKED_CONVERSION but I forgot to "with" them therefore add: with SYSTEM; with UNCHECKED_CONVERSION; Also, in the package body EXECUTE_UNIX_COMMAND the following line: STATUS := C_SYSTEM (CONVERT_TO_C ("clear")); should read: STATUS := C_SYSTEM (CONVERT_TO_C (COMMAND)); so that the EXECUTE_UNIX_COMMAND executes the passed in command and not just the command "clear". Sorry =============================================================================== I know you believe you understand what you think I | Andrew DeFaria said but I'm not sure you realize that what you heard| Hewlett Packard is not what I meant! | California Langauge Labs ===============================================================================