Porting ILE C to GNU C - #pragma cancel_handler - IBM AS400

This is a discussion on Porting ILE C to GNU C - #pragma cancel_handler - IBM AS400 ; I am researching the degree of difficulty involved in porting ILE C code to Linux as GNU C. How would #pragma cancel_handler be implemented in GNU C? I guess I could use GNU C++ instead of C and use the ...

+ Reply to Thread
Results 1 to 4 of 4

Thread: Porting ILE C to GNU C - #pragma cancel_handler

  1. Porting ILE C to GNU C - #pragma cancel_handler

    I am researching the degree of difficulty involved in porting ILE C
    code to Linux as GNU C. How would #pragma cancel_handler be implemented
    in GNU C?

    I guess I could use GNU C++ instead of C and use the destructor of a
    class to fire when a function ends. ( I can explain this with code if
    anyone is interested )

    I asked this question on the comp.lang.c newsgroup and got a useful
    reply:
    http://groups.google.com/group/comp....f6c753b?hl=en&

    In general, I am researching what support Linux provides for exception
    handling and process call stack support. For example, how would the
    the QMHSNDPM API be ported to Linux?

    thanks,

    -Steve


  2. Re: Porting ILE C to GNU C - #pragma cancel_handler

    Moin,

    On Thu, Nov 09, 2006 at 07:25:13AM -0800, Steve Richter wrote:
    > I am researching the degree of difficulty involved in porting ILE C
    > code to Linux as GNU C. How would #pragma cancel_handler be implemented
    > in GNU C?


    I don't know what this pragma exactly means; I guess it declares a
    function to be called when the program exits abnormally or so. UNIX
    provides several so-called signals that get sent to the process in case
    of, say, Segmentation Violation (i.e., when you are trying to access
    data your program isn not authorized to), or if the user chooses to
    terminate the process via the SIGTERM signal.

    You can register signal handlers via the signal() function, e.g.:
    void oops(int signum) {
    switch(signum) {
    case SIGSEGV:
    fprintf(stderr, "Program received a segmentation violation"
    " signal\n");
    break;
    case SIGTERM:
    fprintf(stderr, "User chose to abort the program\n");
    break;
    case SIGHUP:
    fprintf(stderr, "Hangup signal (e.g. terminal emulation"
    " closed\n");
    break;
    default:
    fprintf(stderr, "Unkown signal %d received\n", signum);
    }
    }

    int main(void) {
    ...
    signal(SIGSEGV, oops);
    signal(SIGTERM, oops);
    signal(SIGHUP, oops);
    ...
    return 0;
    }

    (NOT tested).

    > I guess I could use GNU C++ instead of C and use the destructor of a
    > class to fire when a function ends. ( I can explain this with code if
    > anyone is interested )


    If you just want to execute a code fragment when a function ends, I
    would write a caller function that just calls the "real" function and
    then executes other statements.

    > In general, I am researching what support Linux provides for exception
    > handling and process call stack support. For example, how would the
    > the QMHSNDPM API be ported to Linux?


    Forget this message thing, there is no way of doing that in UNIX ;-)
    In UNIX, success or failure of a program is generelly indicated by its
    return value (0 means success, anything else than 0 error). Have a look
    at, for example, chmod's return value when you are changing modes of a
    file that exists and one that doesn't exist (or you don't have
    permission to, which also triggers an error).

    Generally, you may be interested in Richard W. Stevens' "Advanced
    Programming in the UNIX Environment". It's *THE* bible to UNIX
    programming, which you should read, if you want to be able to exploit
    UNIX's full strenghts and not just trying to emulate an OS/400
    environment (which would drive users crazy, cause it's so weird to
    them).


    Hope this helps,
    Sebastian
    --
    signature intentionally left blank

  3. Re: Porting ILE C to GNU C - #pragma cancel_handler


    Sebastian Schmidt wrote:
    > Moin,
    >
    > On Thu, Nov 09, 2006 at 07:25:13AM -0800, Steve Richter wrote:
    > > I am researching the degree of difficulty involved in porting ILE C
    > > code to Linux as GNU C. How would #pragma cancel_handler be implemented
    > > in GNU C?

    >
    > I don't know what this pragma exactly means; I guess it declares a
    > function to be called when the program exits abnormally or so.


    when the function ends abnormally. As I understand it, it would be the
    building block for a try ... finally block of code.

    > UNIX
    > provides several so-called signals that get sent to the process in case
    > of, say, Segmentation Violation (i.e., when you are trying to access
    > data your program isn not authorized to), or if the user chooses to
    > terminate the process via the SIGTERM signal.
    >
    > You can register signal handlers via the signal() function, e.g.:
    > void oops(int signum) {
    > switch(signum) {
    > case SIGSEGV:
    > fprintf(stderr, "Program received a segmentation violation"
    > " signal\n");
    > break;
    > case SIGTERM:
    > fprintf(stderr, "User chose to abort the program\n");
    > break;
    > case SIGHUP:
    > fprintf(stderr, "Hangup signal (e.g. terminal emulation"
    > " closed\n");
    > break;
    > default:
    > fprintf(stderr, "Unkown signal %d received\n", signum);
    > }
    > }
    >
    > int main(void) {
    > ...
    > signal(SIGSEGV, oops);
    > signal(SIGTERM, oops);
    > signal(SIGHUP, oops);
    > ...
    > return 0;
    > }
    >
    > (NOT tested).
    >
    > > I guess I could use GNU C++ instead of C and use the destructor of a
    > > class to fire when a function ends. ( I can explain this with code if
    > > anyone is interested )

    >
    > If you just want to execute a code fragment when a function ends, I
    > would write a caller function that just calls the "real" function and
    > then executes other statements.


    but if a signal is raised, both the real function and the caller
    function go bye bye.

    >
    > > In general, I am researching what support Linux provides for exception
    > > handling and process call stack support. For example, how would the
    > > the QMHSNDPM API be ported to Linux?

    >
    > Forget this message thing, there is no way of doing that in UNIX ;-)
    > In UNIX, success or failure of a program is generelly indicated by its
    > return value (0 means success, anything else than 0 error). Have a look
    > at, for example, chmod's return value when you are changing modes of a
    > file that exists and one that doesn't exist (or you don't have
    > permission to, which also triggers an error).
    >
    > Generally, you may be interested in Richard W. Stevens' "Advanced
    > Programming in the UNIX Environment".


    I have it. It is a good book.

    > It's *THE* bible to UNIX
    > programming, which you should read, if you want to be able to exploit
    > UNIX's full strenghts and not just trying to emulate an OS/400
    > environment (which would drive users crazy, cause it's so weird to
    > them).


    What about me?? What they are doing makes no sense. I appreciate
    what you are saying but there must be a way. C# and the .NET framework
    have been implemented on Linux and .NET has great facilities for
    handling exceptions.

    The picture I am getting is that exception handling and possibly even
    the structure of the call stack is the responsibility of the
    programming language in Linux. All the OS does is fork and run
    processes. Just guessing, but the problem with this approach is every
    language implements exceptions and possibly the call stack differently.
    A Java exception cant be thrown and caught by a Perl shell. And
    forget about the Perl code instantiating a Java class and running its
    methods. All guesses on my part but .NET and Windows appears to be much
    more advanced and structured than Linux.

    -Steve


  4. Re: Porting ILE C to GNU C - #pragma cancel_handler

    On Thu, Nov 09, 2006 at 12:25:18PM -0800, Steve Richter wrote:
    > > > I am researching the degree of difficulty involved in porting ILE C
    > > > code to Linux as GNU C. How would #pragma cancel_handler be implemented
    > > > in GNU C?

    > >
    > > I don't know what this pragma exactly means; I guess it declares a
    > > function to be called when the program exits abnormally or so.

    >
    > when the function ends abnormally. As I understand it, it would be the
    > building block for a try ... finally block of code.


    When a function ends abnormally, the whole program ends abnormally. This
    is also the case in ILE. You can, in UNIX, only "catch" them via
    signal() or by checking the return value in the caller.

    > but if a signal is raised, both the real function and the caller
    > function go bye bye.


    Yes. Anyays, I think we two are talking about different "bye-bye"s: Take
    function a, which calls function b: When function b accesses a memory
    area to which it isn't allowed to, or if it causes a divide by zero
    exception, it's a more severe error than opening a file for reading that
    doesn't exist.

    In the former case, you aren't able to catch that - neither in UNIX, nor
    in ILE (except the monitor; on-error; things in ILE RPG), the whole
    program terminates. It is best practice in C to a) not access memory
    areas which you aren't allowed to (but in this case, you wouldn't be
    programming in C, there are much better languages), and b) checking
    what's your divisor, if you do some math. In this example, of course.

    If you encounter en error on open(), on the other hand, you have to set
    up your function to do either return a special value (0, -1, NULL,
    something like that) in case of an error, or let it handle the error its
    way, like fprintf(stderr, "Error encountered while opening %s: %s\n",
    filename, strerror(errno)); exit(1);.

    Generally, you have to do differentiate between errors which cause the
    whole program to crash and errors, which you may be aware of. This is
    also the case in OS/400: You get an MCHxxxx when you access memory which
    you mustn't access (SIGSEGV on UNIX), on the other hand you get a
    CPFxxxx when CPF, err, OS/400 isn't able to open a file. The latter
    would be in UNIX an open() which returns a negative value.

    But as you are asking: No, there's no way in (ISO, w/o extensions) C to
    generate an "exception" that is "caught" by the caller. Yes, this sucks.
    But it's no difference to ILE, anyways. ;-) It's your choice to use
    better languages, just Perl, Python, Ruby, or whatever you like, for
    example. Just not C.

    > > It's *THE* bible to UNIX
    > > programming, which you should read, if you want to be able to exploit
    > > UNIX's full strenghts and not just trying to emulate an OS/400
    > > environment (which would drive users crazy, cause it's so weird to
    > > them).

    >
    > What about me?? What they are doing makes no sense. I appreciate
    > what you are saying but there must be a way. C# and the .NET framework
    > have been implemented on Linux and .NET has great facilities for
    > handling exceptions.


    You don't matter - you as a programmer have just to make users happy. :-)

    But, as stated in my last paragraph, you are right. There are better (or
    even any) exception handling mechanisms in .NET, Java or anything else.
    If you intend to program .NET on UNIX, you may have a look at Mono,
    which is a re-implementation of CLI (Common Language Infrastructure -
    the thing .NET is built on).

    I for myself prefer Perl or Python for UNIX programming, but both aren't
    as easy to learn as RPG or C, to tell the truth.

    > The picture I am getting is that exception handling and possibly even
    > the structure of the call stack is the responsibility of the
    > programming language in Linux.


    That depends on what you call the call stack: Does a function called by
    a function in _one_ program create a new call stack entry or doesn't it?
    There isn't something like a call stack in UNIX like in OS/400's DSPJOB
    and option 11.

    > All the OS does is fork and run
    > processes.


    Not only, but in case of program execution, you got the point. If you
    call program b out of program a, program a does the following:
    - fork itself, so its process gets copied and both run simultaneously
    - decide on whether the current process is the child or the parent
    - if the process is the child, it replaces its program image by that
    which is ought to run.

    If you have a "call chain", you really get something like a call stack.
    You can call getppid() to get the parent's PID (process ID).

    > Just guessing, but the problem with this approach is every
    > language implements exceptions and possibly the call stack
    > differently. A Java exception cant be thrown and caught by a Perl
    > shell. And forget about the Perl code instantiating a Java class and
    > running its methods. All guesses on my part but .NET and Windows
    > appears to be much more advanced and structured than Linux.


    You are right in almost every point stated, with the exception of .NET
    being The Savior. Many, many, software is written in "legacy" C with
    just using an API. I agree to you that using a common intermediate code
    with exception handling and so on (as CLI is) is the right path to
    follow.

    Nevertheless, in practice you won't be switching between programming
    languages every day. You maybe implement a project in language A, the
    next one in language B, and so on. The common practice in UNIX is either
    to let export B a C-like API that can be called by A, or to let A call B
    in an execve() or system()-like manner. But yes, there's no exception
    handling in both cases, you have to check the return values by yourself.

    Exceptions are a great thing within one program, but between calls of
    many single programs it just isn't possible. But I expect you know the
    "design principle" of UNIX. ;-)

    Sebastian
    --
    signature intentionally left blank

+ Reply to Thread