- 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:
zolliker
2005-09-05 08:14:33 +00:00
parent ba6cf90ab3
commit 476ad8d672
2 changed files with 94 additions and 42 deletions

129
SCinter.c
View File

@ -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);

View File

@ -30,6 +30,7 @@ typedef struct __Clist {
void *pData;
struct __Clist *pNext;
struct __Clist *pPrevious;
int startupOnly;
} CommandList;
typedef struct __SINTER
@ -63,6 +64,12 @@ typedef struct __SINTER
int RemoveCommand(SicsInterp *pInterp, char *pName);
/* 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);