From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 14-APR-1991 20:01:05.89
To:	ARISIA::EVERHART
CC:	
Subj:	Re(2): VAXCRTL atexit return values (also broken under 4.7?)

From:	RELAY-INFO-VAX@CRVAX.SRI.COM@SMTP@CRDGW2
To:	Everhart@Arisia@MRGATE

Received:  by crdgw1.ge.com (5.57/GE 1.97)
	 id AA25162; Sun, 14 Apr 91 19:48:01 EDT
Received: From EQL.CALTECH.EDU by CRVAX.SRI.COM with TCP; Sun, 14 APR 91 15:43:09 PST
Date:     Sun, 14 Apr 91 15:42:59 PDT
From: rankin@EQL.Caltech.Edu (Pat Rankin)
Message-Id: <910414153801.21603ff0@EQL.Caltech.Edu>
Subject:  Re(2): VAXCRTL atexit return values (also broken under 4.7?)
To: info-vax@sri.com

> > [VAX C RTL atexit() on VMS 4.7 causes access violation]
> > >Is atexit broken in the 4.7 vaxcrtl.exe?
>
> >      Yes.  atexit() doesn't work on VAXCRTLs prior to VMS 5.x.  It was
> > documented somewhere in the release notes of VMS ...
>
> The fact that atexit() wasn't documented in the online HELP for VAXC
> releases for pre-V5 systems might have been a clue.

     Online stuff aside, it was documented...  This is an excerpt from
the VAX C V2.3 Release Notes:
 "
 "VAX C RUN-TIME LIBRARY FUNCTIONS
 "
 "The following VAX C Run-Time Library functions are available with V4.6
 "of  VMS.  For more information on each of these functions, see the VAX
 "C Run-Time Library Reference Manual.
 "
 "Functions in both the System V Interface Definition and  the  Proposed
 "ANSI C Language Standard
...
 "Functions Defined in the System V Interface Definition
...
 "Functions Defined in the Proposed ANSI C Language Standard
 "
 "      o  The atexit function, which establishes an action function  to
 "         be called at program termination time.
...
 "Enhancements to Existing Functionality
...

     Here's some code which was cooked up a while back to try to support
VMS V4.5 and earlier.  It hasn't been exhaustively tested though, since
we've never actually needed it.
-----
#ifndef SUPPRESS_ATEXIT
/* int atexit(void (*)(void)) -- register an exit handler.
*/
#define MAX_EXIT_FUNCS 32       /* arbitrary (32 matches VAX C v3.x docs) */
struct _ex_hndlr { long reserved, (*routine)(), arg_count, *arg1_addr; };
static int ex_cnt = 0;          /* number of handlers registered so far */
static struct { long dummy_arg; struct _ex_hndlr handler;   /*(black box)*/
       } ex_data[MAX_EXIT_FUNCS];       /* static handler data */

int atexit( function )
    int (*function)();          /* note: actually gets called with 1 arg */
{
    if ( ex_cnt < MAX_EXIT_FUNCS ) {
	ex_data[ex_cnt].dummy_arg = 0;  /* ultimately receives exit reason */
	ex_data[ex_cnt].handler.reserved  = 0;
	ex_data[ex_cnt].handler.routine   = function;
	ex_data[ex_cnt].handler.arg_count = 1;          /*(required)*/
	ex_data[ex_cnt].handler.arg1_addr = &ex_data[ex_cnt].dummy_arg;
	SYS$DCLEXH( &ex_data[ex_cnt].handler);  /* declare exit handler */
	return ++ex_cnt;        /*(non-zero)*/
    } else
	return 0;
}
#endif /*!SUPPRESS_ATEXIT*/
-----

		Pat Rankin, rankin@eql.caltech.edu

