WRKJOBS

page d'accueil
Boite à outils

Cette page a été mise à jour le 02 octobre 2009
Contact

Welcome page
Tools box

Versionning 

last version : How to upload to my 400

CHGPFM FILE(QPGMSRC) MBR(WRKJOBFM ) SRCTYPE(DSPF ) EXPDATE(*NONE) SHARE(*NO) TEXT('work with jobs, improved ') 
CHGPFM FILE(QPGMSRC) MBR(WRKJOBR ) SRCTYPE(SQLRPGLE ) EXPDATE(*NONE) SHARE(*NO) TEXT('work with jobs, improved ')
CHGPFM FILE(QPGMSRC) MBR(WRKJOBS ) SRCTYPE(CMD ) EXPDATE(*NONE) SHARE(*NO) TEXT('work with jobs, improved ')
CHGPFM FILE(QPGMSRC) MBR(WRKJOBHP ) SRCTYPE(PNLGRP ) EXPDATE(*NONE) SHARE(*NO) TEXT('work with jobs, improved ')

CRTPNLGRP PNLGRP(WRKJOBHP) SRCFILE(QPGMSRC)
CRTDSPF FILE(WRKJOBFM) SRCFILE(QPGMSRC) SRCMBR(WRKJOBFM) RSTDSP(*YES) REPLACE(*YES)
CRTSQLRPGI OBJ(WRKJOBR) SRCFILE(JPLTOOLS) OBJTYPE(*MODULE) OPTION(*NOSEQSRC *XREF *SECLVL) DBGVIEW(*SOURCE) TGTRLS(V5R3M0)
CRTPGM PGM(WRKJOBR) BNDDIR(QC2LE) ACTGRP(JPLTOOLS) TGTRLS(V5R3M0)
CRTCMD CMD(WRKJOBS) PGM(*LIBL/WRKJOBR) SRCFILE(QPGMSRC) SRCMBR(WRKJOBS) REPLACE(*YES)

list of dormant program, for option 50 

CHGPFM FILE(JPLTOOLS) MBR(SLPPGM) SRCTYPE(CMD) TEXT('List of sleeping programs') EXPDATE(*NONE) SHARE(*NO) 
CHGPFM FILE(JPLTOOLS) MBR(SLPPGMFM) SRCTYPE(DSPF) TEXT('List of sleeping programs') EXPDATE(*NONE) SHARE(*NO)
CHGPFM FILE(JPLTOOLS) MBR(SLPPGMR) SRCTYPE(RPGLE) TEXT('List of sleeping programs') EXPDATE(*NONE) SHARE(*NO)

CRTCMD CMD(SLPPGM) PGM(SLPPGMR) SRCFILE(JPLTOOLS)
CRTDSPF FILE(SLPPGMFM) SRCFILE(JPLTOOLS) RSTDSP(*YES)
CRTRPGMOD MODULE(SLPPGMR) SRCFILE(JPLTOOLS) OPTION(*NODEBUGIO *SRCSTMT *SHOWCPY *SECLVL *EXPDDS)
DBGVIEW(*ALL) REPLACE(*YES) TGTRLS(V5R3M0) ENBPFRCOL(*FULL)
CRTPGM PGM(SLPPGMR) BNDDIR(QC2LE JPLTOOLS) ACTGRP(*NEW) OPTION(*DUPPROC) TGTRLS(V5R3M0)
Usage :
Screen shows first with *ALL but Jobname = QZDA* : first usage is to work with ODBC jobs.

The first 3 filter fields are for calling the API, they are wilcards values (IE terminated with a *). A * is added at end if missing

The next fields are masks for filtering when reading list of jobs : do not need to add a * at end. A * at end is removed if any.

For all fields, *BLANK = *ALL = *. So, just clear a filter-field witch is not in the filter target.

To sort a column, let the cursor on the column then press F16, such as in WRKACTJOB

Options :

  •  7 runs a WRKACTJOB JOB(jobname). The idea is to provide a way to answer a message. I don't know how to (programaticaly) show a message a job is waiting for a answer, but WRKACTJOB knows. And I know how to run WRKACTJOB. This runs perfectly but when jobname is like QZDASOINIT, all jobs have the same name. In this case, note the job number before runnning option 7, then (when under wrkactjob) F11 two times

  • all other runs WRKJOB. Well know options are runned directly, other runs option 5 :
    • when option = 1 then *STSA 
    • when option = 2 then *DFNA 
    • when option = 3 then *RUNA 
    • when option = 4 then *SPLA 
    • when option = 5 then *SELECT 
    • when option =10 then *JOBLOG 
    • when option =11 then *PGMSTK 
    • when option =12 then *JOBLCK 
    • when option =13 then *LIBL
    • when option =14 then *OPNF 
    • when option =15 then *FILOVR 
    • when option =16 then *CMTCTL 
    • when option =17 then *CMNSTS 
    • when option =18 then *ACTGRP 
    • when option =19 then *MUTEX 
    • when option =20 then *THREAD 
    • when option =21 then *MLBA 
    • other then *SELECT 

known issues

  • crash when jobname not a name (like *ALL*), correction coming soon

screen snapshot

WRKJOBR B 19/01/07 18:54:11 M170PUB1 JPLTOOLS jp jpltools 195 Lines
Filter with Work with jobs
S JobName UserName JobNbr Cur User IP address sbs Status
*ALL *ALL *ALL JPLTOOLS *ALL *ALL *ALL
*ACTIVE Limit to
Option : same as WRKJOB 4=spool 10=joblog ... 8888 Lines
QPADEV000S JPLTOOLS 259564 JPLTOOLS 181.56.171.44 QINTER RUN
QPWFSERVSO QUSER 259230 JPLTOOLS 181.56.171.44 QSERVER
QZRCSRVS QUSER 259317 JPLTOOLS 181.56.171.44 QUSRWRK TIMW
QZSCSRVS QUSER 259474 JPLTOOLS 181.56.171.44 QUSRWRK TIMW












