× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



David,

That's RPG IV ILE code.  Easiest way on AS/400 is to put into RPGLE source
file, then compile with 14 using PDM.

Command line (or Code400) is CRTRPGPGM.

HTH

Regards,

Jim Langston

-----Original Message-----
From: David Rittenberg [mailto:DRittenberg@pacerintl.com]

How would you compile the below sample program?
----- Original Message -----
From: Scott Klement <klemscot@klements.com>
<SNIP>

Here's a sample:

      * This rather silly program reads STDIN and translates all of the
      * spaces to periods, then writes it to STDOUT.
      *
      * You need to run this from QSHELL for it to be useful:
      *          /qsys.lib/yourlib.lib/this.pgm

     H BNDDIR('QC2LE') DFTACTGRP(*NO)

     D read            PR            10I 0 extproc('read')
     D  fd                           10I 0 value
     D  buf                            *   value
     D  len                          10I 0 value

     D write           PR            10I 0 extproc('write')
     D  fd                           10I 0 value
     D  buf                            *   value
     D  size                         10I 0 value

     D data            S             80A
     D len             S             10I 0

     c                   eval      len = read(0: %addr(data): %size(data))
     c                   dow       len > 0
     c     ' ':'.'       xlate     data          data
     c                   callp     write(1: %addr(data): len)
     c                   eval      len = read(0: %addr(data): %size(data))
     c                   enddo

     c                   eval      *inlr = *on


To run this, you need to run it from QSHELL.  Here's how I did it:

1) Type STRQSH

2) At the QSHELL prompt, I typed:

echo "I sure wish I had periods in this text!" |
/qsys.lib/mylib.lib/test.pgm

(that should all be one line, if it gets wrapped)


And the result looked like this:

   I.sure.wish.I.had.periods.in.this.text!


Hope that helps...





                      rpg400-l-request@m
                      idrange.com               To:
rpg400-l@midrange.com
                      Sent by:                  cc:
                      rpg400-l-admin@mid        Subject:  RPG400-L digest,
Vol 1 #644 - 7 msgs
                      range.com


                      04/15/02 06:13 PM
                      Please respond to
                      rpg400-l






Send RPG400-L mailing list submissions to
             rpg400-l@midrange.com

To subscribe or unsubscribe via the World Wide Web, visit
             http://lists.midrange.com/cgi-bin/listinfo/rpg400-l
or, via email, send a message with subject or body 'help' to
             rpg400-l-request@midrange.com

You can reach the person managing the list at
             rpg400-l-admin@midrange.com

When replying, please edit your Subject line so it is more specific
than "Re: Contents of RPG400-L digest..."


Today's Topics:

   1. Re: ifs api's (Scott Klement)
   2. RE: STDIN, STDOUT, STDERR in RPG (Scott Klement)
   3. RE: STDIN, STDOUT, STDERR in RPG (David Morris)
   4. RE: STDIN, STDOUT, STDERR in RPG (James Rich)
   5. Re: Error Message (WSID) (Ren Fu Ping)
   6. STDIN, STDOUT, STDERR in RPG (Jon Paris)
   7. RE: STDIN, STDOUT, STDERR in RPG (Peter Connell)

--__--__--

Message: 1
Date: Mon, 15 Apr 2002 18:32:09 -0500 (CDT)
From: Scott Klement <klemscot@klements.com>
To: rob@dekko.com
cc: rpg400-l@midrange.com
Subject: Re: ifs api's
Reply-To: rpg400-l@midrange.com


Rob,

Try trimming the trailing blanks off of the file name....
(This is a really common mistake.)


The file is called:
'/rob/spool2.txt'

not

'/rob/spool2.txt                                                  '

Consequently, it can't find the file.   Either use a VARYING field,
or put a %trimr() in the first argument to the stat() call...


On Mon, 15 Apr 2002 rob@dekko.com wrote:

