When running in daemon mode, delay parent exit until device is created
Doing this is somewhat elaborate because cuse_lowlevel_main() when daemonizing, the parent (the calling thread) calls _exit(0) instead of returning.
This commit is contained in:
@@ -39,6 +39,8 @@ static struct ttynvt_param {
|
||||
/* Derived */
|
||||
char host[64];
|
||||
unsigned int port;
|
||||
/* Picked up */
|
||||
int foreground;
|
||||
} ttynvt_param;
|
||||
|
||||
typedef struct ttynvt {
|
||||
@@ -80,6 +82,22 @@ static void _log(int prio, const char *fmt, ...)
|
||||
if (ttynvt_param.debug) _log(LOG_DEBUG, __VA_ARGS__)
|
||||
|
||||
|
||||
static int _check_dev(void)
|
||||
{
|
||||
int rc;
|
||||
char dev_nbuf[128];
|
||||
struct stat st;
|
||||
|
||||
snprintf(dev_nbuf, sizeof(dev_nbuf), "/dev/%s", ttynvt_param.dev_name);
|
||||
|
||||
rc = stat(dev_nbuf, &st);
|
||||
|
||||
DBG("Checking for %s: %d\n", dev_nbuf, rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static void ttynvt_release(fuse_req_t req, struct fuse_file_info *info)
|
||||
{
|
||||
ttynvt_t *tty = (ttynvt_t *) (uintptr_t) info->fh;
|
||||
@@ -828,6 +846,8 @@ process_arg(void *data, const char *arg, int key, struct fuse_args *outargs)
|
||||
print_help();
|
||||
return fuse_opt_add_arg(outargs, "-ho");
|
||||
default:
|
||||
if (strcmp(arg, "-d") == 0 || strcmp(arg, "-f") == 0)
|
||||
ttynvt_param.foreground = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -839,6 +859,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
char dev_name[128];
|
||||
const char *dev_info_argv[] = { dev_name };
|
||||
pid_t cpid;
|
||||
|
||||
openlog("ttynvt", LOG_PID, LOG_DAEMON);
|
||||
|
||||
@@ -881,5 +902,41 @@ int main(int argc, char *argv[])
|
||||
.flags = CUSE_UNRESTRICTED_IOCTL,
|
||||
};
|
||||
|
||||
if (ttynvt_param.foreground)
|
||||
{
|
||||
return cuse_lowlevel_main(args.argc, args.argv, &ci, &ttynvt_op, NULL);
|
||||
}
|
||||
|
||||
cpid = fork();
|
||||
switch (cpid)
|
||||
{
|
||||
case -1:
|
||||
_log(LOG_ERR, "fork(): %m");
|
||||
return -1;
|
||||
|
||||
case 0: /* Child */
|
||||
DBG("Child proceeding...\n");
|
||||
rc = cuse_lowlevel_main(args.argc, args.argv, &ci, &ttynvt_op, NULL);
|
||||
if (rc != 0)
|
||||
_log(LOG_ERR, "ttynvt failed rc=%d", rc);
|
||||
else
|
||||
DBG("Child exited\n");
|
||||
return rc;
|
||||
|
||||
default: /* Parent */
|
||||
break;
|
||||
}
|
||||
|
||||
DBG("Parent proceeding (child=%d)...\n", cpid);
|
||||
|
||||
for (rc = 0; rc < 10; rc++)
|
||||
{
|
||||
if (_check_dev() == 0)
|
||||
break;
|
||||
usleep(500000);
|
||||
}
|
||||
|
||||
DBG("Parent exiting\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user