 |
Compaq ACMS for OpenVMS Systems Interface
Programming
7.2 FORTRAN General-Purpose Agent Program
The FORTRAN program in Example 7-2 is a general-purpose agent program
that handles all types of exchange I/O except stream I/O and Request
Interface I/O.
Example 7-2 FORTRAN General-Purpose Agent
Program |
PROGRAM fortran_agent
C
C This agent program allows the user to select tasks of all exchange I/O
C methods except stream I/O or I/O involving the ACMS Request Interface
C (RI).
C
IMPLICIT NONE
C
INCLUDE 'SYS$LIBRARY:ACMSFOR (ACMS$SUBMITTER)/LIST'
RECORD / ACMS$SUBMITTER_ID / submitter_id
RECORD / ACMS$EXCHANGE_IO_ID / exchange_io_id
RECORD / ACMS$PROCEDURE_ID / procedure_id
RECORD / ACMS$CALL_ID / call_id
INTEGER*4 status
INTEGER*4 LIB$SYS_TRNLOG, LIB$GET_INPUT, LIB$PUT_OUTPUT
C
C Variable declarations for ACMS$SIGN_IN
C
CHARACTER*10 terminal_name
INTEGER*4 terminal_name_desc (2)
C
C Variable declarations for ACMS$GET_PROCEDURE_INFO
C
LOGICAL select_task
LOGICAL need_task_info
C
INTEGER*4 io_method
CHARACTER*31 application_name
CHARACTER*31 task_name
INTEGER*4 task_name_desc (2)
INTEGER*4 task_name_len
C
INTEGER*2 task_info_list (14)
EQUIVALENCE ( task_info_list (1), itm_io_bufsize )
INTEGER*2 itm_io_bufsize
EQUIVALENCE ( task_info_list (2), itm_io_itmcode )
INTEGER*2 itm_io_itmcode
EQUIVALENCE ( task_info_list (3), itm_io_bufadr )
INTEGER*4 itm_io_bufadr
EQUIVALENCE ( task_info_list (5), itm_io_retlen )
INTEGER*4 itm_io_retlen
C
EQUIVALENCE ( task_info_list (7), itm_proc_bufsize )
INTEGER*2 itm_proc_bufsize
EQUIVALENCE ( task_info_list (8), itm_proc_itmcode )
INTEGER*2 itm_proc_itmcode
EQUIVALENCE ( task_info_list (9), itm_proc_bufadr )
INTEGER*4 itm_proc_bufadr
EQUIVALENCE ( task_info_list (11), itm_proc_retlen )
INTEGER*4 itm_proc_retlen
C
EQUIVALENCE ( task_info_list (13), itm_last )
INTEGER*4 itm_last
C
C Variable declarations for ACMS$START_CALL
C
INTEGER*4 argument_list (4)
CHARACTER*255 selection_string
CHARACTER*80 status_string
INTEGER*4 selection_string_desc (2)
INTEGER*4 status_string_desc (2)
C***************************************************************************
C
C Sign in to ACMS, including terminal so that tasks ACMS can authenticate
C the terminal and the submitter can select tasks that use the terminal.
C
status = LIB$SYS_TRNLOG ('TT', , terminal_name)
IF (.NOT. status) THEN
CALL LIB$SIGNAL (%VAL (status) )
END IF
status = ACMS$SIGN_IN ( submitter_id,
1 ,
2 terminal_name )
IF (.NOT. status) THEN
CALL LIB$SIGNAL (%VAL (status) )
END IF
C
C Initialize the submitter to do exchange I/O on behalf of the tasks that it
C selects. This submitter is written to do any kind of exchange I/O except
C stream I/O or I/O involving the ACMS Request Interface (RI).
C
status = ACMS$INIT_EXCHANGE_IO ( submitter_id, exchange_io_id )
IF (.NOT. status) THEN
CALL LIB$SIGNAL (%VAL (status) )
END IF
C
C Construct the item list to get information about the task
C
itm_io_bufsize = 4
itm_io_itmcode = ACMS$K_PROC_IO_METHOD
itm_io_bufadr = %LOC (io_method )
itm_io_retlen = 0
itm_proc_bufsize = ACMS$S_PROCEDURE_ID
itm_proc_itmcode = ACMS$K_PROC_PROCEDURE_ID
itm_proc_bufadr = %LOC ( procedure_id )
itm_proc_retlen = 0
C
itm_last = 0
C
C Loop for task selections, until user types EXIT instead of application name
C
select_task = .TRUE.
DO WHILE (select_task)
C
C Loop until we get a good application/task name.
C
need_task_info = .TRUE.
DO WHILE (need_task_info)
C
C Ask for application name and task name.
C
status = LIB$GET_INPUT (application_name, 'Application name: ')
IF (.NOT. status) THEN
CALL LIB$SIGNAL ( %VAL (status) )
ELSE
IF (application_name .EQ. 'EXIT') THEN
select_task = .FALSE.
GO TO 2000
END IF
END IF
status = LIB$GET_INPUT (task_name, 'Task name: ', task_name_len)
IF (.NOT. status) THEN
CALL LIB$SIGNAL ( %VAL (status) )
END IF
task_name_desc (1) = task_name_len
task_name_desc (2) = %LOC (task_name)
C
C Get the procedure ID for the task.
C If we have a good application/task name, continue. Otherwise,
C print error message and try again.
C
status = ACMS$GET_PROCEDURE_INFO ( submitter_id,
1 task_name_desc,
2 application_name,
3 task_info_list )
IF (.NOT. status) THEN
CALL LIB$SIGNAL (%VAL( status ) )
ELSE
need_task_info = .FALSE.
END IF
END DO
C
C Get the selection string, if any.
C
status = LIB$GET_INPUT (selection_string, 'Selection string: ')
IF (.NOT. status) THEN
CALL LIB$SIGNAL (%VAL (status) )
END IF
C
C Set up argument list for the task.
C
C - Selection string descriptor
C - Extended status descriptor
C - Exchange I/O ID
C
argument_list (1) = 3
selection_string_desc (1)= LEN (selection_string)
selection_string_desc (2)= %LOC (selection_string)
argument_list (2) = %LOC (selection_string_desc)
C
status_string_desc (1) = LEN (status_string)
status_string_desc (2) = %LOC (status_string)
argument_list (3) = %LOC (status_string_desc)
C
argument_list (4) = %LOC (exchange_io_id)
C
C Now start the task.
C
status = ACMS$START_CALL ( submitter_id,
1 procedure_id,
2 call_id,
3 argument_list )
IF (.NOT. status) THEN
CALL LIB$SIGNAL (%VAL (status) )
END IF
C
C Wait for task to complete.
C
status = ACMS$WAIT_FOR_CALL_END (submitter_id,
1 call_id)
IF (.NOT. status) THEN
CALL LIB$SIGNAL (%VAL (status) )
END IF
C Display final status for task.
C
IF ((status_string .NE. ' ') .AND.
1 (status_string .NE. 'Task completed normally')) THEN
CALL LIB$PUT_OUTPUT (status_string)
END IF
C
C We come here when the user wishes to exit the agent program.
C
2000 END DO
C
C Sign the submitter out.
C
status = ACMS$SIGN_OUT ( submitter_id )
IF (.NOT. status) THEN
CALL LIB$SIGNAL (%VAL (status) )
END IF
C
END
|
7.3 C Agent Program that Performs Stream I/O or No I/O
The C agent program in Example 7-3 submits tasks that perform stream
I/O or no I/O. The agent program disables the use of DECforms and TDMS
in exchange steps.
Example 7-3 C Agent Program that Performs
Stream I/O or No I/O |
/*
* This agent program is a special-case agent that only handles tasks
* that do stream I/O in exchange steps.
*/
/** include descriptor declarations **/
#include "sys$library:descrip.h"
/** include ACMS definition files (from sys$library:acmscc.tlb) **/
#include acms$submitter
#include acms$stream
#define SUCCESS 1
#define TRUE 1
#define FALSE 0
#define NULL 0
/** define structure for item list **/
struct item {
short int bufsize;
short int itmcode;
char *bufadr;
int retlen;
};
main()
{
/*
* External routines
*/
int LIB$GET_INPUT();
int LIB$PUT_OUTPUT();
/*
* Variables for ACMS IDs
*/
struct ACMS$SUBMITTER_ID submitter_id;
struct ACMS$EXCHANGE_IO_ID exchange_io_id;
struct ACMS$CONNECT_ID connect_id;
struct ACMS$PROCEDURE_ID procedure_id;
struct ACMS$IO_ID io_id;
/*
* Variables for ACMS$INIT_EXCHANGE_IO
*/
struct item init_exch_io_list[2] =
{ ACMS$S_CONNECT_ID, ACMS$K_CONNECT_ID, &connect_id, 0,
0, 0 }; /* zero the last longword (2 words) for list termination */
int io_enable_flags;
/*
* Variable declarations for ACMS$GET_PROCEDURE_INFO
*/
int io_method;
char task_name_string[39], appl_name_string[255];
$DESCRIPTOR(task_name_desc,task_name_string);
$DESCRIPTOR (appl_name_desc,appl_name_string);
$DESCRIPTOR (appl_prompt_desc,"Application name: ");
$DESCRIPTOR (task_prompt_desc,"Task name: ");
/*
* Item list structure to be used in ACMS$GET_PROCEDURE_INFO
*
* There are 2 elements specified in this item list:
* 1) 4 bytes of data for ACMS$K_PROC_IO_METHOD, to be
* returned in variable io_method.
* 2) 8 bytes data for ACMS$K_PROC_PROCEDURE_ID, to be
* returned in variable procedure_id.
* (This code omits the return length variable address, which
* could be specified to receive the actual length of data
* returned for each item.)
* Other possible items include:
* - ACMS$K_PROC_WORKSPACE_COUNT to receive count of TASK ARGUMENTS
* which the task could accept from the agent program
* - ACMS$K_PROC_WAIT_DELAY_ACTION to receive the wait/delay
* action specified in the task definition
*/
struct item task_info_list[3] =
{ 4, ACMS$K_PROC_IO_METHOD, &io_method, 0,
ACMS$S_PROCEDURE_ID, ACMS$K_PROC_PROCEDURE_ID, &procedure_id, 0,
0, 0 }; /* zero the last longword (2 words) for list termination */
/*
* Variable declarations for ACMS$START_CALL
*/
struct ACMS$CALL_ID call_id;
int argument_list[4];
char selection_string[255], status_string[80];
$DESCRIPTOR(selection_string_desc,selection_string);
$DESCRIPTOR(status_string_desc,status_string);
/*
* Variable declarations for ACMS$WAIT_FOR_STREAM_IO
*/
globalvalue int ACMS$_SENDER_DISCONN;
int sender_disconn;
short int processing_io;
char *input_string_addr, *output_string_addr;
/*
* Miscellaneous variables
*/
int status;
short int i, all_spaces;
/**************************************************************/
/*
* Sign in to ACMS, no terminal IO, only stream IO
*/
status = ACMS$SIGN_IN (&submitter_id);
if ((status & 1) != SUCCESS) LIB$SIGNAL (status);
/*
* Set up the agent program to do only stream I/O in exchange steps.
*/
io_enable_flags = ACMS$M_IO_DISABLE_TDMS + ACMS$M_IO_DISABLE_DECFORMS;
status = ACMS$INIT_EXCHANGE_IO ( &submitter_id,
&exchange_io_id,
&io_enable_flags,
&init_exch_io_list );
if ((status & 1) != SUCCESS) LIB$SIGNAL (status);
/*
* Get the procedure ID for the task
* - prompt the user for the task name
* - prompt the user for application logical name
* (These strings should be entered in upper case
* or converted to upper case.)
* - then call ACMS$GET_PROCEDURE_INFO
*/
status = LIB$GET_INPUT ( &task_name_desc, &task_prompt_desc );
if ((status & 1) != SUCCESS) LIB$SIGNAL (status);
status = LIB$GET_INPUT ( &appl_name_desc, &appl_prompt_desc );
if ((status & 1) != SUCCESS) LIB$SIGNAL (status);
status = ACMS$GET_PROCEDURE_INFO (&submitter_id,
&task_name_desc,
&appl_name_desc,
task_info_list);
if ((status & 1) != SUCCESS) LIB$SIGNAL (status);
/*
* Set up the argument list for the task
*/
argument_list[0] = 3;
argument_list[1] = &selection_string_desc;
argument_list[2] = &status_string_desc;
argument_list[3] = &exchange_io_id;
/*
* Now start the task. This agent program does not supply TASK
* ARGUMENTS. If TASK ARGUMENTS were used, they would require
* the task_info_list structure to be expanded to include the item
* ACMS$K_PROC_WORKSPACE_COUNT, which returns the number of TASK
* ARGUMENTS (if any) declared in the task definition. This agent
* program would then build descriptors pointing to C variables
* corresponding to the number of arguments to be supplied. Then
* argument_list[4] would be supplied the address of the
* first argument descriptor, argument_list[5] the address of the
* second argument descriptor. argument_list[0] would be amended to
* reflect the total argument count = 3 + NUMBER_OF_TASK_ARGUMENTS
* supplied to the task by the agent program.
*/
status = ACMS$START_CALL (&submitter_id,
&procedure_id,
&call_id,
argument_list);
if ((status & 1) != SUCCESS) LIB$SIGNAL (status);
/*
* This agent program handles only tasks that do no exchange I/O and
* tasks that do stream I/O. If it is a NO I/O task, skip the stream
* processing.
*/
if (io_method == ACMS$K_IO_NONE)
processing_io = FALSE;
else
{
processing_io = TRUE;
sender_disconn = ACMS$_SENDER_DISCONN;
}
/*
* Process the stream task with the following algorithm:
*
* - wait for notification to begin the I/O (WAIT_FOR_STREAM_IO
* completes)
* - do the I/O
* - reply that the I/O is finished (REPLY_TO_STREAM_IO)
* - wait for more notification - if there is no more I/O, the
* sender will disconnect and we will be finished
*/
while (processing_io)
{
status = ACMS$WAIT_FOR_STREAM_IO (&connect_id,
&output_string_addr,
&input_string_addr,
&io_id);
if ((status & 1) != SUCCESS)
{
processing_io = FALSE;
if (status != sender_disconn)
LIB$SIGNAL (status);
}
else
{
/*
* We have been notified to do the I/O - do it
*/
if ((output_string_addr != NULL) && (input_string_addr == NULL))
{
status = LIB$PUT_OUTPUT (output_string_addr);
if ((status & 1) != SUCCESS) LIB$SIGNAL (status);
}
if (input_string_addr != NULL)
{
if (output_string_addr == NULL)
status = LIB$GET_INPUT (input_string_addr);
else
status = LIB$GET_INPUT (input_string_addr,
output_string_addr);
if ((status & 1) != SUCCESS) LIB$SIGNAL (status);
}
/*
* Tell the application that we are done with
* the I/O
*/
status = ACMS$REPLY_TO_STREAM_IO (&connect_id,
&io_id);
if ((status & 1) != SUCCESS) LIB$SIGNAL (status);
} /* end of successful WAIT_FOR_STREAM_IO */
} /* end while loop */
/*
* Wait for the task to complete
*/
status = ACMS$WAIT_FOR_CALL_END (&submitter_id, &call_id);
if ((status & 1) != SUCCESS) LIB$SIGNAL (status);
/*
* Terminate the exchange I/O for the submitter
*/
status = ACMS$TERM_EXCHANGE_IO (&exchange_io_id);
/*
* Sign the submitter out
*/
status = ACMS$SIGN_OUT (&submitter_id);
if ((status & 1) != SUCCESS) LIB$SIGNAL (status);
/*
* Display the final status
*/
all_spaces = TRUE;
for (i = 0; (i < 80) && (status_string[i] != NULL) && all_spaces; i++)
if (status_string[i] != ' ')
all_spaces = FALSE;
if (!all_spaces)
LIB$PUT_OUTPUT (status_string);
}
|
7.4 BLISS Agent Program that Uses Superseded Services
Example 7-4 contains a BLISS agent program that uses superseded
exchange I/O services and the method of constructing argument lists
used in ACMS versions earlier than Version 3.1.
Note
Example 7-4 is provided for the convenience of programmers who need
to maintain agent programs written for earlier versions of ACMS. Do not
use the techniques shown in this example when developing new agent
programs.
|
Example 7-4 BLISS Agent Program that Uses
Superseded Services |
MODULE bliss_agent (IDENT = 'V2.1-000',
MAIN = agent_main,
ADDRESSING_MODE (EXTERNAL=GENERAL,
NONEXTERNAL=LONG_RELATIVE)) =
BEGIN
!
! External References
!
EXTERNAL ROUTINE
LIB$SYS_TRNLOG,
LIB$GET_EF,
LIB$FREE_EF,
LIB$GET_INPUT,
LIB$PUT_OUTPUT,
STR$UPCASE;
EXTERNAL LITERAL
ACMS$_SENDER_DISCONN,
ACMS$_NORMAL;
!
! Library Files
!
LIBRARY 'SYS$LIBRARY:STARLET';
LIBRARY 'SYS$LIBRARY:ACMSBLI';
ROUTINE agent_main =
!
! Agent's main routine
!
BEGIN
LOCAL
status,
sub_id: ACMS$SUBMITTER_ID,
!
! Variable declarations for ACMS$GET_PROCEDURE_INFO_A
!
task_name: BLOCK [ DSC$K_D_BLN, BYTE],
application_name: BLOCK [ DSC$K_D_BLN, BYTE],
io_method,
task_info_list: $ITMLST_DECL ( ITEMS = 2 ),
have_task_info,
!
! Variable declarations for ACMS$START_CALL_A
!
proc_id: CMS$PROCEDURE_ID,
task_id: ACMS$CALL_ID,
argument_list: VECTOR [4,LONG],
selection_string: BLOCK [ DSC$K_D_BLN, BYTE],
status_string: BLOCK [ DSC$K_D_BLN, BYTE],
terminal_name: BLOCK [ DSC$K_D_BLN, BYTE],
!
! Variable declarations for Stream Services
!
stream_id: ACMS$STREAM_ID,
connect_id: ACMS$CONNECT_ID,
io_id: ACMS$IO_ID,
output_string_addr: REF BLOCK [4, BYTE],
input_string_addr: REF BLOCK [4, BYTE],
processing_io,
!
! Variable declarations for asychronous service arguments
!
comp_status_block: VECTOR [ 2, LONG ],
event_flag;
LITERAL
TRUE = 1 EQL 1,
FALSE = 0 EQL 1;
BIND
comp_status = comp_status_block [ 0 ];
!
! Initialize dynamic string descriptors
!
$INIT_DYNDESC ( task_name );
$INIT_DYNDESC ( application_name );
$INIT_DYNDESC ( selection_string );
$INIT_DYNDESC ( status_string );
$INIT_DYNDESC ( terminal_name );
status = LIB$GET_EF ( event_flag );
IF NOT .status THEN SIGNAL ( .status );
status = LIB$SYS_TRNLOG ( %ASCID'TT', 0, terminal_name );
IF .status NEQ SS$_NORMAL THEN SIGNAL ( .status );
!
! Sign in to ACMS
!
status = $ACMS$SIGN_IN_A (SUBMITTER_ID = sub_id,
DEVICE = terminal_name,
COMP_STATUS = comp_status,
EFN = event_flag );
IF NOT .status
THEN
SIGNAL (.status)
ELSE
BEGIN
$WAITFR ( EFN = .event_flag );
IF NOT .comp_status THEN SIGNAL ( .comp_status );
END;
!
! Set up item list
!
$ITMLST_INIT ( ITMLST = task_info_list,
( ITMCOD = ACMS$K_PROC_PROCEDURE_ID,
BUFSIZ = ACMS$S_PROCEDURE_ID,
BUFADR = proc_id ),
( ITMCOD = ACMS$K_PROC_IO_METHOD,
BUFSIZ = %UPVAL,
BUFADR = io_method ) );
have_task_info = FALSE;
!
! Loop until we get a good application/task name
!
DO
BEGIN
!
! Ask for application name and task name.
! Convert names to all caps for comparisons in ACMS.
!
status = LIB$GET_INPUT (application_name, %ASCID 'Application name: ');
IF NOT .status THEN SIGNAL (.status);
status = STR$UPCASE (application_name, application_name);
IF .status NEQ SS$_NORMAL THEN SIGNAL ( .status );
status = LIB$GET_INPUT (task_name, %ASCID 'Task name: ');
IF NOT .status THEN SIGNAL (.status);
status = STR$UPCASE (task_name, task_name);
IF .status NEQ SS$_NORMAL THEN SIGNAL ( .status );
!
! Ask ACMS if task is known and get its ID
!
status = $ACMS$GET_PROCEDURE_INFO_A ( SUBMITTER_ID = sub_id,
PROCEDURE = task_name,
PACKAGE = application_name,
ITEM_LIST = task_info_list,
EFN = event_flag,
COMP_STATUS = comp_status );
IF NOT .status
THEN
SIGNAL ( .status )
ELSE
BEGIN
$WAITFR ( EFN = .event_flag );
IF .comp_status EQL ACMS$_NORMAL
THEN
have_task_info = TRUE
ELSE
SIGNAL ( .comp_status );
END;
END
UNTIL .have_task_info;
!
! Get the selection string
!
status = LIB$GET_INPUT (selection_string, %ASCID 'Selection string: ');
IF NOT .status THEN SIGNAL (.status);
!
! If the I/O method is stream, then setup the stream
!
IF .io_method EQL ACMS$K_IO_STREAM
THEN
BEGIN
status = $ACMS$CREATE_STREAM_A (MODE = %REF(ACMS$K_STRM_BIDIRECTIONAL),
STREAM_ID = stream_id,
COMP_STATUS = comp_status,
EFN = event_flag );
IF NOT .status
THEN
SIGNAL (.status)
ELSE
BEGIN
$WAITFR ( EFN = .event_flag );
IF NOT .comp_status THEN SIGNAL ( .comp_status );
END;
status = $ACMS$CONNECT_STREAM_A (STREAM_ID = stream_id,
CONNECT_ID = connect_id,
MODE = %REF(ACMS$K_STRM_PASSIVE),
COMP_STATUS = comp_status,
EFN = event_flag );
IF NOT .status
THEN
SIGNAL (.status)
ELSE
BEGIN
$WAITFR ( EFN = .event_flag );
IF NOT .comp_status THEN SIGNAL ( .comp_status );
END;
END;
!
! Set up argument list for task
!
argument_list [1] = selection_string;
argument_list [2] = status_string;
SELECTONE .io_method OF
SET
[ACMS$K_IO_NONE]:
argument_list [0] = 2;
[ACMS$K_IO_TERMINAL,
ACMS$K_IO_REQUEST]:
BEGIN
argument_list [0] = 3;
argument_list [3] = terminal_name;
END;
[ACMS$K_IO_STREAM]:
BEGIN
argument_list [0] = 3;
argument_list [3] = stream_id;
END;
[OTHERWISE]:
SIGNAL (SS$_ABORT);
TES;
!
! Now start the task
!
status = $ACMS$START_CALL_A (SUBMITTER_ID = sub_id,
PROCEDURE_ID = proc_id,
ARGUMENTS = argument_list,
CALL_ID = task_id,
COMP_STATUS = comp_status,
EFN = event_flag );
IF NOT .status
THEN
SIGNAL (.status)
ELSE
BEGIN
$WAITFR ( EFN = .event_flag );
IF NOT .comp_status THEN SIGNAL ( .comp_status );
END;
!
! If the task I/O method is stream, process the stream I/O in the following
! loop
IF .io_method EQL ACMS$K_IO_STREAM
THEN
BEGIN
processing_io = TRUE;
WHILE .processing_io DO
BEGIN
status = $ACMS$WAIT_FOR_STREAM_IO_A
( CONNECT_ID = connect_id,
OUTPUT_OBJECT = output_string_addr,
INPUT_OBJECT = input_string_addr,
IO_ID = io_id,
COMP_STATUS = comp_status,
EFN = event_flag );
IF NOT .status
THEN
SIGNAL (.status)
ELSE
BEGIN
$WAITFR ( EFN = .event_flag );
IF .comp_status EQL ACMS$_SENDER_DISCONN
THEN
processing_io = FALSE
THEN
SIGNAL ( .comp_status )
ELSE
BEGIN
!
! See what kind of EXCHANGE was in the task defintion
!
IF .output_string_addr NEQ 0 AND .input_string_addr EQL 0
THEN
!
! Exchange step was a WRITE
!
BEGIN
status = LIB$PUT_OUTPUT (.output_string_addr);
IF NOT .status THEN SIGNAL (.status);
END;
IF .input_string_addr NEQ 0
THEN
IF .output_string_addr EQL 0
THEN
!
! Exchange step was a READ
!
BEGIN
status = LIB$GET_INPUT (.input_string_addr);
IF NOT .status THEN SIGNAL (.status);
END
ELSE
!
! Exchange step was a READ WITH PROMPT
!
BEGIN
status = LIB$GET_INPUT (.input_string_addr,
.output_string_addr );
IF NOT .status THEN SIGNAL (.status);
END;
!
! Reply to the I/O request
!
status = $ACMS$REPLY_TO_STREAM_IO_A
(CONNECT_ID = connect_id,
IO_ID = io_id,
EFN = event_flag );
IF NOT .status
THEN
SIGNAL (.status)
ELSE
BEGIN
$WAITFR ( EFN = .event_flag );
IF NOT .comp_status THEN SIGNAL ( .comp_status );
END;
END; ! End of successful wait_for_stream_io completion
END; ! End of successful wait_for_stream_io starting
END; ! End of stream processing loop
END; ! End of stream task
!
! Wait for task to complete
!
status = $ACMS$WAIT_FOR_CALL_END_A (SUBMITTER_ID = sub_id,
CALL_ID = task_id,
COMP_STATUS = comp_status,
EFN = event_flag );
IF NOT .status
THEN
SIGNAL (.status)
ELSE
BEGIN
$WAITFR ( EFN = .event_flag );
IF NOT .comp_status THEN SIGNAL ( .comp_status );
END;
!
! If a stream was used, disconnect it and delete it
!
IF .io_method EQL ACMS$K_IO_STREAM
THEN
BEGIN
status = $ACMS$DISCONNECT_STREAM_A (CONNECT_ID = connect_id,
COMP_STATUS = comp_status,
EFN = event_flag );
IF NOT .status
THEN
SIGNAL (.status)
ELSE
BEGIN
$WAITFR ( EFN = .event_flag );
IF NOT .comp_status THEN SIGNAL ( .comp_status );
END;
status = $ACMS$DELETE_STREAM_A (STREAM_ID = stream_id,
COMP_STATUS = comp_status,
EFN = event_flag );
IF NOT .status
THEN
SIGNAL (.status)
ELSE
BEGIN
$WAITFR ( EFN = .event_flag );
IF NOT .comp_status THEN SIGNAL ( .comp_status );
END;
END;
status = $ACMS$SIGN_OUT_A ( SUBMITTER_ID = sub_id,
COMP_STATUS = comp_status,
EFN = event_flag );
IF NOT .status
THEN
SIGNAL (.status)
ELSE
BEGIN
$WAITFR ( EFN = .event_flag );
IF NOT .comp_status THEN SIGNAL ( .comp_status );
END;
!
! Display final status
!
IF CH$NEQ (.status_string [DSC$W_LENGTH], .status_string [DSC$A_POINTER],
1, UPLIT (' '), %C' ')
THEN
LIB$PUT_OUTPUT (status_string);
status = LIB$FREE_EF ( event_flag );
IF NOT .status THEN SIGNAL ( .status );
RETURN SS$_NORMAL;
END;
END ELUDOM
|
|