> I've read Scott's example at:
> http://archive.midrange.com/rpg400-l/200105/msg00320.html
>
> And I've read the Redbook 'Who knew...' for handling the errno part.
>
> I have a file which shows up with
> wrklnk '/rob/spool2.txt'
>
> However, my command
> STATTEST FILENAME('/rob/spool2.txt')
>
> Results in:
> DSPLY  3025No such path or directory.
>
> File attributes:
> Object . . . . . . :   /rob/spool2.txt
>
> Type . . . . . . . . . . . . . . . . . :   STMF
>
> Owner  . . . . . . . . . . . . . . . . :   ROB
> System object is on  . . . . . . . . . :   Local
> Auxiliary storage pool . . . . . . . . :   1
>   Object overflowed  . . . . . . . . . :   No
>
> Coded character set ID . . . . . . . . :   37
> Hidden file  . . . . . . . . . . . . . :   No
> PC system file . . . . . . . . . . . . :   No
> Read only  . . . . . . . . . . . . . . :   No
>
> Need to archive (PC) . . . . . . . . . :   Yes
> Need to archive (AS/400) . . . . . . . :   No
> Last access date/time  . . . . . . . . :   01/07/02  17:50:5
> Data change date/time  . . . . . . . . :   06/01/01  15:08:5
> Attribute change date/time . . . . . . :   10/21/01  11:11:5
>
> Size of object data in bytes . . . . . :   2926
> Allocated size of object . . . . . . . :   8192
> File format  . . . . . . . . . . . . . :   *TYPE2
> Size of extended attributes  . . . . . :   0
> Storage freed  . . . . . . . . . . . . :   No
>
> Auditing value . . . . . . . . . . . . :   *NONE
>
> Object domain  . . . . . . . . . . . . :   *SYSTEM
>
> Number of hard links . . . . . . . . . :   1
> Last used date . . . . . . . . . . . . :   01/07/02
> Days used count  . . . . . . . . . . . :   2
>   Reset date . . . . . . . . . . . . . :
>
> Allow write during save  . . . . . . . :   No
>
> Digitally signed . . . . . . . . . . . :   No
> File ID  . . . . . . . . . . . . . . . :
> X'0000000000000001833C09CE0000A3BF'
>
>
>
> Entire source:
>
>
>
>      H Datfmt(*USA)
>      H ExprOpts(*RESDECPOS)
>      H Bnddir('ROUTINES/SRVPGM':'QC2LE')
>      H ActGrp('QILE')
>      H DftActGrp(*NO)
>  D**********************************************************************
>      D* File Information Structure (stat)
>      D*
>      D* struct stat {
>      D*  mode_t         st_mode;       /* File mode */
>      D*  ino_t          st_ino;        /* File serial number */
>      D*  nlink_t        st_nlink;      /* Number of links */
>      D*  uid_t          st_uid;        /* User ID of the owner of file */
>      D*  gid_t          st_gid;        /* Group ID of the group of file
*/
>      D*  off_t          st_size;       /* For regular files, the file
>      D*                                 * size in bytes */
>      D*  time_t         st_atime;      /* Time of last access */
>      D*  time_t         st_mtime;      /* Time of last data modification
> */
>      D*  time_t         st_ctime;      /* Time of last file status change
> */
>      D*  dev_t          st_dev;        /* ID of device containing file */
>      D*  size_t         st_blksize;    /* Size of a block of the file */
>      D*  unsigned long  st_allocsize;  /* Allocation size of the file */
>      D*  qp0l_objtype_t st_objtype;    /* AS/400 object type */
>      D*  unsigned short st_codepage;   /* Object data codepage */
>      D*  char           st_reserved1[66]; /* Reserved */
>      D* };
>       ** times in statds are seconds from the "epoch" (Jan 1, 1970)
>       **   and are in GMT (Greenwich Mean Time)...
>      D*
>      D p_statds        S               *
>      D statds          DS                  BASED(p_statds)
>      D  st_mode                      10U 0
>      D  st_ino                       10U 0
>      D  st_nlink                      5U 0
>      D  st_pad                        2A
>      D  st_uid                       10U 0
>      D  st_gid                       10U 0
>      D  st_size                      10I 0
>      D  st_atime                     10I 0
>      D  st_mtime                     10I 0
>      D  st_ctime                     10I 0
>      D  st_dev                       10U 0
>      D  st_blksize                   10U 0
>      D  st_alctize                   10U 0
>      D  st_objtype                   12A
>      D  st_codepag                    5U 0
>      D  st_resv11                    62A
>      D  st_ino_gen_id                10U 0
>
>      D STATTEST        PR                  EXTPGM('STATTEST')
>      D  FileName                    100a   const
>      D STATTEST        PI
>      D  FileName                    100a   const
>  D*--------------------------------------------------------------------
>      D* Get File Information
>      D*
>      D* int stat(const char *path, struct stat *buf)
>  D*--------------------------------------------------------------------
>      D stat            PR            10I 0 ExtProc('stat')
>      D   path                          *   value options(*string)
>      D   buf                           *   value
>
>      D GetTimeZone     PR             5A
>
>      D timezone        DS
>      D   tzDir                        1A
>      D   tzHour                       2S 0
>      D   tzFrac                       2S 0
>
>
>      D statsize        S             10I 0
>      d Msg             S             50A
>      D AccessTime      S               Z
>      D ModifyTime      S               Z
>      D ChgStsTime      S               Z
>      D charTS          S             26A
>      D Epoch           S               Z   INZ(z'1970-01-01-00.00.00')
>
>      DGetErrNo         PR              *   ExtProc('__errno')
>      DStrError         PR              *   ExtProc('strerror')
>      D ErrorNo                       10i 0 Value
>      DpErrorNo         s               *   inz
>      DErrorNo          s             10i 0 based(pErrorNo)
>      DpErrorMsg        s               *   inz
>      DErrorMsg         s            100a   based(pErrorMsg)
>
>      c                   eval      *inlr = *on
>
>      c                   eval      statsize = %size(statds)
>      c                   alloc     statsize      p_statds
>
>      c                   if        stat(FileName: p_statds) < 0
>      c                   eval      pErrorNo = GetErrNo
>      c                   eval      pErrorMsg = StrError(ErrorNo)
>      c                   eval      Msg = %char(ErrorNo) + ErrorMsg
>      c
>      c                   dsply                   Msg
>      c                   return
>      c                   endif
>
>       ** times in statds are seconds from the "epoch" (Jan 1, 1970)
>       **   and are in GMT (Greenwich Mean Time)...
>       ** Hey!  Lets convert them to RPG timestamps!
>      c     Epoch         adddur    st_atime:*S   AccessTime
>      c     Epoch         adddur    st_mtime:*S   ModifyTime
>      c     Epoch         adddur    st_ctime:*S   ChgStsTime
>
>       ** adjust timestamps for timezone:
>      c                   eval      timezone = GetTimeZone
>      c                   if        tzDir = '-'
>      c                   subdur    tzHour:*H     AccessTime
>      c                   subdur    tzHour:*H     ModifyTime
>      c                   subdur    tzHour:*H     ChgStsTime
>      c                   else
>      c                   adddur    tzHour:*H     AccessTime
>      c                   adddur    tzHour:*H     ModifyTime
>      c                   adddur    tzHour:*H     ChgStsTime
>      c                   endif
>
>      C* display the relevant times:
>      c                   move      AccessTime    charTS
>      c                   eval      Msg = 'Last Access ' + charTS
>      c                   dsply                   Msg
>
>      c                   move      ModifyTime    charTS
>      c                   eval      Msg = 'Last Modified ' + charTS
>      c                   dsply                   Msg
>
>      c                   move      ChgStsTime    charTS
>      c                   eval      Msg = 'Status Changed ' + charTS
>      c                   dsply                   Msg
>
>      c                   dealloc                 p_statds
>      c                   eval      *inlr = *on
>
>
>      P*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>      P*  This gets the offset from Universal Coordinated Time (UTC)
>      P*    from the system value QUTCOFFSET
>      P*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>      P GetTimeZone     B
>      D GetTimeZone     PI             5A
>      D peRcvVar        S              1A   DIM(100)
>      D peRVarLen       S             10I 0
>      D peNumVals       S             10I 0
>      D peSysValNm      S             10A
>      D p_Offset        S               *
>      D wkOffset        S             10I 0 BASED(p_Offset)
>      D p_SV            S               *
>      D dsSV            ds                  BASED(p_SV)
>      D   dsSVSysVal                  10A
>      D   dsSVDtaTyp                   1A
>      D   dsSVDtaSts                   1A
>      D   dsSVDtaLen                  10I 0
>      D   dsSVData                     5A
>      D dsErrCode       DS
>      D  dsBytesPrv             1      4B 0 INZ(256)
>      D  dsBytesAvl             5      8B 0 INZ(0)
>      D  dsExcpID               9     15
>      D  dsReserved            16     16
>      D  dsExcpData            17    256
>      C                   CALL      'QWCRSVAL'
99
>      C                   PARM                    peRcvVar
>      C                   PARM      100           peRVarLen
>      c                   PARM      1             peNumVals
>      c                   PARM      'QUTCOFFSET'  peSysValNm
>      c                   PARM                    dsErrCode
>      c                   if        dsBytesAvl > 0  or  *IN99 = *On
>      c                   return    *blanks
>      c                   endif
>      c                   eval      p_Offset = %addr(peRcvVar(5))
>      c                   eval      p_SV = %addr(peRcvVar(wkOffset+1))
>      c                   return    dsSVData
>      P                 E
>
> Rob Berendt
> --
> "They that can give up essential liberty to obtain a little temporary
> safety deserve neither liberty nor safety."
> Benjamin Franklin


