- make shutdown more proper (releasing all memory)
- fixed memory leak (releaseing args when error in command) - introduced startup commands - modified status file writing (avoid potential corrupted files)
This commit is contained in:
127
SCinter.c
127
SCinter.c
@ -62,9 +62,6 @@
|
|||||||
#include "definealias.h"
|
#include "definealias.h"
|
||||||
|
|
||||||
|
|
||||||
#define MAXLEN 256
|
|
||||||
#define MAXPAR 100
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
SicsInterp *InitInterp(void)
|
SicsInterp *InitInterp(void)
|
||||||
{
|
{
|
||||||
@ -91,10 +88,11 @@
|
|||||||
return pInter;
|
return pInter;
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
int AddCommand(SicsInterp *pInterp, char *pName, ObjectFunc pFunc,
|
int AddCommandWithFlag(SicsInterp *pInterp, char *pName, ObjectFunc pFunc,
|
||||||
KillFunc pKFunc, void *pData)
|
KillFunc pKFunc, void *pData, int startupOnly)
|
||||||
{
|
{
|
||||||
CommandList *pNew = NULL;
|
CommandList *pNew = NULL;
|
||||||
|
CommandList *p, *tail;
|
||||||
char pBueffel[512];
|
char pBueffel[512];
|
||||||
|
|
||||||
assert(pName);
|
assert(pName);
|
||||||
@ -134,19 +132,42 @@
|
|||||||
pNew->OFunc = pFunc;
|
pNew->OFunc = pFunc;
|
||||||
pNew->KFunc = pKFunc;
|
pNew->KFunc = pKFunc;
|
||||||
pNew->pData = pData;
|
pNew->pData = pData;
|
||||||
pNew->pNext = pInterp->pCList;
|
pNew->pNext = NULL;
|
||||||
|
pNew->startupOnly = startupOnly;
|
||||||
|
|
||||||
|
/* find end of list */
|
||||||
if(pInterp->pCList)
|
tail = NULL;
|
||||||
|
p = pInterp->pCList;
|
||||||
|
while(p != NULL)
|
||||||
{
|
{
|
||||||
pInterp->pCList->pPrevious = pNew;
|
tail = p;
|
||||||
|
p = p->pNext;
|
||||||
}
|
}
|
||||||
pNew->pPrevious = NULL;
|
if (tail==NULL) { /* first entry */
|
||||||
|
pInterp->pCList = pNew;
|
||||||
|
} else { /* insert at tail */
|
||||||
|
tail->pNext = pNew;
|
||||||
|
}
|
||||||
|
pNew->pPrevious = tail;
|
||||||
|
|
||||||
/* update headpointer */
|
|
||||||
pInterp->pCList = pNew;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
int AddCommand(SicsInterp *pInterp, char *pName, ObjectFunc pFunc,
|
||||||
|
KillFunc pKFunc, void *pData)
|
||||||
|
{
|
||||||
|
return AddCommandWithFlag(pInterp, pName, pFunc, pKFunc, pData, 0);
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
int AddIniCmd(char *pName, ObjectFunc pFunc)
|
||||||
|
{
|
||||||
|
return AddCommandWithFlag(pServ->pSics, pName, pFunc, NULL, NULL, 1);
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
int AddCmd(char *pName, ObjectFunc pFunc)
|
||||||
|
{
|
||||||
|
return AddCommandWithFlag(pServ->pSics, pName, pFunc, NULL, NULL, 0);
|
||||||
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
int RemoveCommand(SicsInterp *pInterp, char *pName)
|
int RemoveCommand(SicsInterp *pInterp, char *pName)
|
||||||
{
|
{
|
||||||
@ -198,10 +219,21 @@
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAXLEN 256
|
|
||||||
#define MAXCOM 50
|
/*------------------------------------------------------------------------*/
|
||||||
extern char *stptok(char *s, char *tok, unsigned int toklen, char *brk);
|
void RemoveStartupCommands(void)
|
||||||
extern char *SkipSpace(char *pPtr);
|
{
|
||||||
|
CommandList *pCurrent, *pNext;
|
||||||
|
pCurrent = pServ->pSics->pCList;
|
||||||
|
while(pCurrent)
|
||||||
|
{
|
||||||
|
pNext = pCurrent->pNext;
|
||||||
|
if (pCurrent->startupOnly) {
|
||||||
|
RemoveCommand(pServ->pSics, pCurrent->pName);
|
||||||
|
}
|
||||||
|
pCurrent = pNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
int InterpExecute(SicsInterp *self,SConnection *pCon, char *pText)
|
int InterpExecute(SicsInterp *self,SConnection *pCon, char *pText)
|
||||||
{
|
{
|
||||||
@ -233,18 +265,21 @@ extern char *SkipSpace(char *pPtr);
|
|||||||
|
|
||||||
/* convert to argc, argv */
|
/* convert to argc, argv */
|
||||||
argc = 0;
|
argc = 0;
|
||||||
|
argv = NULL;
|
||||||
Text2Arg(pText,&argc,&argv);
|
Text2Arg(pText,&argc,&argv);
|
||||||
|
|
||||||
/* the first one must be the target object. If not given an empty
|
/* the first one must be the target object. If not given an empty
|
||||||
command string was given which will be silently ignored */
|
command string was given which will be silently ignored */
|
||||||
if(argc < 1)
|
if(argc < 1)
|
||||||
{
|
{
|
||||||
return 1;
|
iRet = 1;
|
||||||
|
goto deleteArgv;
|
||||||
}
|
}
|
||||||
if(argv[0] == NULL)
|
if(argv[0] == NULL)
|
||||||
{
|
{
|
||||||
SCWrite(pCon,"ERROR: failed to parse command",eError);
|
SCWrite(pCon,"ERROR: failed to parse command",eError);
|
||||||
return -1;
|
iRet = -1;
|
||||||
|
goto deleteArgv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find it */
|
/* find it */
|
||||||
@ -254,8 +289,8 @@ extern char *SkipSpace(char *pPtr);
|
|||||||
sprintf(pBueffel,"ERROR: Object -> %s <- NOT found",
|
sprintf(pBueffel,"ERROR: Object -> %s <- NOT found",
|
||||||
argv[0]);
|
argv[0]);
|
||||||
SCWrite(pCon,pBueffel,eError);
|
SCWrite(pCon,pBueffel,eError);
|
||||||
return -1;
|
iRet = -1;
|
||||||
|
goto deleteArgv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -266,16 +301,18 @@ extern char *SkipSpace(char *pPtr);
|
|||||||
iRet = pCommand->OFunc(pCon, self, pCommand->pData, argc, argv);
|
iRet = pCommand->OFunc(pCon, self, pCommand->pData, argc, argv);
|
||||||
MacroPop();
|
MacroPop();
|
||||||
|
|
||||||
/* delete argv */
|
deleteArgv:
|
||||||
for(i = 0; i < argc; i++)
|
if (argv) {
|
||||||
{
|
/* delete argv */
|
||||||
if(argv[i] != NULL)
|
for(i = 0; i < argc; i++)
|
||||||
{
|
{
|
||||||
free(argv[i]);
|
if(argv[i] != NULL)
|
||||||
}
|
{
|
||||||
|
free(argv[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(argv);
|
||||||
}
|
}
|
||||||
free(argv);
|
|
||||||
|
|
||||||
return iRet;
|
return iRet;
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
@ -319,23 +356,24 @@ extern char *SkipSpace(char *pPtr);
|
|||||||
float fVal;
|
float fVal;
|
||||||
pIDrivable pDriv = NULL;
|
pIDrivable pDriv = NULL;
|
||||||
void *pTest = NULL;
|
void *pTest = NULL;
|
||||||
|
char tmpfile[PATH_MAX];
|
||||||
|
int l;
|
||||||
|
|
||||||
assert(self);
|
assert(self);
|
||||||
assert(file);
|
assert(file);
|
||||||
|
|
||||||
/* open file */
|
/* make sure that status file is always valid M.Z. Apr 2005 */
|
||||||
fd = fopen(file,"w");
|
/* create a temporary file first */
|
||||||
if(!fd)
|
l=strlen(file);
|
||||||
{
|
if (l >= sizeof tmpfile - 2) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* remove it, as I found garbage from previous runs in the
|
strcpy(tmpfile, file);
|
||||||
status file
|
tmpfile[l]='.';
|
||||||
*/
|
tmpfile[l+1]='\0';
|
||||||
fclose(fd);
|
remove(tmpfile); /* remove already existing file */
|
||||||
remove(file);
|
|
||||||
|
|
||||||
fd = fopen(file,"w");
|
fd = fopen(tmpfile,"w");
|
||||||
if(!fd)
|
if(!fd)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@ -376,11 +414,15 @@ extern char *SkipSpace(char *pPtr);
|
|||||||
}
|
}
|
||||||
pCurrent = pCurrent->pNext;
|
pCurrent = pCurrent->pNext;
|
||||||
}
|
}
|
||||||
|
fclose(fd);
|
||||||
|
/* rename temporary to final file (this is an atomic action) */
|
||||||
|
if (0 > rename(tmpfile, file)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if(iMot)
|
if(iMot)
|
||||||
{
|
{
|
||||||
fprintf(fd,"Success \n");
|
fprintf(fd,"Success \n");
|
||||||
}
|
}
|
||||||
fclose(fd);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
@ -426,7 +468,10 @@ extern char *SkipSpace(char *pPtr);
|
|||||||
memory problem deep in the Tcl library. This causes a core dump on
|
memory problem deep in the Tcl library. This causes a core dump on
|
||||||
each SICS restart and breaks the use of external tools.
|
each SICS restart and breaks the use of external tools.
|
||||||
Tcl_DeleteInterp(pTcl);
|
Tcl_DeleteInterp(pTcl);
|
||||||
|
|
||||||
|
call KillSicsUnknown instead to clean up all memory properly. M.Z., Apr 05
|
||||||
*/
|
*/
|
||||||
|
KillSicsUnknown();
|
||||||
}
|
}
|
||||||
|
|
||||||
free(self);
|
free(self);
|
||||||
|
@ -30,6 +30,7 @@ typedef struct __Clist {
|
|||||||
void *pData;
|
void *pData;
|
||||||
struct __Clist *pNext;
|
struct __Clist *pNext;
|
||||||
struct __Clist *pPrevious;
|
struct __Clist *pPrevious;
|
||||||
|
int startupOnly;
|
||||||
} CommandList;
|
} CommandList;
|
||||||
|
|
||||||
typedef struct __SINTER
|
typedef struct __SINTER
|
||||||
@ -63,6 +64,12 @@ typedef struct __SINTER
|
|||||||
int RemoveCommand(SicsInterp *pInterp, char *pName);
|
int RemoveCommand(SicsInterp *pInterp, char *pName);
|
||||||
/* kills the command name from the interpreter pInterp
|
/* kills the command name from the interpreter pInterp
|
||||||
*/
|
*/
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
int AddCommandWithFlag(SicsInterp *pInterp, char *pName, ObjectFunc pFunc,
|
||||||
|
KillFunc pKFunc, void *pData, int startupFlag);
|
||||||
|
int AddIniCmd(char *pName, ObjectFunc pFunc); /* command will be deleted after startup */
|
||||||
|
int AddCmd(char *pName, ObjectFunc pFunc); /* syntactic sugar for AddCommand without data */
|
||||||
|
void RemoveStartupCommands(void); /* called after startup to delete startup commands */
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
int InterpExecute(SicsInterp *self,pSConnection pCon,char *pCommand);
|
int InterpExecute(SicsInterp *self,pSConnection pCon,char *pCommand);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user