- 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:
129
SCinter.c
129
SCinter.c
@ -62,9 +62,6 @@
|
||||
#include "definealias.h"
|
||||
|
||||
|
||||
#define MAXLEN 256
|
||||
#define MAXPAR 100
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
SicsInterp *InitInterp(void)
|
||||
{
|
||||
@ -91,10 +88,11 @@
|
||||
return pInter;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
int AddCommand(SicsInterp *pInterp, char *pName, ObjectFunc pFunc,
|
||||
KillFunc pKFunc, void *pData)
|
||||
int AddCommandWithFlag(SicsInterp *pInterp, char *pName, ObjectFunc pFunc,
|
||||
KillFunc pKFunc, void *pData, int startupOnly)
|
||||
{
|
||||
CommandList *pNew = NULL;
|
||||
CommandList *p, *tail;
|
||||
char pBueffel[512];
|
||||
|
||||
assert(pName);
|
||||
@ -134,19 +132,42 @@
|
||||
pNew->OFunc = pFunc;
|
||||
pNew->KFunc = pKFunc;
|
||||
pNew->pData = pData;
|
||||
pNew->pNext = pInterp->pCList;
|
||||
pNew->pNext = NULL;
|
||||
pNew->startupOnly = startupOnly;
|
||||
|
||||
|
||||
if(pInterp->pCList)
|
||||
/* find end of list */
|
||||
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;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
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)
|
||||
{
|
||||
@ -198,10 +219,21 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define MAXLEN 256
|
||||
#define MAXCOM 50
|
||||
extern char *stptok(char *s, char *tok, unsigned int toklen, char *brk);
|
||||
extern char *SkipSpace(char *pPtr);
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
void RemoveStartupCommands(void)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -233,18 +265,21 @@ extern char *SkipSpace(char *pPtr);
|
||||
|
||||
/* convert to argc, argv */
|
||||
argc = 0;
|
||||
argv = NULL;
|
||||
Text2Arg(pText,&argc,&argv);
|
||||
|
||||
/* the first one must be the target object. If not given an empty
|
||||
command string was given which will be silently ignored */
|
||||
if(argc < 1)
|
||||
{
|
||||
return 1;
|
||||
iRet = 1;
|
||||
goto deleteArgv;
|
||||
}
|
||||
if(argv[0] == NULL)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: failed to parse command",eError);
|
||||
return -1;
|
||||
SCWrite(pCon,"ERROR: failed to parse command",eError);
|
||||
iRet = -1;
|
||||
goto deleteArgv;
|
||||
}
|
||||
|
||||
/* find it */
|
||||
@ -254,8 +289,8 @@ extern char *SkipSpace(char *pPtr);
|
||||
sprintf(pBueffel,"ERROR: Object -> %s <- NOT found",
|
||||
argv[0]);
|
||||
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);
|
||||
MacroPop();
|
||||
|
||||
/* delete argv */
|
||||
for(i = 0; i < argc; i++)
|
||||
{
|
||||
if(argv[i] != NULL)
|
||||
{
|
||||
free(argv[i]);
|
||||
}
|
||||
deleteArgv:
|
||||
if (argv) {
|
||||
/* delete argv */
|
||||
for(i = 0; i < argc; i++)
|
||||
{
|
||||
if(argv[i] != NULL)
|
||||
{
|
||||
free(argv[i]);
|
||||
}
|
||||
}
|
||||
free(argv);
|
||||
}
|
||||
free(argv);
|
||||
|
||||
return iRet;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
@ -319,23 +356,24 @@ extern char *SkipSpace(char *pPtr);
|
||||
float fVal;
|
||||
pIDrivable pDriv = NULL;
|
||||
void *pTest = NULL;
|
||||
|
||||
char tmpfile[PATH_MAX];
|
||||
int l;
|
||||
|
||||
assert(self);
|
||||
assert(file);
|
||||
|
||||
/* open file */
|
||||
fd = fopen(file,"w");
|
||||
if(!fd)
|
||||
{
|
||||
/* make sure that status file is always valid M.Z. Apr 2005 */
|
||||
/* create a temporary file first */
|
||||
l=strlen(file);
|
||||
if (l >= sizeof tmpfile - 2) {
|
||||
return 0;
|
||||
}
|
||||
/* remove it, as I found garbage from previous runs in the
|
||||
status file
|
||||
*/
|
||||
fclose(fd);
|
||||
remove(file);
|
||||
strcpy(tmpfile, file);
|
||||
tmpfile[l]='.';
|
||||
tmpfile[l+1]='\0';
|
||||
remove(tmpfile); /* remove already existing file */
|
||||
|
||||
fd = fopen(file,"w");
|
||||
fd = fopen(tmpfile,"w");
|
||||
if(!fd)
|
||||
{
|
||||
return 0;
|
||||
@ -376,11 +414,15 @@ extern char *SkipSpace(char *pPtr);
|
||||
}
|
||||
pCurrent = pCurrent->pNext;
|
||||
}
|
||||
fclose(fd);
|
||||
/* rename temporary to final file (this is an atomic action) */
|
||||
if (0 > rename(tmpfile, file)) {
|
||||
return 0;
|
||||
}
|
||||
if(iMot)
|
||||
{
|
||||
fprintf(fd,"Success \n");
|
||||
}
|
||||
fclose(fd);
|
||||
return 1;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
@ -426,7 +468,10 @@ extern char *SkipSpace(char *pPtr);
|
||||
memory problem deep in the Tcl library. This causes a core dump on
|
||||
each SICS restart and breaks the use of external tools.
|
||||
Tcl_DeleteInterp(pTcl);
|
||||
|
||||
call KillSicsUnknown instead to clean up all memory properly. M.Z., Apr 05
|
||||
*/
|
||||
KillSicsUnknown();
|
||||
}
|
||||
|
||||
free(self);
|
||||
|
Reference in New Issue
Block a user