total rewrite; no longer uses tasks or LWP
This commit is contained in:
@@ -28,9 +28,10 @@
|
||||
* .01 11-26-90 rac initial version
|
||||
* .02 07-30-91 rac installed in SCCS
|
||||
* .03 09-11-91 joh updated for v5 vxWorks
|
||||
* .03 11-07-91 rac be more forgiving of unexpected interactions
|
||||
* .04 12-06-91 rac total rewrite, Unix-only, no LWP
|
||||
*
|
||||
* make options
|
||||
* -DvxWorks makes a version for VxWorks
|
||||
* -DNDEBUG don't compile assert() checking
|
||||
* -DDEBUG compile various debug code, including checks on
|
||||
* malloc'd memory
|
||||
@@ -51,93 +52,39 @@
|
||||
* > cmdClient "hostName",portNum
|
||||
*
|
||||
* BUGS
|
||||
* o need to clean up structure to be more in line with cmdProto's structure
|
||||
* o the stdout stream from this program contains, intermixed, the
|
||||
* server's stdout and stderr streams
|
||||
* o under VxWorks, if the server is on the same IOC, then the IOC itself
|
||||
* must be added to the host table with hostAdd()
|
||||
* o this program should use tasks.h to establish priorities, stack
|
||||
* sizes, etc.
|
||||
* o not all signals are caught
|
||||
*-***************************************************************************/
|
||||
#include <genDefs.h>
|
||||
#include <genTasks.h>
|
||||
#include <cmdDefs.h>
|
||||
#include <tsDefs.h>
|
||||
#include <ezsSockSubr.h>
|
||||
|
||||
#ifdef vxWorks
|
||||
/*----------------------------------------------------------------------------
|
||||
* includes and defines for VxWorks compile
|
||||
*---------------------------------------------------------------------------*/
|
||||
# include <vxWorks.h>
|
||||
# include <stdioLib.h>
|
||||
# include <ctype.h>
|
||||
# include <strLib.h>
|
||||
# include <sigLib.h>
|
||||
# include <setjmp.h>
|
||||
# include <taskLib.h>
|
||||
# define MAXPRIO 160
|
||||
#else
|
||||
/*----------------------------------------------------------------------------
|
||||
* includes and defines for Sun compile
|
||||
*---------------------------------------------------------------------------*/
|
||||
# include <stdio.h>
|
||||
# include <ctype.h>
|
||||
# include <strings.h>
|
||||
# include <signal.h>
|
||||
# include <setjmp.h>
|
||||
# define MAXPRIO 50
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <strings.h>
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
/*/subhead CMDCL_CTX-------------------------------------------------------
|
||||
* CMDCL_CTX - context information
|
||||
*
|
||||
* A cmdcl descriptor is the `master handle' which is used for
|
||||
* handling business.
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define CmdclLock semTake(pglCmdclCtx->semLock, WAIT_FOREVER)
|
||||
#define CmdclUnlock semGive(pglCmdclCtx->semLock)
|
||||
#define CmdclLockCheck semClear(pglCmdclCtx->semLock)
|
||||
#define CmdclLockInitAndLock semInit(pglCmdclCtx->semLock)
|
||||
|
||||
typedef struct {
|
||||
TASK_ID id; /* ID of task */
|
||||
int status; /* status of task--initially ERROR */
|
||||
int stop; /* task requested to stop if != 0 */
|
||||
int stopped; /* task has stopped if != 0 */
|
||||
int serviceNeeded; /* task needs servicing */
|
||||
int serviceDone; /* task servicing completed */
|
||||
jmp_buf sigEnv; /* environment for longjmp at signal time */
|
||||
} CMDCL_TASK_INFO;
|
||||
|
||||
typedef struct cmdclCtx {
|
||||
SEM_ID semLock;
|
||||
CMDCL_TASK_INFO cmdclTaskInfo;
|
||||
CMDCL_TASK_INFO cmdclInTaskInfo;
|
||||
int showStack; /* show stack stats on task terminate */
|
||||
} CMDCL_CTX;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* prototypes
|
||||
*----------------------------------------------------------------------------*/
|
||||
int cmdcl();
|
||||
void cmdclCmdProcess();
|
||||
long cmdclInitAtStartup();
|
||||
long cmdclInTask();
|
||||
char *cmdclInTask();
|
||||
long cmdclTask();
|
||||
void cmdclTaskSigHandler();
|
||||
void cmdclTaskSigInit();
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* global definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
CX_CMD glCmdclCxCmd;
|
||||
CX_CMD *pglCmdclCxCmd=NULL;
|
||||
CMDCL_CTX glCmdclCtx;
|
||||
CMDCL_CTX *pglCmdclCtx=NULL;
|
||||
|
||||
#ifndef vxWorks
|
||||
jmp_buf sigEnv; /* environment for longjmp at signal time */
|
||||
|
||||
main(argc, argv)
|
||||
int argc; /* number of command line args */
|
||||
char *argv[]; /* command line args */
|
||||
@@ -153,47 +100,16 @@ char *argv[]; /* command line args */
|
||||
goto mainUsage;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* do some lwp initialization:
|
||||
* o set allowable priorities between 1 and MAXPRIO
|
||||
* o set up a cache of stacks for MAXTHREAD stacks
|
||||
*
|
||||
* A side effect is that this routine is turned into a lwp thread with a
|
||||
* priority of MAXPRIO.
|
||||
*---------------------------------------------------------------------------*/
|
||||
(void)pod_setmaxpri(MAXPRIO);
|
||||
lwp_setstkcache(100000, 9);
|
||||
|
||||
return cmdClient(hostName, portNum);
|
||||
|
||||
mainUsage:
|
||||
printf("Usage: %s serverHostName serverPortNumber\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*+/subr**********************************************************************
|
||||
* NAME cmdClient - shell callable interface for cmdClient
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This routine is the only part of cmdClient which is intended to be
|
||||
* called directly from the shell. Several functions are performed here:
|
||||
* o spawn the cmdclTask
|
||||
* o spawn the cmdclInTask
|
||||
* o wait until the cmdclInTask quits, then return to the shell. If
|
||||
* other tasks belonging to cmdClient are being stopped, then this
|
||||
* routine waits until they, too, are stopped before returning to
|
||||
* the shell.
|
||||
*
|
||||
* RETURNS
|
||||
* OK, or
|
||||
* ERROR
|
||||
*
|
||||
* BUGS
|
||||
* o stack size and priority should come from tasks.h
|
||||
* o there are lots of "holes" in detecting whether tasks exist, are
|
||||
* suspended, etc.
|
||||
*
|
||||
*-*/
|
||||
int
|
||||
cmdClient(hostName, portNum)
|
||||
@@ -201,108 +117,21 @@ char *hostName; /* I host name for server */
|
||||
int portNum; /* I port number for server */
|
||||
{
|
||||
long stat; /* status return from calls */
|
||||
|
||||
pglCmdclCtx = &glCmdclCtx;
|
||||
pglCmdclCxCmd = &glCmdclCxCmd;
|
||||
stat = cmdclInitAtStartup(pglCmdclCtx, pglCmdclCxCmd);
|
||||
assert(stat == OK);
|
||||
|
||||
#ifdef vxWorks
|
||||
assert(taskNameToId("cmdclTask") == ERROR);
|
||||
assert(taskNameToId("cmdclInTask") == ERROR);
|
||||
#endif
|
||||
pglCmdclCtx->showStack = 0;
|
||||
|
||||
pglCmdclCtx->cmdclTaskInfo.status = ERROR;
|
||||
pglCmdclCtx->cmdclTaskInfo.stop = 0;
|
||||
pglCmdclCtx->cmdclTaskInfo.stopped = 1;
|
||||
|
||||
pglCmdclCtx->cmdclInTaskInfo.status = ERROR;
|
||||
pglCmdclCtx->cmdclInTaskInfo.stop = 0;
|
||||
pglCmdclCtx->cmdclInTaskInfo.stopped = 1;
|
||||
|
||||
pglCmdclCtx->cmdclInTaskInfo.serviceNeeded = 0;
|
||||
pglCmdclCtx->cmdclInTaskInfo.serviceDone = 1;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* cmdclTask
|
||||
* spawn it
|
||||
*----------------------------------------------------------------------------*/
|
||||
pglCmdclCtx->cmdclTaskInfo.id = taskSpawn("cmdclTask", MAXPRIO,
|
||||
VX_STDIO | VX_FP_TASK, 50000, cmdclTask,
|
||||
&pglCmdclCxCmd, hostName, portNum);
|
||||
if (GenTaskNull(pglCmdclCtx->cmdclTaskInfo.id)) {
|
||||
(void)fprintf(stdout, "error spawning cmdclTask\n");
|
||||
return ERROR;
|
||||
}
|
||||
pglCmdclCtx->cmdclTaskInfo.status = OK;
|
||||
pglCmdclCtx->cmdclTaskInfo.stopped = 0;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* cmdclInTask
|
||||
* spawn it
|
||||
*----------------------------------------------------------------------------*/
|
||||
pglCmdclCtx->cmdclInTaskInfo.id = taskSpawn("cmdclInTask", MAXPRIO,
|
||||
VX_STDIO | VX_FP_TASK, 50000, cmdclInTask, &pglCmdclCxCmd);
|
||||
if (GenTaskNull(pglCmdclCtx->cmdclInTaskInfo.id)) {
|
||||
(void)fprintf(stdout, "error spawning cmdclInTask\n");
|
||||
return ERROR;
|
||||
}
|
||||
pglCmdclCtx->cmdclInTaskInfo.status = OK;
|
||||
pglCmdclCtx->cmdclInTaskInfo.stopped = 0;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* wait for cmdclInTask to exit and then return to the shell. If other
|
||||
* "cmdClient tasks" are also exiting, wait until their wrapups are complete.
|
||||
*----------------------------------------------------------------------------*/
|
||||
while (!pglCmdclCtx->cmdclInTaskInfo.stopped)
|
||||
taskSleep(SELF, 1, 0);
|
||||
if (pglCmdclCtx->cmdclTaskInfo.stop) {
|
||||
while (!pglCmdclCtx->cmdclTaskInfo.stopped)
|
||||
taskSleep(SELF, 1, 0);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*+/subr**********************************************************************
|
||||
* NAME cmdclTask - main processing task for cmdClient
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* RETURNS
|
||||
* OK, or
|
||||
* ERROR
|
||||
*
|
||||
* BUGS
|
||||
* o text
|
||||
*
|
||||
*-*/
|
||||
long
|
||||
cmdclTask(ppCxCmd, hostName, portNum)
|
||||
CX_CMD **ppCxCmd;
|
||||
char *hostName; /* I host name for server */
|
||||
int portNum; /* I port number for server */
|
||||
{
|
||||
long stat;
|
||||
CX_CMD *pCxCmd;
|
||||
int serverSock=-1; /* socket connected to server */
|
||||
char serverBuf[80];
|
||||
char *pBuf;
|
||||
FILE *myIn=NULL;
|
||||
FILE *myOut=NULL;
|
||||
char *findNl;
|
||||
char message[80];
|
||||
|
||||
int i;
|
||||
char keyboard[80]; /* line from keyboard */
|
||||
int eofFlag=0;
|
||||
int discardNL=0;
|
||||
|
||||
pCxCmd = *ppCxCmd;
|
||||
genSigInit(cmdclTaskSigHandler);
|
||||
|
||||
CmdclLockInitAndLock;
|
||||
CmdclUnlock;
|
||||
|
||||
cmdclTaskSigInit();
|
||||
|
||||
if (setjmp(pglCmdclCtx->cmdclTaskInfo.sigEnv) != 0)
|
||||
if (setjmp(sigEnv) != 0)
|
||||
goto cmdclTaskWrapup;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
@@ -327,6 +156,7 @@ int portNum; /* I port number for server */
|
||||
myIn = NULL;
|
||||
goto cmdclTaskWrapup;
|
||||
}
|
||||
setbuf(myIn, NULL);
|
||||
if (ezsFopenToFd(&myOut, &serverSock) < 0) {
|
||||
perror("myOut");
|
||||
myOut = NULL;
|
||||
@@ -338,34 +168,60 @@ int portNum; /* I port number for server */
|
||||
* do the interactions with the server, attempting as much as possible
|
||||
* to show the messages as they come in from the server.
|
||||
*---------------------------------------------------------------------------*/
|
||||
while (!pglCmdclCtx->cmdclTaskInfo.stop) {
|
||||
if (pglCmdclCtx->cmdclInTaskInfo.serviceNeeded) {
|
||||
fputs(pCxCmd->line, myOut);
|
||||
while (!eofFlag) {
|
||||
if (cmdclInTask(keyboard) != NULL) {
|
||||
fputs(keyboard, myOut);
|
||||
fflush(myOut);
|
||||
pglCmdclCtx->cmdclInTaskInfo.serviceNeeded = 0;
|
||||
pglCmdclCtx->cmdclInTaskInfo.serviceDone = 1;
|
||||
}
|
||||
|
||||
if (ezsCheckFpRead(myIn)) {
|
||||
if (fgets(serverBuf, 80, myIn) != NULL) {
|
||||
if (strncmp(serverBuf, "#p#r#", 5) == 0) {
|
||||
if ((findNl = index(serverBuf, '\n')) != NULL)
|
||||
*findNl = '\0';
|
||||
fputs(serverBuf+5, stdout);
|
||||
int i, c;
|
||||
|
||||
i = 0;
|
||||
while (ezsCheckFpRead(myIn)) {
|
||||
if ((c = fgetc(myIn)) == EOF) {
|
||||
eofFlag++;
|
||||
break;
|
||||
}
|
||||
serverBuf[i++] = c;
|
||||
if (i >= 79 || c == '\n')
|
||||
break;
|
||||
}
|
||||
pBuf = serverBuf;
|
||||
serverBuf[i] = '\0';
|
||||
if (i > 0) {
|
||||
char *findChr;
|
||||
if ((findChr = index(pBuf, '#')) != NULL) {
|
||||
while (pBuf != findChr) {
|
||||
putchar(*pBuf);
|
||||
pBuf++;
|
||||
}
|
||||
if (strncmp(pBuf, "#p#r#", 5) == 0) {
|
||||
pBuf += 5;
|
||||
discardNL = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
fputs(serverBuf, stdout);
|
||||
pBuf = serverBuf;
|
||||
if (discardNL) {
|
||||
if ((findNl = index(pBuf, '\n')) != NULL) {
|
||||
*findNl = '\0';
|
||||
discardNL = 0;
|
||||
}
|
||||
}
|
||||
fputs(pBuf, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
else {
|
||||
if (strncmp(pCxCmd->line, "quit", 4) == 0)
|
||||
if (strncmp(keyboard, "quit", 4) == 0)
|
||||
break;
|
||||
else if (strncmp(pCxCmd->line, "close", 5) == 0)
|
||||
else if (strncmp(keyboard, "close", 5) == 0)
|
||||
break;
|
||||
printf("server gone (?)\n");
|
||||
break;
|
||||
else
|
||||
printf("null message from server\n");
|
||||
}
|
||||
}
|
||||
taskSleep(SELF, 0, 100000); /* wait .1 sec */
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
cmdclTaskWrapup:
|
||||
@@ -376,23 +232,6 @@ cmdclTaskWrapup:
|
||||
if (serverSock >= 0)
|
||||
close(serverSock);
|
||||
|
||||
while ((*ppCxCmd)->pPrev != NULL)
|
||||
cmdCloseContext(ppCxCmd);
|
||||
pCxCmd = *ppCxCmd;
|
||||
|
||||
pglCmdclCtx->cmdclInTaskInfo.stop = 1;
|
||||
while (pglCmdclCtx->cmdclInTaskInfo.stopped == 0) {
|
||||
taskSleep(SELF, 1, 0);
|
||||
}
|
||||
|
||||
#ifdef vxWorks
|
||||
if (pglCmdclCtx->showStack)
|
||||
checkStack(pglCmdclCtx->cmdclTaskInfo.id);
|
||||
#endif
|
||||
|
||||
pglCmdclCtx->cmdclTaskInfo.stopped = 1;
|
||||
pglCmdclCtx->cmdclTaskInfo.status = ERROR;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -408,7 +247,6 @@ cmdclTaskWrapup:
|
||||
*
|
||||
* BUGS
|
||||
* o not all signals are caught
|
||||
* o under VxWorks, taskDeleteHookAdd isn't used
|
||||
* o it's not clear how useful it is to catch the signals which originate
|
||||
* from the keyboard
|
||||
*
|
||||
@@ -419,129 +257,54 @@ int signo;
|
||||
{
|
||||
printf("entered cmdclTaskSigHandler for signal:%d\n", signo);
|
||||
signal(signo, SIG_DFL);
|
||||
longjmp(pglCmdclCtx->cmdclTaskInfo.sigEnv, 1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cmdclTaskSigInit()
|
||||
{
|
||||
(void)signal(SIGTERM, cmdclTaskSigHandler); /* SunOS plain kill (not -9) */
|
||||
(void)signal(SIGQUIT, cmdclTaskSigHandler); /* SunOS ^\ */
|
||||
(void)signal(SIGINT, cmdclTaskSigHandler); /* SunOS ^C */
|
||||
(void)signal(SIGILL, cmdclTaskSigHandler); /* illegal instruction */
|
||||
#ifndef vxWorks
|
||||
(void)signal(SIGABRT, cmdclTaskSigHandler); /* SunOS assert */
|
||||
#else
|
||||
(void)signal(SIGUSR1, cmdclTaskSigHandler); /* VxWorks assert */
|
||||
#endif
|
||||
(void)signal(SIGBUS, cmdclTaskSigHandler); /* bus error */
|
||||
(void)signal(SIGSEGV, cmdclTaskSigHandler); /* segmentation violation */
|
||||
(void)signal(SIGFPE, cmdclTaskSigHandler); /* arithmetic exception */
|
||||
longjmp(sigEnv, 1);
|
||||
}
|
||||
|
||||
/*+/subr**********************************************************************
|
||||
* NAME cmdclInTask - handle the keyboard and keyboard commands
|
||||
* NAME cmdclInTask - handle keyboard input
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Gets input text and passes the input to cmdclTask.
|
||||
*
|
||||
* This task exists to avoid the possibility of blocking cmdclTask
|
||||
* while waiting for operator input.
|
||||
*
|
||||
* This task waits for input to be available from the keyboard. When
|
||||
* an input line is ready, this task does some preliminary processing:
|
||||
*
|
||||
* o if the command is control-D, "^D" is echoed and the command is
|
||||
* changed to "quit"
|
||||
*
|
||||
* Then cmdclTask is signalled and this task goes into a sleeping loop
|
||||
* until cmdclTask signals that it is ready for the next command.
|
||||
* Checks to see if input is available and reads it, if so. If
|
||||
* there is EOF, then question is asked whether to shut down the
|
||||
* server.
|
||||
*
|
||||
* RETURNS
|
||||
* OK, or
|
||||
* ERROR
|
||||
* char *, or
|
||||
* NULL
|
||||
*
|
||||
*-*/
|
||||
long
|
||||
cmdclInTask(ppCxCmd)
|
||||
CX_CMD **ppCxCmd; /* IO ptr to pointer to command context */
|
||||
char *
|
||||
cmdclInTask(buf)
|
||||
char *buf;
|
||||
{
|
||||
/*----------------------------------------------------------------------------
|
||||
* wait for input from keyboard. When some is received, signal caller,
|
||||
* wait for caller to process it, and then wait for some more input.
|
||||
*
|
||||
* stay in the main loop until .stop flag is set by cmdclTask.
|
||||
*---------------------------------------------------------------------------*/
|
||||
while (1) {
|
||||
while (pglCmdclCtx->cmdclInTaskInfo.serviceDone == 0) {
|
||||
if (pglCmdclCtx->cmdclInTaskInfo.stop == 1)
|
||||
goto cmdclInTaskDone;
|
||||
taskSleep(SELF, 0, 500000); /* sleep .5 sec */
|
||||
}
|
||||
cmdRead(ppCxCmd, &pglCmdclCtx->cmdclInTaskInfo.stop);
|
||||
char *input;
|
||||
char message[80];
|
||||
fd_set fdSet; /* set of fd's to watch with select */
|
||||
int fdSetWidth; /* width of select bit mask */
|
||||
struct timeval fdSetTimeout;/* timeout interval for select */
|
||||
|
||||
if (pglCmdclCtx->cmdclInTaskInfo.stop == 1)
|
||||
goto cmdclInTaskDone;
|
||||
fdSetWidth = getdtablesize();
|
||||
fdSetTimeout.tv_sec = 0;
|
||||
fdSetTimeout.tv_usec = 0;
|
||||
FD_ZERO(&fdSet);
|
||||
FD_SET(fileno(stdin), &fdSet);
|
||||
|
||||
if (strncmp((*ppCxCmd)->line, "quit", 4) == 0) {
|
||||
char *prompt;
|
||||
if (*ppCxCmd != (*ppCxCmd)->pCxCmdRoot) {
|
||||
(void)printf("can't use quit command in source file\n");
|
||||
(*ppCxCmd)->line[0] = '\0';
|
||||
}
|
||||
else {
|
||||
prompt = (*ppCxCmd)->prompt;
|
||||
(*ppCxCmd)->prompt = "stop the server (y/n) ? ";
|
||||
cmdRead(ppCxCmd, &pglCmdclCtx->cmdclInTaskInfo.stop);
|
||||
if ((*ppCxCmd)->line[0] == 'y' || (*ppCxCmd)->line[0] == 'Y')
|
||||
(void)strcpy((*ppCxCmd)->line, "quit\n");
|
||||
else
|
||||
(*ppCxCmd)->line[0] = '\0';
|
||||
(*ppCxCmd)->prompt = prompt;
|
||||
}
|
||||
if (select(fdSetWidth, &fdSet, NULL, NULL, &fdSetTimeout) == 0)
|
||||
return NULL;
|
||||
if (fgets(buf, 80, stdin) == NULL) {
|
||||
strcpy(buf, "quit\n");
|
||||
clearerr(stdin);
|
||||
}
|
||||
if (strncmp(buf, "quit", 4) == 0) {
|
||||
(void)printf("stop the server (y/n) ? ");
|
||||
if (fgets(message, 80, stdin) == NULL) {
|
||||
strcpy(message, "y");
|
||||
}
|
||||
pglCmdclCtx->cmdclInTaskInfo.serviceDone = 0;
|
||||
pglCmdclCtx->cmdclInTaskInfo.serviceNeeded = 1;
|
||||
if (message[0] == 'y' || message[0] == 'Y')
|
||||
strcpy(buf, "quit\n");
|
||||
else
|
||||
strcpy(buf, "\n");
|
||||
}
|
||||
|
||||
cmdclInTaskDone:
|
||||
cmdCloseContext(ppCxCmd);
|
||||
|
||||
#ifdef vxWorks
|
||||
if (pglCmdclCtx->showStack)
|
||||
checkStack(pglCmdclCtx->cmdclInTaskInfo.id);
|
||||
#endif
|
||||
pglCmdclCtx->cmdclInTaskInfo.stop = 1;
|
||||
pglCmdclCtx->cmdclInTaskInfo.stopped = 1;
|
||||
pglCmdclCtx->cmdclInTaskInfo.status = ERROR;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*+/subr**********************************************************************
|
||||
* NAME cmdclInitAtStartup - initialization for cmdClient
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Perform several initialization duties:
|
||||
* o initialize the command context block
|
||||
*
|
||||
* RETURNS
|
||||
* OK, or
|
||||
* ERROR
|
||||
*
|
||||
*-*/
|
||||
long
|
||||
cmdclInitAtStartup(pCmdclCtx, pCxCmd)
|
||||
CMDCL_CTX *pCmdclCtx;
|
||||
CX_CMD *pCxCmd;
|
||||
{
|
||||
pCxCmd->prompt = NULL;
|
||||
pCxCmd->input = stdin;
|
||||
pCxCmd->inputName = NULL;
|
||||
pCxCmd->dataOut = stdout;
|
||||
pCxCmd->pPrev = NULL;
|
||||
pCxCmd->pCxCmdRoot = pCxCmd;
|
||||
|
||||
return OK;
|
||||
return buf;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user