fis-gtm/sr_port/op_zsystem.c

127 lines
3.1 KiB
C

/****************************************************************
* *
* Copyright 2001, 2012 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 <errno.h>
#ifdef VMS
#include <descrip.h>
#include <ssdef.h>
#else
#include <sys/wait.h>
#endif
#include "gtm_stdlib.h"
#include "gtm_string.h"
#include "gdsroot.h"
#include "gdskill.h"
#include "gdsbt.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsfhead.h"
#include "gdscc.h"
#include "filestruct.h"
#include "buddy_list.h" /* needed for tp.h */
#include "io.h"
#include "jnl.h"
#include "hashtab_int4.h" /* needed for tp.h */
#include "tp.h"
#include "send_msg.h"
#include "gtmmsg.h" /* for gtm_putmsg() prototype */
#include "op.h"
#include "change_reg.h"
#include "setterm.h"
#include "getzposition.h"
#ifdef DEBUG
#include "have_crit.h" /* for the TPNOTACID_CHECK macro */
#endif
#define ZSYSTEMSTR "ZSYSTEM"
#define MAXZSYSSTRLEN 4096 /* maximum command line length supported by most Unix shells */
GBLREF uint4 dollar_trestart;
GBLREF int4 dollar_zsystem; /* exit status of child */
GBLREF io_pair io_std_device;
GBLREF uint4 trust;
error_def(ERR_INVSTRLEN);
error_def(ERR_SYSCALL);
void op_zsystem(mval *v)
{
int len;
#ifdef UNIX
char *sh, cmd_buf[MAXZSYSSTRLEN], *cmd;
#ifdef _BSD
union wait wait_stat;
#else
int4 wait_stat;
#endif
#elif defined VMS
uint4 status;
$DESCRIPTOR(d_cmd,"");
#else
#error UNSUPPORTED PLATFORM
#endif
DCL_THREADGBL_ACCESS;
SETUP_THREADGBL_ACCESS;
TPNOTACID_CHECK(ZSYSTEMSTR);
MV_FORCE_STR(v);
#ifdef UNIX
if (v->str.len > (MAXZSYSSTRLEN - 32 - 1)) /* 32 char for shell name, remaining for ZSYSTEM command */
rts_error(VARLSTCNT(4) ERR_INVSTRLEN, 2, v->str.len, (MAXZSYSSTRLEN - 32 - 1));
/* get SHELL environment */
sh = GETENV("SHELL");
/* use bourn shell as default */
if (!sh)
strcpy(cmd_buf, "/bin/sh");
else
strcpy(cmd_buf, sh);
cmd = cmd_buf;
if (v->str.len)
{
strcat(cmd, " -c '");
len = STRLEN(cmd);
memcpy(cmd + len, v->str.addr, v->str.len);
*(cmd + len + v->str.len) = 39; /* ' = 39 */
*(cmd + len + v->str.len + 1) = 0;
}
#elif defined VMS
MVAL_TO_DSC(v, d_cmd);
#endif
flush_pio();
if (io_std_device.in->type == tt)
resetterm(io_std_device.in);
#ifdef UNIX
dollar_zsystem = SYSTEM(cmd);
if (-1 == dollar_zsystem)
rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("system"), CALLFROM, errno);
#ifdef _BSD
assert(SIZEOF(wait_stat) == SIZEOF(int4));
wait_stat.w_status = dollar_zsystem;
#else
wait_stat = dollar_zsystem;
#endif
if (WIFEXITED(wait_stat))
dollar_zsystem = WEXITSTATUS(wait_stat);
#elif defined VMS
status = spawn_and_bgwait(&d_cmd, 0, 0, &trust, 0, 0, &dollar_zsystem);
#endif
if (io_std_device.in->type == tt)
setterm(io_std_device.in);
#ifdef VMS
if (status != SS$_NORMAL)
rts_error(VARLSTCNT(1) status);
#endif
return;
}