comp.lang.ada
 help / color / mirror / Atom feed
* Spawning a subprocess and communicating with it.
@ 1998-10-01  0:00 Condic, Marin D.
  1998-10-02  0:00 ` Rick Stikkers
                   ` (3 more replies)
  0 siblings, 4 replies; 24+ messages in thread
From: Condic, Marin D. @ 1998-10-01  0:00 UTC (permalink / raw)


    I'm looking for an example of how I might accomplish the following
    using SunOS 5.5.1 Unix and GNAT 3.9 (or later):

    I want to write an Ada program that can start up another Ada
    program as a subprocess, coprocess or whatever is the common Unix
    paradigm. (I just need it running as a separate, stand-alone
    executable image whose execution need go on no longer than that of
    the parent program that initiated it.) When the subprocess is up
    and running, I need to trade messages back and forth (character
    strings are sufficient) between the two processes.

    I presume this is all doable through various Unix system calls,
    but unfortunately, we don't seem to have anyone around here who is
    much of an expert on Unix calls, or how to interface to them via
    Ada or even any manuals one might peruse on the subject. If
    someone could send me a small example of how this is done, I would
    be grateful. Thanks.

    MDC
Marin D. Condic
Real Time & Embedded Systems
Pratt & Whitney,
Government Engines & Space Propulsion
M/S 731-95, P.O.B. 109600,
West Palm Beach, FL, 33410-9600
Ph: 561.796.8997         Fx: 561.796.4669

"The speed with which people can change a courtesy into an entitlement is
awe-inspiring."
        --  Miss Manners, February 8, 1994




^ permalink raw reply	[flat|nested] 24+ messages in thread
* Re: Spawning a subprocess and communicating with it.
@ 1998-10-05  0:00 Condic, Marin D.
  1998-10-06  0:00 ` Robert L. Spooner
                   ` (3 more replies)
  0 siblings, 4 replies; 24+ messages in thread
From: Condic, Marin D. @ 1998-10-05  0:00 UTC (permalink / raw)


Rick Stikkers <rstikkers@TELIS.ORG> writes:
>    As far as starting another program within your program, that is
>relatively easy.  Look up unix.exec and that should give you a pretty good
>start.  When it comes to communicating between these processes, things
>become a little more difficult.
>    The programs are going to have to talk back and forth on sockets.  As
>long as you just plan on talking between these two processes, it is
>relatively easy.  If you plan on adding more processes in the future,
>though, I would suggest writing a message router.  Socket communications
can
>either be done through C routines as we use at my company, or through use
of
>C pragmas.  Either way, you are going to have to rely heavily on C code.
>Although I am not allowed to release source code done for work, I did find
>some source that looks like it will work at
>http://www.cs.fsu.edu/~baker/cen4010.S97/ada/sockets/gnatsocks/
>Good luck in this journey.  It is not an easy road.
>

Thanks for the info. I've bookmarked the page you site & will check it out.

I believe all I am going to need for my current application is the plain
vanilla case of one-to-one communication. Simple command/response protocol
where one process asks the other process for data and that process simply
returns it.

Are you sure it all has to be done with C routines? I'd think that most of
this should be simply connecting to OS runtime libraries, which may have an
interface expressed in C syntax, but ought to be accessible from anything.
Especially since Ada has such good syntax for connecting to stuff in other
languages.

MDC

Marin D. Condic
Real Time & Embedded Systems
Pratt & Whitney,
Government Engines & Space Propulsion
M/S 731-95, P.O.B. 109600,
West Palm Beach, FL, 33410-9600
Ph: 561.796.8997         Fx: 561.796.4669

"The speed with which people can change a courtesy into an entitlement is
awe-inspiring."
        --  Miss Manners, February 8, 1994




^ permalink raw reply	[flat|nested] 24+ messages in thread
* Re: Spawning a subprocess and communicating with it.
@ 1998-10-07  0:00 Condic, Marin D.
  1998-10-08  0:00 ` dennison
                   ` (2 more replies)
  0 siblings, 3 replies; 24+ messages in thread