F3=Exit F12=Cancel F5=Refresh F16=Sort

WRKJOBR nuggets

wrkjobr is based on well known apis QUS*US, QUSLJOB and QUSRJOBI. OK, no gold here. But I have discover a pretty way when using the user space. After loading the user space, I have declared it as ... a working variable. How ? With a pointer ! The blending of user space and pointer produce a code very clear. code excerpt  :

start with creating a user space in qtemp (no secret)

quscrtus ( Usrspc// get memory for array .../...

then, call the list job API : (no more secret)

qusljob(usrspc : 'JOBL0100' : qjob : cbstatus :errcode )

now, I have a based data structure named LAH (for List Api Header). (it's here the sorcerer had worked)
I give to the pointer the address of the user space. Clearly, I use LAH as a mask to format & read the user space 

qusptrus(usrspc : pLAH);

And Voila ! my LAH work field is now "containing" the user space data : under STRDBG, i can run EVAL LAH
Now, I can use the list as if it is in an array (in fact, it's really an array)

for iJob= 0 to lah.count - 1;
pJobL0100 = pLAH + LAH.Data_Offset + iJob * LAH.entry_Size ;
// Now, the DS JOBL0100 contains one of the jobs listed by QUSLJOB
rtvjoba(jobi0200:%size(jobi0200):'JOBI0200':'*INT':jobl0100.Internal_ID:errcode);
.../...
endfor;

Applause the guru ! (yes i'm very proud of myself. it's not politically correct, but when I am alone in front of my mirror, no one comes to antagonize me, even my reflection, it's to say!)

it's not the end ! there is an other nugget

I have implemented the "F16=sort" with the C-Sort-Array procedure :

For details search the web about QSORT, there are many articles on (first target : SystemINews)
But, to resume, QSORT need

Below, SortArray is the array, and SortBy is the function that sorts 2 elements

some data definitions

// Prototype for qsort - which should be in a /COPY member
D C_QSort Pr ExtProc('qsort')
D DataToSort * value
D Elements 10U 0 Value
D Size 10U 0 Value
D SortFunct * ProcPtr Value

d SortElement ds
d qualified
d based(pSortElement)
d JOBNAME like(sbJOBNAME )
d USERNAME like(sbUSERNAME)
d JOBNBR like(sbJOBNBR )
d CURUSER like(sbCURUSER )
d IP like(sbIP )
d sts like(sbsts )
d SBS like(sbSBS )
d SortArray s 65535 based(pSortArray)
d SortAryNbr s 10i 0 inz(0)
d SortAryPos s 10i 0 inz(0)
d SortAryLen s 10i 0 inz(0)
d SortEltlen s 10i 0 inz(%size(SortElement))
// Constants used by qsort sequencing routines
D High C 1
D Low C -1
D Equal C 0
// Prototypes for the sequencing routines used in the program
D SortBySbsJob Pr 10I 0
D Element1 Likeds(SortElement)
D Element2 Likeds(SortElement)
d SortBy s * procptr

how to load an element :

// add an element to sort array 
sortarylen+= sorteltlen;
sortAryNbr+=1;
pSortArray=%realloc(pSortArray:SortAryLen);
// prepare last element for update
pSortElement = pSortArray + SortaryLen - sorteltlen ;
// update the element
sortelement.jobname= JOBI0600.Job_name ;
sortelement.username= JOBI0600.User_name ;
sortelement.jobnbr = JOBI0600.Job_number ;
sortelement.curuser = JOBI0600.Current_user ;
sortelement.ip = JOBI0600.Client_IP ;
sortelement.sts = JOBI0200.actjob_status;

how to sort the elements

SortBy = %Paddr(SortBySbsJob); 
C_QSort(PSortArray:SortAryNbr:SortEltLen:SortBy);

how to unload elements

SortAryPos = 1;
// set pointer to first job
iJob=0;
// get one job
if sortARyPos > SortAryNbr;
// done
iter;
endif;
// * load one line
pSortElement = pSortArray + ( SortaryPos - 1 ) * sortEltLen ;
sbjobname = sortelement.jobname ;
sbusername = sortelement.username ;
sbjobnbr = sortelement.jobnbr ;
sbcuruser = sortelement.curuser ;
sbip = sortelement.ip ;
sbsts = sortelement.sts ;
sbsbs = sortelement.sbs ;

And the call-back sort procedure for one element :

P SortBySbsJob b 
D PI 10I 0
D Element1 Likeds(SortElement)
D Element2 Likeds(SortElement)
/FREE
SELECT;
// level 1 sort : by sbs
WHEN Element1.sbs > Element2.sbs ;
RETURN High;
WHEN Element1.sbs < Element2.sbs ;
RETURN Low ;
// next level : by name
WHEN Element1.jobname> Element2.jobname;
RETURN High;
WHEN Element1.jobname< Element2.jobname;
RETURN Low ;
OTHER;
RETURN Equal;
ENDSL;
BEGSR *PSSR ;
DUMP ;
ENDSR ;
/end-free
P e

RPGLE + C runtime library, the dream team !

The source code is provided as an open source tool under the GNU General Public License, version 2.  In summary, this license specifies:

By clicking the download link you acknowledge and agree to the terms of the license.

Download the (zipped) SAVF containing the JPLTOOLS : the source file, the message file, the bnddir

THIS TOOLBOX IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROVIDER OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS TOOLBOX, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.