|
Alan,
The documentation merely says that it has to accept null-terminated
strings as parameters. It doesn't say it has to be a C program.
The C program that you posted is doing nothing to convert the
null-terminated strings to non-null terminated strings, so you must be
already taking care of that part in your RPG program. (Or the caller is
padding it with sufficient blanks that it's not needed.)
So what is there to show you, really?
I'm guessing you're expecting it to be more complex than it is... For
example, you're spawning a program that takes 2 parameters, each are
character strings... You already know how to use the spawn() API to send
those, since you're already doing that. So the RPG program to receive them
would receive them like this (in current coding style):
dcl-pi *N;
parm1 char(123);
parm2 char(123);
end-pi;
In older V5/V6 fixed format style you'd use D-specs, this does exactly the
same thing:
D PI
D parm1 123a
D parm2 123a
In ancient V3 or RPG/400 style you'd do this:
C *ENTRY PLIST
C PARM PARM1 123
C PARM PARM2 123
All of these methods do exactly the same thing. You get two parameters
into your program.. I'm just not sure which one you are/aren't familiar
with.
Anyway, the other consideration is that the parameters are
null-terminated. You're already dealing with this, since your C stub
program was also passing them null-terminated to the RPG. Which is why I
don't know what question to answer here... but in case you don't know:
1) If the caller passes a string that's as large as the parameter or
larger (123 characters in my example above) then there's no need to do
anything, it'll work fine with the above code.
2) If the caller sometimes passes shorter strings, you'll want to convert
the parameters above to RPG CHAR (or better, VARCHAR/VARYING) variables
with the nulls removed, so you'll do this:
dcl-s workVar1 varchar(123);
dcl-s workVar2 varChar(123);
workVar1 = %str(%addr(parm1));
workVar2 = %str(%addr(parm2));
And from that point on, only work with workVar1/workVar2.
As for not keeping track of pids and wait/waitpid... that means you have a
memory leak in your application. Each time you spawn a job, it consumes
memory. Not until the parent job ends (the one that called the spawn API)
is this memory cleaned up.
-SK
On 5/26/2016 2:31 PM, Alan Campin wrote:
You are right. I found other code that I did that passed the argument listThis is the RPG programming on the IBM i (AS/400 and iSeries) (RPG400-L)
correctly. I will fix my code.
It was my understanding from what I read on-line that you had to have a C
program to receive the parameters. Maybe documentation is old? Not sure.
In
my case, I did not have any parameters I was passing through. The socket
descriptor is being passed in a file descriptor. I did not find anything
in
any of your example programs where you used an RPG program as a start of a
spawned job. Do you have an example? If yes, I could eliminate the C stub
which I would prefer.
I definitely don't want to use a SBMJOB. That would mean that each time
that a client job connected it would have to wait for the submitted job to
start up. Spawn and pre-start jobs work great.
In my case, I am not worrying about PID's. I simply have a socket server
sitting and waiting for requests to come in. When request comes in, it
spawns a new job and has nothing further to do with the request.Just an
RPG
implementation of C code.
Anyway, if you have an RPG version of a spawned program receiving
parameters I would appreciate it.
On Thu, May 26, 2016 at 11:42 AM, Scott Klement <
rpg400-l@xxxxxxxxxxxxxxxx>
wrote:
Alan,
That code is wrong, it is passing only one parameter to the RPG program,
not the whole list.
And, it's not really necessary to do this... you can just use regular
RPG
parameters and skip the C stub, it's not doing anything for you but
adding
complexity.
True, the parameters you get will be null-terminated, but so what... the
way you're passing the C parameter across, it'll still be
null-terminated.
RPG can easily copy it to a variable without the null terminator with
it's
%str() BIF.
You seem to be going out of your way to make this more complicated than
it
needs to be.
The complex part is really in the program that's calling spawn(). Don't
forget to keep track of the pid and call wait() or waitpid() to clean up
the child job! Don't forget to set up the inheritance and handle the
proper signals! Don't forget to make null-terminated pointer arrays for
args and envvars...
Or use SBMJOB instead.
-SK
On 5/26/2016 10:51 AM, Alan Campin wrote:
One other thing I forgot to mention is that spawn jobs need a C type
interface so you need a small stub of code to receive the parameters Cmailing list
style and call an RPG procedure. .
#include <stdio.h>
#include <stdlib.h>
void RunWorker(char *);
main(int argc, char **argv) {
// Call RPG/ILE function to run worker job.
RunWorker(argv[1]); // Pass pointer to argument list.
}
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* RunWorker
* Run the Worker Job for the Iseries Interface.
* Input - Null Terminated List of parameters.
* Output - None
* Returns - None
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
dcl-proc RunWorker Export;
dcl-pi *N;
InArgumentList Pointer Value;
end-pi;
On Thu, May 26, 2016 at 7:16 AM, Alan Campin <alan0307d@xxxxxxxxx>
wrote:
Alex, normally you would not be using spawn to run jobs in QBATCH. Spawn
is used to connect to pre-start jobs.This is the RPG programming on the IBM i (AS/400 and iSeries) (RPG400-L)
You define a subsystem with pre-start jobs and then you use Spawn to
take
over one of these jobs. This is not something that you would want to do
in
QBATCH.
Having said that I have an open source project that I have been working
on. that consists of a socket server spawning socket worker jobs. One
part
of that project is a service program XVSPWN that wraps up the spawn
interface to make it easy to use.
Could I know what you are planning to use the spawn api for. It sounds
like you might be looking for pre-start jobs.
On Thu, May 26, 2016 at 3:34 AM, Scott Klement <
rpg400-l@xxxxxxxxxxxxxxxx>
wrote:
Hello Alex,
--
On 5/26/2016 2:09 AM, amunra@xxxxxx wrote:
Speaking about not CL technique.
Does anybody use spawn() API to create a separate jobs?I use the spawn() API quite often. But it is important to understand
Some years ago I tried to use it, but I didn't find the way to
create job
in different subsystems.
Does anyone know if there is a way to run jobs in QBATCH
subsystem?
that it does not simply submit a new job -- instead it creates a
"child
process". Your job that calls spawn() is considered it's parent.
Due to the nature of a child process, it must always be in the same
subsystem as the parent job. So spawn() cannot cause a job to run in
a
different subsystem.
There are other things about child processes that are different,
too...
for example, even after the child process ends, some memory from it is
kept
around until the parent process calls wait or waitpid to get it's exit
status, etc. Also, child processes inherit a number of things from
the
parent. For details on all these things, see the manual for spawn()
in
the
IBM Knowledge Center.
For what you are doing, you might consider using the SBMJOB command
instead of the spawn() API.
-SK
--
This is the RPG programming on the IBM i (AS/400 and iSeries)
(RPG400-L)
mailing list
To post a message email: RPG400-L@xxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: http://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxx
Before posting, please take a moment to review the archives
at http://archive.midrange.com/rpg400-l.
Please contact support@xxxxxxxxxxxx for any subscription related
questions.
To post a message email: RPG400-L@xxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: http://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxx
Before posting, please take a moment to review the archives
at http://archive.midrange.com/rpg400-l.
Please contact support@xxxxxxxxxxxx for any subscription related
questions.
--
mailing list
To post a message email: RPG400-L@xxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: http://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxx
Before posting, please take a moment to review the archives
at http://archive.midrange.com/rpg400-l.
Please contact support@xxxxxxxxxxxx for any subscription related
questions.
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.