/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- appinit_start
- appinit_stop
- appinit_waitfor
- appinit_register_name
- appinit_get_name
- appinit_remove_name
- appinit_get_sname
/* Application initialization/notification API.
Rick Smereka, Copyright (C) 2002-2004.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, get a copy via the Internet at
http://gnu.org/copyleft/gpl.html or write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
You can contact the author via email at rsmereka@future-lab.com
This API notifies other applications that the running program
is initializing. Notification is done through a lock file.
This API should be used by any program that depends on other
applications to be running before starting-up. This API also
provides a storage location for the application name in case
this name is required by another API outside of the main
program module.
Original Linux version. May/2002, Rick Smereka
Ported to 32-bit Windows. Jun/2002, Rick Smereka
Added functions to register and obtain the application name.
Ported to QNX 4.x. Jul/2002, Rick Smereka
Ported to Debian Linux. Nov/2002, Rick Smereka
Fixed bug in function 'appinit_get_name' that ignored whether
'appinit_apname' was NULL. Changed all logging calls from
'log_file_date' to 'logman'. Mar/2004, Rick Smereka */
#include "stdhead.h"
#include "appinit.h"
/* global module data */
char *appinit_apname = (char *)NULL;
/* private function */
static int appinit_get_sname(char *, char *);
int appinit_start(char *sname)
{
/* Indicate that the application is starting up by creating
a zero byte lock file. The parameter 'sname' should be a
unique name to identify the application and is usually
the 'socloc' service name when dealing with a socket
server. Function returns 'TRUE' upon success, 'FALSE'
otherwise. */
char *nsname, mname[] = "appinit_start";
logman("%s:enter:sname=%s", mname, sname);
if (sname == (char *)NULL || !strlen(sname))
{
logman("%s:exit:null or empty[sname]", mname);
return(FALSE);
}
if ((nsname = (char *)malloc(strlen(sname) + 5)) == (char *)NULL)
{
logman("%s:exit:alloc fail[nsname]", mname);
return(FALSE);
}
if (!appinit_get_sname(sname, nsname))
{
logman("%s:exit:bad rc[FALSE] from appinit_get_sname", mname);
free(nsname);
return(FALSE);
}
if (exist(nsname))
{
logman("%s:exit:lock file %s already exists", mname, nsname);
free(nsname);
return(FALSE);
}
if (!zcreate(nsname))
{
logman("%s:exit:bad rc[FALSE] from zcreate", mname);
free(nsname);
return(FALSE);
}
free(nsname);
logman("%s:normal exit[TRUE]", mname);
return(TRUE);
}
int appinit_stop(char *sname)
{
/* Indicate that the application has completed its
initialization by deleting the zero byte lock file.
The parameter 'sname' must be the same name used to
call 'appinit_start'. Function returns 'TRUE' upon
success, 'FALSE' otherwise. */
char *nsname, mname[] = "appinit_stop";
logman("%s:enter:sname=%s", mname, sname);
if (sname == (char *)NULL || !strlen(sname))
{
logman("%s:exit:null or empty[sname]", mname);
return(FALSE);
}
if ((nsname = (char *)malloc(strlen(sname) + 5)) == (char *)NULL)
{
logman("%s:exit:alloc fail[nsname]", mname);
return(FALSE);
}
if (!appinit_get_sname(sname, nsname))
{
logman("%s:exit:bad rc[FALSE] from appinit_get_sname", mname);
free(nsname);
return(FALSE);
}
if (!exist(nsname))
{
logman("%s:exit:lock file %s not present", mname, nsname);
free(nsname);
return(FALSE);
}
unlink(nsname);
free(nsname);
logman("%s:normal exit[TRUE]", mname);
return(TRUE);
}
int appinit_waitfor(char *sname, int min_timeout)
{
/* Check for a lock file using the name 'sname'. Wait
up to 'min_timeout' minutes for the lock file to be
removed. Function returns 'TRUE' if the lock file
no longer exists, 'FALSE' otherwise. */
time_t nowtime, target_time;
char *nsname, mname[] = "appinit_waitfor";
logman("%s:enter:sname=%s", mname, sname);
if (sname == (char *)NULL || !strlen(sname))
{
logman("%s:exit:null or empty[sname]", mname);
return(FALSE);
}
if (min_timeout <= 0)
{
logman("%s:exit:out of range[min_timeout]", mname);
return(FALSE);
}
if ((nsname = (char *)malloc(strlen(sname) + 5)) == (char *)NULL)
{
logman("%s:exit:alloc fail[nsname]", mname);
return(FALSE);
}
if (!appinit_get_sname(sname, nsname))
{
logman("%s:exit:bad rc[FALSE] from appinit_get_sname", mname);
free(nsname);
return(FALSE);
}
nowtime = time(NULL);
target_time = nowtime + (min_timeout * 60);
do
{
if (!exist(nsname))
{
logman("%s:normal exit[TRUE],lock file %s is not present",
mname, nsname);
free(nsname);
return(TRUE);
}
#ifdef OS_UNIX
/* use 'sleep' under Unix systems to block process */
sleep(2);
#endif
nowtime = time(NULL);
}
while(nowtime < target_time);
free(nsname);
logman("%s:exit[FALSE]:time expired", mname);
return(FALSE);
}
int appinit_register_name(char *apname)
{
/* Load the passed 'apname' into the module global
'appinit_apname'. Function returns 'TRUE' upon
success, 'FALSE' otherwise. */
char mname[] = "appinit_register_name";
int len, ret = FALSE;
logman("%s:enter", mname);
if (apname == (char *)NULL || !strlen(apname))
{
logman("%s:exit[FALSE]:null or empty[apname]", mname);
return(ret);
}
len = strlen(apname);
/* if name already allocated, de-allocate it */
if (appinit_apname != (char *)NULL)
if (!appinit_remove_name())
{
logman("%s:exit[FALSE]:bad rc from appinit_remove_name",
mname);
return(ret);
}
if ((appinit_apname = (char *)malloc(len + 1)) == (char *)NULL)
{
logman("%s:exit[FALSE]:alloc fail[appinit_apname]", mname);
return(ret);
}
strcpy(appinit_apname, apname);
ret = TRUE;
logman("%s:normal exit[TRUE]", mname);
return(ret);
}
int appinit_get_name(char *apname)
{
/* Obtain the application name which must already be defined
by calling the function 'appinit_register_name'. Function
returns 'TRUE' upon success with the application name
loaded into 'apname' (which must already be allocated to
sufficient size), 'FALSE' otherwise. */
char mname[] = "appinit_get_name";
int ret = FALSE;
logman("%s:enter", mname);
if (apname == (char *)NULL)
{
logman("%s:exit[FALSE]:null[apname]", mname);
return(ret);
}
apname[0] = EOS;
if (appinit_apname == (char *)NULL || !strlen(appinit_apname))
return(FALSE);
strcpy(apname, appinit_apname);
logman("%s:normal exit[TRUE]", mname);
ret = TRUE;
return(ret);
}
int appinit_remove_name(void)
{
/* De-allocate the current application name ('appinit_apname').
Function returns 'TRUE' upon success, 'FALSE' otherwise. */
char mname[] = "appinit_remove_name";
int ret = FALSE;
logman("%s:enter", mname);
if (appinit_apname == (char *)NULL || !strlen(appinit_apname))
{
logman("%s:exit[FALSE]:no application name present", mname);
return(ret);
}
free(appinit_apname);
appinit_apname = (char *)NULL;
logman("%s:normal exit[TRUE]", mname);
ret = TRUE;
return(ret);
}
static int appinit_get_sname(char *oldname, char *newname)
{
/* Translate an application name. The lock file extension
will be appended to the name. In addition, any QNX 4.x
nameloc name (starting with '/') will have its leading
slash removed. Function will load the translated name
into 'newname' which must already be allocated by the
caller to sufficient size. Function returns 'TRUE'
upon success, 'FALSE' otherwise. */
char mname[] = "appinit_get_sname";
logman("%s:enter:oldname=%s", mname, oldname);
if (oldname == (char *)NULL || !strlen(oldname))
{
logman("%s:exit:null or empty[oldname]", mname);
return(FALSE);
}
if (newname == (char *)NULL)
{
logman("%s:exit:null[newname]", mname);
return(FALSE);
}
newname[0] = EOS;
#ifdef IPC_QNX
if (oldname[0] == '/')
sprintf(newname, "%s.lck", &oldname[1]);
else
sprintf(newname, "%s.lck", oldname);
#else
sprintf(newname, "%s.lck", oldname);
#endif
logman("%s:normal exit[TRUE]:newname=%s", mname, newname);
return(TRUE);
}