[comp.lang.pascal] Unix system call `open' from HP-Pascal; how?

bert@gufalet.let.rug.nl (Bert Bos) (07/04/90)

I tried to use the Unix system routine `open' to open files in my
HP-Pascal program (on a HP 9000/840), but the linker consistently used
HP-Pascal's own `open' routine. I tried to declare `open' as `external
C' (which worked for other calls), I even tried to uses the $alias
compiler option to try to fool the linker, but to no avail. Is there a
way around this?-- 
  "Always remember, however, that there's    Bert Bos (bert@gufalet.let.rug.nl)
   usually a simpler and better way to do    Alfa-informatica
   something than the first way that pops    RijksUniversiteit Groningen
   into your head." (D.E. Knuth, TeXbook)    Groningen, The Netherlands

ton@hpuamsa.UUCP (Ton 't Lam AEO) (07/05/90)

Hallo,

I have piece of code and I remember to have it working.
(But it may have been beginner's luck ?!)

TYPE
   PATHNAME = PACKED ARRAY [1..50] OF CHAR;
...
FUNCTION open
   VAR path : PATHNAME;
       oflag: INTEGER);
   INTEGER:
   EXTERNAL;

...
BEGIN
   path = '/dev/hpib9';
   path[11] = CHR(0);        { The C-open expects that a string
			       is terminated with character zero! }
   eid = open( path, 2);     { 2 = O_RDWR; look also in
			       /usr/include/stdio.h }


Another possible solution that will works:

FUNCTION $ ALIAS 'open' $ dopen
   VAR path : PATHNAME;
       oflag: INTEGER);
   INTEGER:
   EXTERNAL;

and dopen() is in a so called onionskin, this is a little C-program:

dopen( path, oflag)
char *path;
int oflag;
{
   int eid;
   if( (eid = open( path, oflag)) == -1) {
      perror( "Problem ");
      exit( 1);
   }
   return( eid);
}

Compile the C program as follows:
   cc -c cprog.c

The result is an object file called cprog.o

Now do:
   pc -o pprog pprog.p cprog.o

Good luck,
Ton 't Lam,

ton@hpuamsa.UUCP (Ton 't Lam AEO) (07/05/90)

I made a little typo.

I said:
  FUNCTION open
     ( VAR path : PATHNAME;
	   oflag: INTEGER);   
       INTEGER:
       EXTERNAL;

This must be:
  FUNCTION open
     ( VAR path : PATHNAME;
	   oflag: INTEGER):  <---   
       INTEGER;   <---
       EXTERNAL;

I exchanged the : and ;

By the way thinking it over you don't need an unionskin.

$sysprog on$
$underscore on$
program tryit( input, output);

const
   O_RDWR   = 2;
   O_WRONLY = 1;

type
   pathname = packed array[1..81] of char;
   cstring  = packed array[1..81] of char;

var
   eid            : integer;
   err ['_errno'] : integer;
   path           : pathname;
   str            : cstring;
   len            : integer;


function $ ALIAS 'open' $ dopen
		 (var path  : pathname;
		      oflag : integer) : integer ; external;

function $ ALIAS 'close' $ dclose
		 (       fd : integer) : integer ; external;

function $ ALIAS 'write' $ send  
		 (       fd : integer;
		  var buffer: cstring;
		      nbyte : integer)           ; external;

begin
   path     = 'filename';
   path[9]  = chr(0);
   eid      = dopen( path, O_RDWR);
   if eid = -1 then
   begin
      writeln( 'Err: ', err');
      halt;
   end;
   cstring  = 'Just a sentence' + chr( 0);
   len      = strlen( cstring);
   write( eid, cstring, len);   { something like this }
   dclose( eid);
end.

This will do. You may want to look in the UNIX reference manual
at create(2), open(2), read(2), close(2). 

Please give a little reply, if it went fine.

Regards,
Ton 't Lam.

bigelow@hpfcso.HP.COM (Jim Bigelow) (07/24/90)

Regarding the problem of having the linker always pick the pascal open
rather then the unix system call open, try explicitly including libc.a
on the compile line, e.g.,
  pc prog.p -lc

This will cause libc.a to be searched *before* libpc.a by generating
the following ld line:

  /bin/ld /lib/crt0.o prog.o -lc -x -lpc -lm -lc

Note that libc.a is on the command line twice, the second reference
will statisfy libpc.a calls to unix and C.

Best regards,

Jim Bigelow
S300 Pascal
Colorado Language Lab
Hewlett Packard.