--__--__--

Message: 2
Date: Mon, 15 Apr 2002 19:03:34 -0500 (CDT)
From: Scott Klement <klemscot@klements.com>
To: "'rpg400-l@midrange.com'" <rpg400-l@midrange.com>
Subject: RE: STDIN, STDOUT, STDERR in RPG
Reply-To: rpg400-l@midrange.com


On Tue, 16 Apr 2002, Peter Connell wrote:
>
> James, Scott, Jim.
> Thanks. I'm aware that OS like Unix and the C (or C++) language provide
an
> operator that permits the output of one program to be easily piped to
> another but the challenge is to prove that this can be achieved
effectively
> on OS/400 since the analagous facility to override stdout appears to be
> ignored when the QtmhWrStout Api is used to generate stdout.
>

Again, I'm not familiar with that API or what it does.   But if your goal
is to simply pipe data on the iSeries from one program to another, that
CAN be done...  at least, within QSHELL it can.

> Populating stdout from within an RPGLE cgi program (or C) is a relatively
> simple matter using the built-in Apis or functions that the language
> provides since this is how all CGI programs are written. I suspect that
> James's explanation that stdout does not actually exist as a file may be
the
> reason that the concept of subsequently opening it is not possible.
>

Yeah, but I thought you were asking how to read stdin, not stdout...
Where do you get the input data for your CGI script when you use the
POST method?  i.e., if someone passed you a form, where would you get
the data from the web browser?   On Unix systems, you get that from stdin
with the POST method (or from an environment variable with the GET method,
but the env var is limited in size, so we always use POST)


