[comp.lang.ada] Unix

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
===============================================================================