Is there a way to ensure that a program has only a single instance running (on neutrino)?
Previously on QNX4…it could be done using qnx_name_attach and qnx_name_locate. Is it a direct mapping to name_attach and name_open?
Or is there a better way to do it?
Hmm…looks like I was not on the wrong path after all.
So I hope the skeleton:
Step1: name_open with tests for - a return of -1 and then errno for EBUSY, followed by an exit.
Step2: name_attach with a MsgReply of EOK for a _IO_CONNECT
Step3: name_open for any further processing
would be the basic principle for ensuring the single instance?
This is an overly simplistic solution. I could easily be expanded to handler multiple different programs. You could also hide the client interface fairly easily. If the code looks familiar, it mostly right out of Robert Krytn’s book “Getting Started with QNX Neutrion 2”
singl_mgr.c:
#include <libc.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>
char device_name[64] = "/dev/mypgm";
//
// This variable is either 0 or 1 indicating whether the program is already
// running
//
#define TRUE 1
#define FALSE 0
int opened;
int io_open(resmgr_context_t *ctp, io_open_t *msg,
RESMGR_HANDLE_T *handle, void *extra);
int io_close(resmgr_context_t *ctp, void *reserved, RESMGR_OCB_T *ocb);
int main (int argc, char **argv)
{
dispatch_t *dpp;
resmgr_attr_t resmgr_attr;
resmgr_context_t *ctp;
resmgr_connect_funcs_t cfuncs;
resmgr_io_funcs_t ifuncs;
iofunc_attr_t attr;
if (argc > 1)
{
if (argv[1][0] == '-' && argv[1][1] == 'n')
{
strcpy(device_name,argv[1]+2);
}
}
fprintf(stderr,"%s: using name %s\n",argv[0],device_name);
if ((dpp = dispatch_create()) == NULL)
{
perror("error: dispatch_create\n");
exit(EXIT_FAILURE);
}
iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);
memset(&resmgr_attr, 0, sizeof(resmgr_attr));
resmgr_attr.nparts_max = 1;
resmgr_attr.msg_max_size = 2048;
iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &cfuncs,
_RESMGR_IO_NFUNCS, &ifuncs);
cfuncs.open = &io_open;
ifuncs.close_ocb = &io_close;
if (resmgr_attach(dpp, &resmgr_attr, device_name, _FTYPE_ANY, 0, &cfuncs,
&ifuncs, &attr) == -1)
{
perror("error: resmgr_attach\n");
exit(EXIT_FAILURE);
}
opened = 0;
ctp = resmgr_context_alloc(dpp);
while(1)
{
if ((ctp = resmgr_block(ctp)) == NULL)
{
perror("error: resmgr_block\n");
exit(EXIT_FAILURE);
}
resmgr_handler(ctp);
}
}
int io_open(resmgr_context_t *ctp, io_open_t *msg,
RESMGR_HANDLE_T *handle, void *extra)
{
int ret;
if (opened)
{
return(EBUSY);
}
ret = iofunc_open_default(ctp,msg,handle,extra);
if (ret == EOK)
{
opened = TRUE;
}
return(ret);
}
singl_client.c:
int io_close(resmgr_context_t *ctp, void *reserved, RESMGR_OCB_T *ocb)
{
int ret;
opened = 0;
return(iofunc_close_ocb_default(ctp,reserved,ocb));
}
#include <libc.h>
int main()
{
FILE *fp;
fp = fopen("/dev/mypgm","r");
if (fp == NULL)
{
fprintf(stderr,"singl_client is already running\n");
exit(-1);
}
fprintf(stderr,"I can run now\n");
sleep(20);
fprintf(stderr,"Done\n");
}