178 lines
5.3 KiB
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;
|
|
}
|