> The piping technique would therefore appear be a mechanism the merely
primes
> the OS before making a program call so that it bypasses the usual low
level
> process that generates stdout and instead passes the output stream to a
> redirected actual file that is available for read.

Right, if you do redirecting, the shell will open a new STDIN/STDOUT for
you to go to a pipe, or a file, or whatever.   You don't open it yourself
in other environments.

Likewise, if you run your RPG program from QSHELL, you could do the same
thing, since QSHELL opens the pipe/file/whatever for you.

>
> I'm inclined to agree that this cannot be done (unless emulating popen()
and
> pclose() is worth a look.)
>

If I understand you correctly, and you just want to pipe the output of
some program to an RPG program for further processing, and you're using
QSHELL, it can be done.   You just use descriptors 0, & 1.

Here's a sample:

      * This rather silly program reads STDIN and translates all of the
      * spaces to periods, then writes it to STDOUT.
      *
      * You need to run this from QSHELL for it to be useful:
      *          /qsys.lib/yourlib.lib/this.pgm

     H BNDDIR('QC2LE') DFTACTGRP(*NO)

     D read            PR            10I 0 extproc('read')
     D  fd                           10I 0 value
     D  buf                            *   value
     D  len                          10I 0 value

     D write           PR            10I 0 extproc('write')
     D  fd                           10I 0 value
     D  buf                            *   value
     D  size                         10I 0 value

     D data            S             80A
     D len             S             10I 0

     c                   eval      len = read(0: %addr(data): %size(data))
     c                   dow       len > 0
     c     ' ':'.'       xlate     data          data
     c                   callp     write(1: %addr(data): len)
     c                   eval      len = read(0: %addr(data): %size(data))
     c                   enddo

     c                   eval      *inlr = *on


To run this, you need to run it from QSHELL.  Here's how I did it:

1) Type STRQSH

2) At the QSHELL prompt, I typed:

