ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

How to view "Errno" global indicator within STRDBG?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to view "Errno" global indicator within STRDBG?

    Hello,

    The open() api documentation, located here, details that upon error it returns -1 but it also populates "errno" with a specific error ID.

    I am within STRDBG via;

    1: STRSRVJOB JOB(700475/OVERNIGHT/MYJOB)
    2: STRDBG PGM(MYPROG) UPDPROD(*YES) OPMSRC(*NO) SRVPGM(SVRPGM1)
    3: Set break at point MYPROG calls internal "BIF" (contained within SVRPGM1)
    4: Use Shift+F10 to step into SVRPGM
    5: Set break point in SVRPGM to after the open() api is used

    At this point I can see the return value from the open() api is -1, so I tried eval errno and it stated the value didn't exist

    Can anyone advise how I view "errno" from within STRDBG? Google isn't being very helpful.

    Many Thanks,
    Ryan

  • #2
    This is how the open API is used:

    MYPROG executes a PR called OpenIFSFile;

    Code:
    0617.00     MyFileHandle = OpenIFSFile(IFSPath:    
    0618.00                               '*READONLY':
    0619.00                                     '*NO':
    0620.00                                     '*NO');
    0621.00                                            
    0622.00     // If file not openeded error and end  
    0623.00     If MyFileHandle < 0;                  
    xxx.xx     ... do some rejecting ...
    OpenIFSFile is located in a service program (SVRPGM1), part of the PR does the following; (Flags is set to O_RDONLY)

    Code:
    0137.00     // Now try to Open the file              
    0138.00     ReturnValue = OpenStream(FileName: Flags);
    0139.00                                              
    0140.00     Return ReturnValue;
    "OpenStream" is defined within a "QRPGLEREF" source file with the following;

    Code:
    0184.00 D***************************************************************/
    0185.00 D* Prototype for Calling Open() API                              
    0186.00 D***************************************************************/
    0187.00 D OpenStream      pr            10i 0 extproc('open')            
    0188.00 D  xFilename                      *   value options(*string)    
    0189.00 D  xOpenflags                   10i 0 value                      
    0190.00 D  xMode                        10u 0 value options(*nopass)    
    0191.00 D  xCodepage                    10u 0 value options(*nopass)

    I don't really understand why there's loads of definitions in different source files and stuff - gets very confusing for us noobs.

    Comment


    • #3
      First of all in order to see errno you must have it in your program. Like so:

      Code:
      Dcl-pr  get_errno  Pointer   ExtProc('__errno');  // Note _double_ underscore
      
      Dcl-s  c_errno  Int(10)  based(perrno); 
       If MyFileHandle < 0;     perrno = get_errno; // Now the errno value is visible
      You can also use this to get the error text associated with the errno:
      Code:
        Dcl-pr  strerror  pointer ExtProc('strerror');   errno  Int(10)  Value;  Dcl-s  errorString  Char(100)  Based(perrorString);  perrorString = strerror(c_errno);
      Sorry about the formatting - this idiot software just will not format for me today.

      Comment


      • #4
        ... I don't really understand why there's loads of definitions in different source files and stuff - gets very confusing for us noobs.
        Not wishing to sound rude but it is hard for us to help you when a) You don't say if you are new to RPG or b) New to using C APIs. It would also help to know where you are getting your base code ideas from because your call to the open() function can never work as the only parameter that might be correct is the first one. There are no RPG reserved constants *READONLY or *NO.

        An open() would normally look more like this:
        Code:
        open (?'/Partner400/XMLStuff/Test1.xml'
              : O_WRONLY + O_CREAT + O_TRUNC  
              : S_IRUSR + S_IWUSR + S_IRGRP;
        There are many excellent tutorials on using C APIs from RPG - I've written a few myself. The definitive one for the IFS is Scott Klement'e ebook - although it may be missing more recent changes. Check his website for details.
        Last edited by JonBoy; December 5, 2017, 11:53 AM.

        Comment


        • #5
          Jon, I'm sorry but the software's action in reply to your answer is hilarious. You called it "this idiot software", and it's marked your next post as unapproved just to prove that AI is alive and well.
          Regards

          Kit
          http://www.ecofitonline.com
          DeskfIT - ChangefIT - XrefIT
          ___________________________________
          There are only 3 kinds of people -
          Those that can count and those that can't.

          Comment


          • #6
            Originally posted by JonBoy View Post
            It would also help to know where you are getting your base code ideas from because your call to the open() function can never work as the only parameter that might be correct is the first one. There are no RPG reserved constants *READONLY or *NO.
            The OP does say that the OpenIFSFile is in a service program. It seems logical to assume it accepts certain parameters and works out the necessary Open() flags from those.

            Comment


            • #7
              Hi,

              You're not being rude, I probably should've mentioned my experience - I have no official programming training.

              I am in a support role, I showed some interest/aptitude in programming and so a colleague showed me how to access source files, gave me some basic concepts and from there I just kind of taught myself via google, exploring, reading programs and just asking people.

              I only started actually doing changes within production, in Jan and started out with said colleague basically showing me what the outcome of the error was and then I'd have to go and find where in the program the error occurred - with her assisting me if I needed it.
              Now I'm at a stage where I can locate bugs and fix them myself, albeit nothing incredibly complex and I've written some programs, but I can't write them off the top of my head - I think up a concept, then use google/existing programs to get me to where I want to go.

              Apologies for the life story, but there you have it.

              I struggle when it comes to APIs, specifically setting up the data structures and stuff to receive the data from them and also prototypes, where they are defined in service programs.

              I.e what I'm looking at here;

              You have something that's used in a RPGLE program
              But the actual code for what that does is within another RPGLE program
              And this is also defined in a "QRPGLEREF" file!? Is that normal?

              Regarding this response;

              Code:
               Dcl-pr  get_errno  Pointer   ExtProc('__errno');  // Note _double_ underscore  
              Dcl-s  c_errno  Int(10)  based(perrno);  
               If MyFileHandle < 0;    
               perrno = get_errno; // Now the errno value is visible
              This suggests defining it within the program, will errno will be visible there? Because the "open" functionality is defined in the QRPGLEREF file which I guess is used in the service program, so should I define it in the program or service program? Or is it visible everywhere because it's a "global indicator"?
              Also do I need an endif within the code?

              Apologies if the questions seem stupid.

              Regards,
              Ryan

              Comment


              • #8
                Originally posted by kitvb1 View Post
                Jon, I'm sorry but the software's action in reply to your answer is hilarious. You called it "this idiot software", and it's marked your next post as unapproved just to prove that AI is alive and well.
                No worries Kit - but I have to say the way this software behaves since the last couple of updates means I don't visit as often as I used to - it drives me nuts.

                Comment


                • kitvb1
                  kitvb1 commented
                  Editing a comment
                  Me too Jon, I still have to approve each of my own posts
                  This is also the reason why I have not upgraded the EcofIT support portal.

              • #9
                Originally posted by RDKells View Post
                Hi,

                I.e what I'm looking at here;

                You have something that's used in a RPGLE program
                But the actual code for what that does is within another RPGLE program (*1)
                And this is also defined in a "QRPGLEREF" file!? Is that normal? (*2)

                <snip>

                This suggests defining it within the program, will errno will be visible there? Because the "open" functionality is defined in the QRPGLEREF file which I guess is used in the service program, so should I define it in the program or service program? (*3) Or is it visible everywhere because it's a "global indicator"? (*4)
                Also do I need an endif within the code? (*5)

                Apologies if the questions seem stupid.
                No stupid questions Ryan - and welcome to the club - great to hear that you have taken the initiative to move ahead.

                First of all be cautious of using the term API when talking about procedures written in RPG. API tends to have a more specific meaning in the IBM i world - it normally relates to IBM supplied capabilities. You can find details of most via this page https://www.ibm.com/support/knowledg...der/finder.htm

                What you appear to be talking about are subprocedures which are in-house written "APIs". So in your statement *1 above you are correct in that the code is elsewhere but the term "program" is technically incorrect. You start with source code (that is the RPG logic that you write) which is normally kept in a source physical file with a name like QRPGLESRC (which is the default). when you compile with CRTBNDRPG (PDM option 14 if you are using PDM) you are actually running CRTRPGMOD and the CRTPGM under the covers. The first step creates a *MODULE object and the second takes that module and creates a *PGM object which is the executable unit. In the case of subprocedures the CRTRPGMOD is run by itself (PDM 15) and then the module is bound into a Service Program - normally along with other modules which provide associated capabilities - via CRTSRVPGM.

                Because the RPG compiler does not know about "your" additions to the language (i.e. the functions available in the Service Program) it has to be told about them. That is the purpose of prototypes - which are probably what you are referring to in *2 when you mention QRPGLEREF. Is that normal? Yes it is normal (indeed compulsory) to include prototypes but the name is one that was made up in your shop and probably not the best choice because any object name that starts with a Q is implied to be an IBM related object. Included in your programs will be a /COPY directive that references the appropriate source member in that file.

                In order for the linkage to the Service Program to be picked up automatically there would normally be a binding directory entry in your RPG program. This would appear in the H spec (or Ctl-Opt in modern RPG). If you don't have that you're going to have to tell me how you compile your programs.

                With regard to your other questions.

                *3 Normally prototypes for errno and similar functions would be included in a file such as your QRPGLEREF - in a member with a name such as FUNCTIONS_H - this "H" in some ways is inherited from the C language where prototypes are known as H(eader) files. The service programs that contain the open() function are supplied by IBM and are automatically linked to the program during the CRTPGM stage.

                *4 The visibility is visible anywhere within your program. If another program needs to use it, it must also include the prototypes and make the function call to __errno. The visibility _is_ global - but from the Service Program containing it. It is hard to explain as your learning to-date has skipped a number of building blocks.

                *5 Yes - always. Some languages (PHP for example) allow for a short-form If that does not require an end scope marker - but RPG is not one of them.

                Right now there is a fire sale going on at MC Press and the two books that most colleges use to teach RPG and the IBM i are both heavily discounted right now.

                This one will teach you RPG and how to build programs and Service Programs. https://www.mc-store.com/collections...nt=19020080263 - I strongly suggest you read this one as, much as I enjoy answering newbies questions, there is a limit to how far a discussion like this can go - and by spending the $30 or so on this book you'll be in a much better position.

                Use this one for a better idea of the capabilities of the system as a whole. https://www.mc-store.com/collections...astering-ibm-i
                Last edited by JonBoy; December 7, 2017, 10:58 AM.

                Comment


                • #10
                  Yeah, just like getting blood out of a stone trying to get some official training where I am! Meetings to follow, hopefully they will start me off at the beginning of the path.

                  When I use the word API, I do mean IBM functionality like QP0FPTOS or QSPRJOBQ - I was talking about something like setting up a DS within a PR to receive the data from the call to QSPRJOBQ for example.

                  Thanks for adding some clarity regarding programs/modules/service programs.

                  Yes there are /COPY records in the program that point at the QRPGLEREF file and there is a BNDDIR option in the H spec also.

                  *4 - I don't quite understand that but I have raised the missing of building blocks so that's on me.

                  I did have a look at the books at the time and the shipping to the UK was more than the books themselves, I will make a note of them though and see if I can get them over here.


                  I'd like to thank you for the information here, you've helped a lot. For this issue it's clear this is far outside of my capabilities currently so I have passed it onto a senior programmer - also I was wanting to add it so I could break into the program, debug it and then capture the value but he had the idea of just writing it out to a file... I was definitiely over complicating things, such a simple idea that I never thought off... Guess that kind of simple but effective thinking comes with experience.

                  Comment


                  • #11
                    Pity you didn't say about the shipping cost a bit quicker. I just got back from a Christmas trip to the UK - coulda bought them over and mailed them to you. Oh well.

                    I'm back in the UK presenting at the i-UG event http://www.nccomms.com/international_ipower/home.aspx - who knows perhaps you can persuade someone to send you!

                    Comment

                    Working...
                    X