From: Condic, Marin D. @ 1998-10-07  0:00 UTC (permalink / raw)


dennison@TELEPATH.COM writes:
>
>I don't think that was excetly what he was saying. But if it is, he's
>incorrect. Since they are meant to interface with C code directly, OS
>routines are usually imported into Ada programs *as*if* they were C
routines.
>The only problem with writing your code in Ada is that you will find their
>interfaces annoyingly non-Ada like. I suppose you also have to be aware
that
>OS routines aren't always task-safe.
>
Yeah, I sort of figured that was the case. In this particular instance, I
don't need to worry too much about task-safe. I just need to make sure that
I have two processes with a pipeline between them which will trade off data
in a command/response protocol.

>Again, if you aren't ever going to run these processes on separate
processors
>I would highly suggest using Unix IPC (shared memory or message queues)
>rather than sockets (TCP/IP). IPC is a lot easier to interface to and use.
On
>the other hand, TCP/IP looks better on a resume'...
>
Actually, my problem is *is* separate processors. I've got a tool which
normally would run on a workstation and would want to talk to an embedded
processor across a 1553 mux. The embedded software just waits for a message,
then responds to it. (maybe a little more complicated than all that, but not
by a lot.) What I'm building is a way of running pieces of that embedded
software on the workstation and having the tool see it in pretty much the
same way.

BTW: I was trying to do essentially the same sort of thing on a WinNT
platform with the Win32ada bindings without much success. In attempting to
build the client/server version of the "Hello World" application, I wrote
the following code, which no matter how I changed around the parameters,
didn't seem to want to fire up a separate process. Everything I've been able
to gather about the CreateProcess call indicates that when this program is
run in an MS-DOS command prompt window (on WinNT) it should create another
window in which will execute the "Server_01" application. But the
CreateProcess call keeps failing and I have no clue as to why. Any guesses?

MDC


with Win32 ;
with Win32.Winbase ;
with Ada.Text_IO ;
with Ada.Unchecked_Conversion ;
with Interfaces.C ;
with System ;

use Interfaces.C ;

