fis-gtm/sr_unix/jobchild_init.c

178 lines
5.3 KiB
C

/****************************************************************
* *
* Copyright 2001, 2011 Fidelity Information Services, Inc *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "gtm_string.h"
#include "gtm_stdlib.h"
#include "gtm_unistd.h"
#include <errno.h>
#include "rtnhdr.h"
#include "startup.h"
#include "gtm_startup.h"
#include "stack_frame.h"
#include "job_addr.h"
#include "compiler.h"
#include "indir_enum.h"
#include "error.h"
#include "util.h"
#include "cli.h"
#include "job.h"
#include "gcall.h"
#include "jobchild_init.h"
#include "lv_val.h" /* needed for "callg.h" */
#include "callg.h"
#include "invocation_mode.h"
#include "gtmci.h"
#include "send_msg.h"
#define FILE_NAME_SIZE 255
GBLREF stack_frame *frame_pointer;
GBLREF uint4 process_id;
error_def (ERR_RUNPARAMERR);
error_def (ERR_TEXT);
error_def(ERR_SYSCALL);
LITDEF char interactive_mode_buf[] = "INTERACTIVE";
LITDEF char other_mode_buf[] = "OTHER";
CONDITION_HANDLER(job_init_ch)
{
START_CH;
PRN_ERROR;
NEXTCH;
}
/*
* ---------------------------------------------------------
* Child process test and initialization.
* If this copy of GTM is a child process,
* then initialize the child.
* ---------------------------------------------------------
*/
void jobchild_init(void)
{
unsigned int status;
job_params_type jparms;
unsigned char *transfer_addr; /* Transfer data */
rhdtyp *base_addr;
unsigned short i, arg_len;
char run_file_name[FILE_NAME_SIZE + 2], *c;
gcall_args job_arglist;
mval job_args[MAX_ACTUALS];
DCL_THREADGBL_ACCESS;
SETUP_THREADGBL_ACCESS;
ESTABLISH(job_init_ch);
/*
* Check if environment variable ppid - job parent pid
* exists. If it does not, we are a regular gtm process,
* else, we are a child process of a job command.
*/
if ((c = GETENV(CHILD_FLAG_ENV)) && strlen(c))
{ /* We are a Jobbed process Get Job parameters and set up environment to run the Job command */
/* Clear the environment variable so that subsequent child mumps processes can start normal initialization. */
if (PUTENV(CLEAR_CHILD_FLAG_ENV))
{
util_out_print("Unable to clear gtmj0 process !UL exiting.", TRUE, process_id);
rts_error(VARLSTCNT(1) errno);
}
/* read parameters into parameter structure */
ojchildparms(&jparms, &job_arglist, job_args);
/* Execute the command to be run before executing the actual M routine */
if (jparms.startup.len)
{
if (0 != SYSTEM(jparms.startup.addr))
{
rts_error(VARLSTCNT(4) ERR_TEXT, 2, LEN_AND_LIT("STARTUP command failed"));
}
}
/* Set up job's input, output and error files. Redirect them, if necessary. */
/* It is needed since the middle process would not have always done this(under jobpid == TRUE cases) */
if (!(status = ojchildioset(&jparms)))
rts_error(VARLSTCNT(4) ERR_TEXT, 2, LEN_AND_LIT("Failed to set STDIN/OUT/ERR for the job"));
job_addr(&jparms.routine, &jparms.label, jparms.offset, (char **)&base_addr, (char **)&transfer_addr);
/* Set process priority */
if (jparms.baspri)
{
/* send message to system log if nice fails */
if (-1 == nice((int)jparms.baspri))
send_msg(VARLSTCNT(8) ERR_SYSCALL, 5, LEN_AND_LIT("nice"), CALLFROM, errno);
}
/* Set up $ZMODE to "OTHER" */
(TREF(dollar_zmode)).mvtype = MV_STR;
(TREF(dollar_zmode)).str.addr = (char *)other_mode_buf;
(TREF(dollar_zmode)).str.len = SIZEOF(other_mode_buf) -1;
/* Release storage allocated by ojchildparms() */
if (jparms.directory.len)
free(jparms.directory.addr);
if (jparms.gbldir.len)
free(jparms.gbldir.addr);
if (jparms.startup.len)
free(jparms.startup.addr);
if (jparms.input.len)
free(jparms.input.addr);
if (jparms.output.len)
free(jparms.output.addr);
if (jparms.error.len)
free(jparms.error.addr);
if (jparms.routine.len)
free(jparms.routine.addr);
if (jparms.label.len)
free(jparms.label.addr);
if (jparms.logfile.len)
free(jparms.logfile.addr);
} else
{
/* If we are not a child, setup a dummy mumps routine */
if (MUMPS_RUN == invocation_mode)
{
mstr routine, label;
int offset;
arg_len = FILE_NAME_SIZE;
if (!cli_get_str("INFILE", run_file_name, &arg_len))
rts_error(VARLSTCNT(1) ERR_RUNPARAMERR);
lref_parse((uchar_ptr_t)run_file_name, &routine, &label, &offset);
job_addr(&routine, &label, offset, (char **)&base_addr, (char **)&transfer_addr);
} else if (MUMPS_CALLIN & invocation_mode) /* call-in mode */
{
base_addr = make_cimode();
transfer_addr = PTEXT_ADR(base_addr);
} else /* direct mode */
{
base_addr = make_dmode();
transfer_addr = PTEXT_ADR(base_addr);
}
job_arglist.callargs = 0;
/* Set up $ZMODE to "INTERACTIVE" */
(TREF(dollar_zmode)).mvtype = MV_STR;
(TREF(dollar_zmode)).str.addr = (char *)interactive_mode_buf;
(TREF(dollar_zmode)).str.len = SIZEOF(interactive_mode_buf) -1;
}
gtm_init_env(base_addr, transfer_addr);
if (MUMPS_CALLIN & invocation_mode)
{
SET_CI_ENV(ci_ret_code_exit);
}
if (job_arglist.callargs)
{
callg((INTPTR_T (*)(intszofptr_t cnt, ...))push_parm, (gparam_list *)&job_arglist);
frame_pointer->type |= SFT_EXTFUN;
}
REVERT;
}