echo "I sure wish I had periods in this text!" |
/qsys.lib/mylib.lib/test.pgm

(that should all be one line, if it gets wrapped)


And the result looked like this:

   I.sure.wish.I.had.periods.in.this.text!


Hope that helps...




--__--__--

Message: 3
Date: Mon, 15 Apr 2002 18:07:32 -0600
From: "David Morris" <David.Morris@plumcreek.com>
To: <rpg400-l@midrange.com>
Subject: RE: STDIN, STDOUT, STDERR in RPG
Reply-To: rpg400-l@midrange.com

Scott,

I never got the original to this message so it may not be an
exact quote.  Debug may appear to be one of those programs.
Starting debug opens and never releases 0, 1, or 3. That was
what got me started on this, particularly because when you do
have problems debug is one way to assess the problem. It
appears that debug may not be effective because of its
behavior.

Thanks,

David Morris

From: Scott Klement [mailto:klemscot@klements.com]
Sent: Sunday, April 14, 2002 4:19 PM
To: rpg400-l@midrange.com
Subject: Re: STDIN, STDOUT, STDERR in RPG



In Unix, 0=stdin, 1=stdout, 2=stderr.   That's a standard.

...Of course, if you ran that same program from within a process
that already had those streams open, it'd cause problems.


--__--__--

Message: 4
Date: Mon, 15 Apr 2002 18:09:48 -0600 (MDT)
From: James Rich <james@eaerich.com>
To: "'rpg400-l@midrange.com'" <rpg400-l@midrange.com>
Subject: RE: STDIN, STDOUT, STDERR in RPG
Reply-To: rpg400-l@midrange.com

On Tue, 16 Apr 2002, Peter Connell wrote:

> James, Scott, Jim.
> Thanks. I'm aware that OS like Unix and the C (or C++) language provide
an
> operator that permits the output of one program to be easily piped to
> another but the challenge is to prove that this can be achieved
effectively
> on OS/400 since the analagous facility to override stdout appears to be
> ignored when the QtmhWrStout Api is used to generate stdout.

Is it ignored?  I don't know if it is, but here is a test:

1. write an RPG program that writes "Hello World" to stdout.
2. From QSH invoke your program and pipe the output to grep like this:
             hellopgm | grep ello
3. Again from QSH invoke your program and redirect the output to a file:
             hellopgm > /tmp/hellooutput

All this should work.  Why?  because QSH will tell the OS how the various
stdins and stdouts should be set up.  So your goal of having one program
write to stdout and another program read it can be done if they are
invoked in this way using QSH.  But the first program cannot be called and
then another program read the first's stdout later, because the stdout is
not stored anywhere.  Use QSH and make life easy.

If you really do want to delay invoking the second program until after the
first has started then just use a temporary file.  If you were using
stdout before then use a file on the IFS since it won't require you to
make any significant code changes.  It probably won't perform nearly as
well but it will get the job done.

> Populating stdout from within an RPGLE cgi program (or C) is a relatively
> simple matter using the built-in Apis or functions that the language
> provides since this is how all CGI programs are written. I suspect that

Again, I think it is misleading to describe writing to stdout as
populating it.  stdout is never populated.  If something (like the screen)
is connected to stdout then that something will receive whatever is
written to stdout.  But if nothing is connected then anything written to
stdout just disappears.  IOW, the contents of stdout are always nothing.

However, stdout (AFAIK) is always connected to something, that something
usually being the screen.

> The piping technique would therefore appear be a mechanism the merely
primes
> the OS before making a program call so that it bypasses the usual low
level
> process that generates stdout and instead passes the output stream to a
> redirected actual file that is available for read.

Not quite.  stdout always exists.  A pipe is an kernel level device that
connects one stdout to another stdin.  A pipe does not create an actual
file.

James Rich
james@eaerich.com


--__--__--

Message: 5
From: "Ren Fu Ping" <fupingren@yeah.net>
To: <rpg400-l@midrange.com>
Subject: Re: Error Message (WSID)
Date: Tue, 16 Apr 2002 09:06:18 +0800
Reply-To: rpg400-l@midrange.com

Dear All,
Thanks Very Much, I solve this problem yestday night under your help. but a
=
nother issue is as the follow:
RPG1:
***************************************************
ISDS        SDS
I                                      244 253 WSID
I                                      254 263 #USER
I                                      199 2000#UYEAR
I                                      276 2810#UDATE
I                                     *PROGRAM PGM
***************************************************
I define system data structure in SDS, and WSID and USER position as above,
=
 I put this two variable into display file and printer file in RPG2, when r
=
unning interactive, WSID and USER can get his result on printer file. but r
=
unning in batch, WSID variable changed with 'INVX01', this maybe my first R
=
PG name, maybe my batch job name. mentioned here, My CL don't use and pass
=
this two parameter. my consideration is that the two variable is system def
=
ine and needn't control by user.

Many thanks!
Ping



----- Original Message -----
From: <rob@dekko.com>
To: <rpg400-l@midrange.com>
Sent: Tuesday, April 16, 2002 1:45 AM
Subject: Re: Error Message


> This is a multipart message in MIME format.
> --
> [ Picked text/plain from multipart/alternative ]
> How do you like the following:
> http://faq.midrange.com/data/cache/197.html
>
> Rob Berendt
> --
> "They that can give up essential liberty to obtain a little temporary
> safety deserve neither liberty nor safety."
> Benjamin Franklin
>
>
>
>
> "John Taylor" <jtaylor@rpg2java.com>
> Sent by: rpg400-l-admin@midrange.com
> 04/15/2002 10:52 AM
> Please respond to rpg400-l
>
>
>         To:     <rpg400-l@midrange.com>
>         cc:
>         Fax to:
>         Subject:        Re: Error Message
>
>
>
> Rob Berendt wrote:
>
> > I didn't think it went into using a command to get around the 15,5
> > limitation imposed by a CALL used via SBMJOB.
>
>
> Well, the problem is certainly thoroughly explained, and there is an
> example
> of creating a CMD object, but the example uses  a *CHAR parameter, instea
=
d
> of *DEC. I assume (it's Buck's example) that it was done this way because
> the vast majority of the problems are caused by the more complex rules of
> the *CHAR.
>
> It'd be nice if you took a minute to add the *DEC example that you sent t
=
o
> Ping.  Because it focuses only on the issue with numerics, it's much more
> concise, and would be a valuable addition to the FAQ.
>
>
> Regards,
>
> John Taylor
>
>
>
> _______________________________________________
> This is the RPG programming on the AS400 / iSeries (RPG400-L) mailing lis
=
t
> To post a message email: RPG400-L@midrange.com
> To subscribe, unsubscribe, or change list options,
> visit: http://lists.midrange.com/cgi-bin/listinfo/rpg400-l
> or email: RPG400-L-request@midrange.com
> Before posting, please take a moment to review the archives
> at http://archive.midrange.com/rpg400-l.
>
>
>
> _______________________________________________
> This is the RPG programming on the AS400 / iSeries (RPG400-L) mailing lis
=
t
> To post a message email: RPG400-L@midrange.com
> To subscribe, unsubscribe, or change list options,
> visit: http://lists.midrange.com/cgi-bin/listinfo/rpg400-l
> or email: RPG400-L-request@midrange.com
> Before posting, please take a moment to review the archives
> at http://archive.midrange.com/rpg400-l.
>

--__--__--

Message: 6
From: "Jon Paris" <Jon.Paris@Partner400.com>
To: <rpg400-l@midrange.com>
Subject: STDIN, STDOUT, STDERR in RPG
Date: Mon, 15 Apr 2002 21:10:14 -0400
Reply-To: rpg400-l@midrange.com

 >> but the challenge is to prove that this can be achieved effectively on
OS/400 since the analogous facility to override stdout appears to be
ignored
when the QtmhWrStout Api is used to generate stdout.

Maybe I missed it, but I wish I'd known earlier that that was what you were
trying to do.  For some reason the QtmhWrStout Api does not allow an
override.  This is something that changed in ? (V4R1?) - prior to that you
could override but for some reason (efficiency?) it is no longer supported.
I found this out after I contacted Rochester for help after struggling to
get the overrides working to help me debug some problems I was having with
a
CGI program.  The response came from the developer of the API so I believe
it to be a definitive answer.

Jon Paris
Partner400



--__--__--

Message: 7
From: Peter Connell <Peter.Connell@baycorpadvantage.com>
To: "'rpg400-l@midrange.com'" <rpg400-l@midrange.com>
Subject: RE: STDIN, STDOUT, STDERR in RPG
Date: Tue, 16 Apr 2002 13:10:40 +1200
Reply-To: rpg400-l@midrange.com

Scott,
I am concerned with the CGI response that is generated for an HTTP request.
If necessary STDIN or QUERY_STRING will already have been processed before
performing the process that generates STDOUT.
I already use QShell on the HTTP server for it's ability to pipe but only
for infrequent requests where the apparent overhead of launching a new
thread each time Qshell is required is tolerable. The solution I have sough
=
t
must apply to every cgi request that the server receives so I can't go
wrapping my cgi program (or IBMs DB2WWW) up in a Qshell wrapper.

-----Original Message-----
From: Scott Klement [mailto:klemscot@klements.com]
Sent: Tuesday, April 16, 2002 12:04 PM
To: 'rpg400-l@midrange.com'
Subject: RE: STDIN, STDOUT, STDERR in RPG



On Tue, 16 Apr 2002, Peter Connell wrote:
>
> James, Scott, Jim.
> Thanks. I'm aware that OS like Unix and the C (or C++) language provide a
=
n
> operator that permits the output of one program to be easily piped to
> another but the challenge is to prove that this can be achieved
effectively
> on OS/400 since the analagous facility to override stdout appears to be
> ignored when the QtmhWrStout Api is used to generate stdout.
>

Again, I'm not familiar with that API or what it does.   But if your goal
is to simply pipe data on the iSeries from one program to another, that
CAN be done...  at least, within QSHELL it can.

> Populating stdout from within an RPGLE cgi program (or C) is a relatively
> simple matter using the built-in Apis or functions that the language
> provides since this is how all CGI programs are written. I suspect that
> James's explanation that stdout does not actually exist as a file may be
the
> reason that the concept of subsequently opening it is not possible.
>

Yeah, but I thought you were asking how to read stdin, not stdout...
Where do you get the input data for your CGI script when you use the
POST method?  i.e., if someone passed you a form, where would you get
the data from the web browser?   On Unix systems, you get that from stdin
with the POST method (or from an environment variable with the GET method,
but the env var is limited in size, so we always use POST)


> The piping technique would therefore appear be a mechanism the merely
primes
> the OS before making a program call so that it bypasses the usual low
level
> process that generates stdout and instead passes the output stream to a
> redirected actual file that is available for read.

Right, if you do redirecting, the shell will open a new STDIN/STDOUT for
you to go to a pipe, or a file, or whatever.   You don't open it yourself
in other environments.

Likewise, if you run your RPG program from QSHELL, you could do the same
thing, since QSHELL opens the pipe/file/whatever for you.

>
> I'm inclined to agree that this cannot be done (unless emulating popen()
and
> pclose() is worth a look.)
>

If I understand you correctly, and you just want to pipe the output of
some program to an RPG program for further processing, and you're using
QSHELL, it can be done.   You just use descriptors 0, & 1.

Here's a sample:

      * This rather silly program reads STDIN and translates all of the
      * spaces to periods, then writes it to STDOUT.
      *
      * You need to run this from QSHELL for it to be useful:
      *          /qsys.lib/yourlib.lib/this.pgm

     H BNDDIR('QC2LE') DFTACTGRP(*NO)

     D read            PR            10I 0 extproc('read')
     D  fd                           10I 0 value
     D  buf                            *   value
     D  len                          10I 0 value

     D write           PR            10I 0 extproc('write')
     D  fd                           10I 0 value
     D  buf                            *   value
     D  size                         10I 0 value

     D data            S             80A
     D len             S             10I 0

     c                   eval      len =3D read(0: %addr(data): %size(data)
=
)
     c                   dow       len > 0
     c     ' ':'.'       xlate     data          data
     c                   callp     write(1: %addr(data): len)
     c                   eval      len =3D read(0: %addr(data): %size(data)
=
)
     c                   enddo

     c                   eval      *inlr =3D *on


To run this, you need to run it from QSHELL.  Here's how I did it:

1) Type STRQSH

2) At the QSHELL prompt, I typed:

echo "I sure wish I had periods in this text!" |
/qsys.lib/mylib.lib/test.pgm

(that should all be one line, if it gets wrapped)


And the result looked like this:

   I.sure.wish.I.had.periods.in.this.text!


Hope that helps...




As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

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.