procedure Client_02 is
    --
    --  Cause a Server process to be started up.
    --
    Success                : Win32.Bool ;
    Wait                   : Win32.Dword ;
    Cmd                    : aliased constant Char_Array :=
        To_C ("C:\Ada95\Server_01.exe") ;
    Proc_Security          : aliased Win32.Winbase.SECURITY_ATTRIBUTES ;
    Thread_Security        : aliased Win32.Winbase.SECURITY_ATTRIBUTES ;
    Startup_Info           : aliased Win32.Winbase.STARTUPINFOA ;
    Process_Info           : aliased Win32.Winbase.PROCESS_INFORMATION ;
    --
    function CP (A : Interfaces.C.Char_Array) return Win32.LPSTR is
        function
            UC1
        is new
            Ada.Unchecked_Conversion (
                Source    => System.Address,
                Target    => Win32.LPSTR);
    begin
        return UC1 (A (A'First)'Address);
    end CP;
    --
    use Win32 ;
    use Ada.Text_IO ;
    use Win32.Winbase ;
begin
    Put_Line ("Client_02: Getting Client Process Info") ;
    GetStartupInfo (
        lpStartupInfo    => Startup_Info'Unchecked_Access) ;
    --
    --  Create the subprocess.
    --
    Put_Line ("Client_02: Creating Process") ;
    Success    := CreateProcess (
        lpApplicationName    => null,
        lpCommandLine        => CP (Cmd),
        lpProcessAttributes  => Proc_Security'Unchecked_Access,
        lpThreadAttributes   => Thread_Security'Unchecked_Access,
        bInheritHandles      => Win32.False,
        dwCreationFlags      => Win32.Winbase.CREATE_NEW_CONSOLE or
                                Win32.Winbase.NORMAL_PRIORITY_CLASS,
        lpEnvironment        => System.Null_Address,
        lpCurrentDirectory   => null,
        lpStartupInfo        => Startup_Info'Unchecked_Access,
        lpProcessInformation => Process_Info'Unchecked_Access) ;
    --
    if (Success = Win32.False) then
        Put_Line ("Client_02: Process did not start successfully." &
            Win32.Bool'Image (Success)) ;
    else
        --
        Put_Line ("Client_01: Hello World! ") ;
        delay 1.0 ;
        --
        --  Wait for the other process to complete.
        --
        Wait := WaitForSingleObject (
            hHandle           => Process_Info.hProcess,
            dwMilliseconds    => INFINITE) ;
        --
        Put_Line ("Client_02: Completed") ;
    end if ;
    --
end Client_02 ;




Marin D. Condic
Real Time & Embedded Systems
Pratt & Whitney,
Government Engines & Space Propulsion
M/S 731-95, P.O.B. 109600,
West Palm Beach, FL, 33410-9600
Ph: 561.796.8997         Fx: 561.796.4669

"The speed with which people can change a courtesy into an entitlement is
awe-inspiring."
        --  Miss Manners, February 8, 1994




^ permalink raw reply	[flat|nested] 24+ messages in thread
* Re: Spawning a subprocess and communicating with it.
@ 1998-10-08  0:00 Condic, Marin D.
  1998-10-09  0:00 ` alan walkington
  0 siblings, 1 reply; 24+ messages in thread
From: Condic, Marin D. @ 1998-10-08  0:00 UTC (permalink / raw)


Thanks for the reply. Looking at the GNAT code in the GNAT.OS_Lib package,
it's "Non_Blocking_Spawn" function degenerates to a C call after massaging
some parameters. Someone sent me an example of how to do this with Unix
calls, but then you've got something that can't automatically correct itself
if moved to the PC.

Unfortunately, I do have to have two separate processes. The problem is that
the client and the server have to be separate programs since the server
could be either another process running on the workstation, or on a
different workstation, or an embedded application in my engine control
computer. I need to design the connection so that the same program - or one
with slight variations - can talk to the simulated embedded machine or the
real embedded machine. I figure that breaks down into processes and pipes at
the workstation end.

The GNAT.OS_Lib routines work successfully and without change on both the
Sun and the PC, so this is good. The bad part is that I can't seem to get
the child process fired up in a different window and I'm not sure how to
open up the pipe between the two processes in a semi-portable manner. If you
think of anything that might help here, I'd appreciate it. Thanks.

> ----------
> From:         Roga Danar[SMTP:smithm@stelnj.com]
> Sent:         Thursday, October 08, 1998 4:02 PM
> To:   Condic, Marin D.
> Subject:      Re: Spawning a subprocess and communicating with it.
>
> Hi,
>
>   What you want to do could be done with a little 'C' used as a glue
> between
> the 2 Ada processes.  C has a routine that will call the OS.  You give it
> a
> string as you would on the command line and off you go.  Ada can,
> ofcourse,
> interface with the 'C' which can be as the communication line between the
> 2
> processes.
>
>   That said,  I cannot think of a situation off-hand that I would not use
> Ada
> native tasking to produce a current "process".  A task will not be another
> process, ofcourse.
>
>

Marin D. Condic
Real Time & Embedded Systems
United Technologies, Pratt & Whitney
Government Engines & Space Propulsion
M/S 731-95, P.O.B. 109600, West Palm Beach, FL, 33410-9600
Ph: 561.796.8997         Fx: 561.796.4669

"Today is the first day of the rest of your solitary, poor, nasty brutish,
and short existence on this planet"
       -- "Life In Hell"




^ permalink raw reply	[flat|nested] 24+ messages in thread
* Re: Spawning a subprocess and communicating with it.
@ 1998-10-09  0:00 Condic, Marin D.
  0 siblings, 0 replies; 24+ messages in thread
From: Condic, Marin D. @ 1998-10-09  0:00 UTC (permalink / raw)


John McCabe <john@ASSEN.DEMON.CO.UK> writes:
>As a matter of interest, should it not be possible to do interprocess
>communication using the RPC stuff defined in the Distributed Systems
>Annexe?
>
>Does anyone fully support that yet?

I took a look at the Distributed Systems Annex and it didn't seem to do what
I wanted to do. From as best I could figure (not really being a distributed
computing kind of guy - at least not in the sense most people would mean)
this looked like it was spelling out ways of sharing memory between two
processes and of supporting "dynamic link libraries" (or whatever the term
would be for the given OS) which might reside on a separate processor. I
suppose this would be fine if all I wanted was to distribute the workload of
one program across several machines. My problem is that I really have two
separate programs which both run independently and the one program needs to
interrogate the other program periodically concerning its state. (One of the
programs simulates the embedded computer application on a workstation or PC
- the other is a monitor program that would normally run on the workstation
and interrogate the embedded computer.)

As far as support for the annex, I vaguely recall somebody making mention of
it being available in GNAT, but I certainly couldn't attest to that
personally. I'm sure Robert Dewar could fill us in on this one.

MDC

Marin D. Condic
Real Time & Embedded Systems
United Technologies, Pratt & Whitney
Government Engines & Space Propulsion
M/S 731-95, P.O.B. 109600, West Palm Beach, FL, 33410-9600
Ph: 561.796.8997         Fx: 561.796.4669

"Today is the first day of the rest of your solitary, poor, nasty, brutish,
and short existence on this planet"
       -- "Life In Hell"




^ permalink raw reply	[flat|nested] 24+ messages in thread
* Re: Spawning a subprocess and communicating with it.
@ 1998-10-09  0:00 Condic, Marin D.
  1998-10-13  0:00 ` Robert I. Eachus
  0 siblings, 1 reply; 24+ messages in thread
From: Condic, Marin D. @ 1998-10-09  0:00 UTC (permalink / raw)


dennison@TELEPATH.COM writes:
>To my mind that whole annex misses the mark. It doesn't actually require
>different implementations to interoperate. Thus even if every compiler
>suppored it, it would be useless unless you are developing a system using a
>single compiler and architecture.

This would certainly be interesting, but I think it would have required some
sort of standard outside the bounds of the language. The problem would be
that you'd have to specify in painful detail exactly how all the data would
be represented and how the connections were to be made. We typically have a
similar problem in that we build an embedded machine which will communicate
with the outside world via MilStd1553 or UART links and, given the life of a
system possibly running out 30 years or more, you have no clue what will be
on the other end of the wire. Hence, you have to have an ICD that lays out
exact representation of all messages and once done, you're stuck with them
forever.

I would think that if Ada wanted to guarantee interoperability between Ada
implementations (and possibly other languages as well) the standard would
have to have become machine or OS specific. (Thou shalt use such-and-such OS
call in Unix to implement feature XYZ lest ye should fail to communicate
with thine neighbor. :-)

MDC

Marin D. Condic
Real Time & Embedded Systems
United Technologies, Pratt & Whitney
Government Engines & Space Propulsion
M/S 731-95, P.O.B. 109600, West Palm Beach, FL, 33410-9600
Ph: 561.796.8997         Fx: 561.796.4669

"Today is the first day of the rest of your solitary, poor, nasty, brutish,
and short existence on this planet"
       -- "Life In Hell"




^ permalink raw reply	[flat|nested] 24+ messages in thread
* Re: Spawning a subprocess and communicating with it.
@ 1998-10-12  0:00 Condic, Marin D.
  1998-10-13  0:00 ` Pascal Obry
  0 siblings, 1 reply; 24+ messages in thread
From: Condic, Marin D. @ 1998-10-12  0:00 UTC (permalink / raw)


The model you suggest sounds interesting. I don't know much about what
compiler options you'd have to use (or other linkage issues that might be
involved) to get this sort of thing to work, but it doesn't sound
particularly hard. Maybe you have a "Hello World" of distributed processing
you could share?

While the distributed issue could certainly be useful in other contexts, I
don't think it would suit my current problem. Imagine my embedded control
software running in its own little box and periodically looking at a
MilStd1553 bus for a message from the monitor program. It receives a
message, collects up some data and blips it back down the wire. I can't
change that software because it already exists in lots of boxes. What I'd
like to do is run a variation of that software on a workstation with no
"structural" changes - just a thin layer of code that says "Instead of
getting your messages from a MilStd1553 bus, you're going to be getting them
from this OS supplied pipe - otherwise, they look identical and the protocol
is the same." The same situation would exist for the monitor program -
either it uses the MilStd1553 to talk to the embedded code in the "real"
machine, or it uses a pipe to communicate with a variation of the software
compiled for the workstation. (Initially a Sun/Unix box, but soon to be
appearing in a WinNT box as well.) There may be some way of visualizing this
all as RPCs, but it sounds like I'd be building some layer of complexity I
don't need if all I want to do is change the transport mechanism for a
message passing system that is already in place.

BTW: You wouldn't happen to know how to make the CreateProcess system call
work on WinNT using Win32ada? I've been fighting it for days and keep
loosing. Maybe there's some secret handshake for getting system calls to
work with GNAT on the PC??? ;-)

MDC

> ----------
> From:         dale@cs.rmit.edu.au[SMTP:dale@cs.rmit.edu.au]
> Sent:         Sunday, October 11, 1998 7:22 AM
> To:   Condic, Marin D.
> Subject:      Re: Spawning a subprocess and communicating with it.
>
> In article <F3740247C2BED111A0AE00805FEA9C92017FFD30@pwflml02.pwfl.com>,
> "Condic, Marin D." <condicma@PWFL.COM> wrote:
>
> hello Marin,
>
> I've (and my first year students) have used the DSA, and found it quite
> easy to use. The model it presents is of one large Ada program that is run
> on separate machines.
>
> We managed to have a client server model for a chat room. Students would
> write simple programs that called on the services of a package (who is in
> the room with me, what doors are there from this room, say something to
> the people in the room etc). The students programs were then compiled
> using gnatdist, which translated the conventional procedure calls into RPC
> stubs. The package would receive the calls (you didn't have to do anything
> special - the DSA details were all hidden from you), and service them as
> any other call to the package would have been.
>
> All in all a very easy way to run programs. If you can imagine your system
> as a large Ada program consisting of independent Ada tasks, then this
> model is a very easy way to approach this sort of problem.
>
> Dale
>




^ permalink raw reply	[flat|nested] 24+ messages in thread
* Re: Spawning a subprocess and communicating with it.
@ 1998-10-13  0:00 Condic, Marin D.
  1998-10-13  0:00 ` Scott Ingram
  0 siblings, 1 reply; 24+ messages in thread
From: Condic, Marin D. @ 1998-10-13  0:00 UTC (permalink / raw)


Tom Moran <tmoran@BIX.COM> writes:
>This sounds like you could have your main Ada program start a task
>which would call the main procedure in the other program, and then
>they could trade information via a (protected) buffer or something.

That would work if I could live with a monolithic program. The problem is
that the two units are difficult to intertwine. On the one side, you have a
Monitor program which wants (normally) to communicate with an embedded
computer via a 1553 bus. I want to modify it to use either a 1553 bus or an
OS Pipe so that it can talk to a "simulated" embedded computer. On the other
side, I've got software which would normally run in the embedded computer
that I want to wrap with some "glue" software such that it can be compiled
and run on a Workstation or PC. The "glue" simply wants to hide the 1553 bus
behind an OS Pipe so that, hopefully with minimal change to the embedded
software, it can behave just as it does in its embedded box - just getting
the messages via a different transport. I don't think it would be a good
idea to be trying to create versions of each software product which have to
be compiled and linked together in order to communicate. That could begin to
hurt a lot, not to mention start structurally changing things so that you
can't be sure of similar behavior to the "real" software.

>  But other messages in this thread suggest that the 'subprogram' may
>in fact be running on another machine (in which case as noted the
>Distributed Annex would be appropriate) but it is already in existence
>and cannot be changed and does not use the Distributed Annex for its
>communication.  That implies the programs need to talk via the OS.
>Unless the existing program(s) use some OS communication method that
>is transparent as to whether one, or more, CPUs are involved, it sure
>sounds like you are going to have to write some glue code to abstract
>away the CPU count.  So this is really a language independent  OS
>question.
>  Or did I miss something?

I don't think the Distributed Annex is appropriate - although somebody might
suggest a model which would allow things to work with minimal fuss. The
embedded software is already in existence, but to run it on the workstation
would require some wrapper software to hide the lack of physical devices.
(mostly, at this juncture, the 1553 bus) So I'm not totally against any
modification to the embedded side - I'd just like to minimize it.

My understanding of the Distributed Annex is that it gives you two
mechanisms for passing messages between separate processes. One is some form
of shared memory. The other is a Remote Procedure Call with parameters.
Neither of these lines up really well with what the software does now -
transmit/receive messages across a wire. Whereas an OS Pipe is nearly an
identical mechanism. To use a shared buffer, I'd have to drastically change
the way messages are passed between the monitor and the embedded software
such that I'll really end up with two distinct products which may not behave
in exactly identical ways. To use an RPC, I'd have to (on the transmit side)
do something to change the bundling up & sending of bytes into the passing
of parameters to a remote procedure. On the receiving side, instead of
responding asynchronously to the arrival of a message, I've got a procedure
which gets called that then has to take its parameter and do something to
make it look like a message arrival. And then there's the problem that
*both* pieces of software are going to transmit and receive and I'm not sure
how that figures into an RPC kind of model. So I'm thinking that the
Distributed Annex, while interesting for a whole lot of reasons, may not be
the best fit to this problem.

I've seen some possible methods of firing up child processes from both WinNT
and Unix. I've also seen some calls for creating the pipes between the
processes. I think that some version of this is probably the answer I need.
My problem at this point is that I can't quite get the behavior I want from
the Unix side (my ignorance, no doubt) and I can't get the WinNT calls to
work at all. (Must be doing something wrong! ;-) The GNAT.OS_Lib package
seems to provide some semi-standard ways of creating the child process,
(which is good if I've got to support both platforms) but on either the Unix
or WinNT side, it doesn't seem to create a separate "window" for the child
process. (Maybe that's *more* OS calls?) It is also not clear if it is
possible to use the GNAT.OS_Lib to create a pipeline between the two
processes. So I'm still doing research and hammering away at different
trial-and-error programs to see if I can get something to work at the "Hello
World" level. If you've got any examples or suggestions, I'm listening.

Thanks

MDC

Marin D. Condic
Real Time & Embedded Systems
United Technologies, Pratt & Whitney
Government Engines & Space Propulsion
M/S 731-95, P.O.B. 109600, West Palm Beach, FL, 33410-9600
Ph: 561.796.8997         Fx: 561.796.4669

"Today is the first day of the rest of your solitary, poor, nasty, brutish,
and short existence on this planet"
       -- "Life In Hell"




^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~1998-10-13  0:00 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-10-01  0:00 Spawning a subprocess and communicating with it Condic, Marin D.
1998-10-02  0:00 ` Rick Stikkers
1998-10-02  0:00 ` dennison
1998-10-05  0:00 ` John McCabe
1998-10-12  0:00 ` Tom Moran
  -- strict thread matches above, loose matches on Subject: below --
1998-10-05  0:00 Condic, Marin D.
1998-10-06  0:00 ` Robert L. Spooner
1998-10-06  0:00 ` dennison
1998-10-07  0:00 ` Jerry van Dijk
1998-10-07  0:00 ` John McCabe
1998-10-08  0:00   ` dennison
1998-10-07  0:00 Condic, Marin D.
1998-10-08  0:00 ` dennison
1998-10-08  0:00 ` dennison
1998-10-08  0:00 ` Jerry van Dijk
1998-10-08  0:00 Condic, Marin D.
1998-10-09  0:00 ` alan walkington
1998-10-09  0:00 Condic, Marin D.
1998-10-09  0:00 Condic, Marin D.
1998-10-13  0:00 ` Robert I. Eachus
1998-10-12  0:00 Condic, Marin D.
1998-10-13  0:00 ` Pascal Obry
1998-10-13  0:00 Condic, Marin D.
1998-10-13  0:00 ` Scott Ingram

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox