I often write tiny, throw-away things when I need to learn a new API or
something on the 400 and found that I had an example of handling an
exception like this for an old API. Anyway, I came up with the following.
I will gladly entertain suggestions for improvements, etc.

#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <unistd.h>
#include <qmhqrdqd.h>
#include <except.h>
#include <signal.h>

using namespace std;

// icc qmhqrdqd.cpp -o qmhqrdqd

#define TRIMMED_STRING(x) (string((x), sizeof((x))))

static _INTRPT_Hndlr_Parms_T exception_data;
static void handler_SIGALL(int sig)
cout << "Exception message ID is " <<
TRIMMED_STRING(exception_data.Msg_Id) << endl;
cout << "Signal raised is " << sig << endl;
throw runtime_error("your mom goes to college");

int main(int argc, char* argv[])
Qmh_Qrdqd_RDQD0100_t dtaqDesc;

try {
void (*signal_handler)(int);
signal_handler = signal(SIGALL, handler_SIGALL);
QMHQRDQD(&dtaqDesc, sizeof(Qmh_Qrdqd_RDQD0100_t), "RDQD0100",
signal_handler = signal(SIGALL, signal_handler);

cout << "Bytes_Return=" << dtaqDesc.Bytes_Return << endl;
cout << "Bytes_Available=" << dtaqDesc.Bytes_Available << endl;
cout << "Message_Length=" << dtaqDesc.Message_Length << endl;
cout << "Key_Length=" << dtaqDesc.Key_Length << endl;
cout << "Sequence=" << TRIMMED_STRING(dtaqDesc.Sequence) << endl;
cout << "Include_Sender_Id=" <<
TRIMMED_STRING(dtaqDesc.Include_Sender_Id) << endl;
cout << "Force_Indicators=" <<
TRIMMED_STRING(dtaqDesc.Force_Indicators) << endl;
cout << "Text=" << TRIMMED_STRING(dtaqDesc.Text) << endl;
cout << "Type=" << TRIMMED_STRING(dtaqDesc.Type) << endl;
cout << "Automatic_Reclaim=" <<
TRIMMED_STRING(dtaqDesc.Automatic_Reclaim) << endl;
cout << "Enforce_Object_Locks=" <<
TRIMMED_STRING(dtaqDesc.Enforce_Object_Locks) << endl;
cout << "Number_Messages=" << dtaqDesc.Number_Messages << endl;
cout << "Max_Number_Messages=" << dtaqDesc.Max_Number_Messages <<
cout << "Data_Queue_Name=" <<
TRIMMED_STRING(dtaqDesc.Data_Queue_Name) << endl;
cout << "Data_Queue_Library=" <<
TRIMMED_STRING(dtaqDesc.Data_Queue_Library) << endl;
cout << "Max_Number_Entries_Allowed=" <<
dtaqDesc.Max_Number_Entries_Allowed << endl;
cout << "Initial_Number_Entries=" <<
dtaqDesc.Initial_Number_Entries << endl;
cout << "Max_Number_Entries_Specified=" <<
dtaqDesc.Max_Number_Entries_Specified << endl;
cout << "Last_Auto_Reclaim_Date_Time=" <<
TRIMMED_STRING(dtaqDesc.Last_Auto_Reclaim_Date_Time) << endl;
catch (runtime_error& e) {
cerr << e.what() << endl;

On Thu, Nov 10, 2016 at 11:36 AM, Tim Bronski <tim.bronski@xxxxxxxxx> wrote:

If you're using system() then something like this:

if (rc=system(cmdstring)) {
if (!strcmp(_EXCP_MSGID, "CPF9801"))
if (!strcmp(_EXCP_MSGID, "CPF9810"))
return -1;
} else
return 0; // Object found

On 11/10/2016 6:27 PM, Buck Calabro wrote:

On 11/10/2016 11:54 AM, Kelly Beard wrote:


QMHQRDQD() is an API without an error receiver variable, yet the page
possible error codes. How do you get these back from the API? I need a
good C/C++ example on this.

This particular API returns errors the old fashioned way - as exception
messages. If the API runs into an issue (like not authorised to the
library) then IBM i will send a message to your program (the caller of
the API) telling you so.

You need to monitor for, and receive those messages.

The whole topic is covered in 'Handling Exceptions in a Program'

It's a little upside down to typical C where you get errno via a 'side
channel' and you can check it or not as you see fit. When IBM i throws
exception messages, your code gets interrupted and a white message
occurs unless you specifically monitor and handle the message.

Also, isn't there a reason no CRTDTAQ API is available? Why just a
command? That makes it difficult to capture any potential errors on that
as well.

This works the same as QMHQRDQD(); you handle the exception message that

Need sFTP or PGP? Download your native sFTP or OpenPGP solutions here:

This is the Bare Metal Programming IBM i (AS/400 and iSeries) (C400-L)
mailing list
To post a message email: C400-L@xxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: http://lists.midrange.com/mailman/listinfo/c400-l
or email: C400-L-request@xxxxxxxxxxxx
Before posting, please take a moment to review the archives
at http://archive.midrange.com/c400-l.

This thread ...


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

This mailing list archive is Copyright 1997-2020 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].