Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 30 additions & 16 deletions common/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -797,30 +797,25 @@ void open_syslog(const char *progname)
#endif /* WIN32 */
}

/* close ttys and become a daemon */
void background(void)
int background_fork(void)
{
/* Normally we enable SYSLOG and disable STDERR,
* unless NUT_DEBUG_SYSLOG envvar interferes as
* interpreted in syslog_is_disabled() method: */
int syslog_disabled = syslog_is_disabled(),
stderr_disabled = (syslog_disabled == 0 || syslog_disabled == 2);
int pid = 0;

#ifndef WIN32
int pid;

if ((pid = fork()) < 0)
fatal_with_errno(EXIT_FAILURE, "Unable to enter background");
#endif /* !WIN32 */

if (!syslog_disabled)
/* not disabled: NUT_DEBUG_SYSLOG is unset or invalid */
xbit_set(&upslog_flags, UPSLOG_SYSLOG);
if (stderr_disabled)
/* NUT_DEBUG_SYSLOG="none" or unset/invalid */
xbit_clear(&upslog_flags, UPSLOG_STDERR);
return pid;
}

/* close ttys and become a daemon */
void background(void)
{
#ifndef WIN32
int pid;

pid = background_fork();
if (pid != 0) {
/* parent */
/* these are typically fds 0-2: */
Expand All @@ -829,9 +824,28 @@ void background(void)
close(STDERR_FILENO);
_exit(EXIT_SUCCESS);
}
#else /* WIN32 */
NUT_WIN32_INCOMPLETE_MAYBE_NOT_APPLICABLE();
#endif /* WIN32 */
background_child();
}

void background_child(void)
{
/* Normally we enable SYSLOG and disable STDERR,
* unless NUT_DEBUG_SYSLOG envvar interferes as
* interpreted in syslog_is_disabled() method: */
int syslog_disabled = syslog_is_disabled(),
stderr_disabled = (syslog_disabled == 0 || syslog_disabled == 2);

/* child */
if (!syslog_disabled)
/* not disabled: NUT_DEBUG_SYSLOG is unset or invalid */
xbit_set(&upslog_flags, UPSLOG_SYSLOG);
if (stderr_disabled)
/* NUT_DEBUG_SYSLOG="none" or unset/invalid */
xbit_clear(&upslog_flags, UPSLOG_STDERR);

#ifndef WIN32
/* make fds 0-2 (typically) point somewhere defined */
# ifdef HAVE_DUP2
/* system can close (if needed) and (re-)open a specific FD number */
Expand Down
40 changes: 40 additions & 0 deletions drivers/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2188,6 +2188,7 @@ int main(int argc, char **argv)
# ifndef WIN32
int cmd = 0;
pid_t oldpid = -1;
int background_pipefd[2];
# else /* WIN32 */
/* FIXME NUT_WIN32_INCOMPLETE : *actually* handle WIN32 builds too */
const char * cmd = NULL;
Expand Down Expand Up @@ -2995,6 +2996,33 @@ int main(int argc, char **argv)
* when its a pdu! */
dstate_setinfo("device.type", "ups");

#ifndef WIN32
if (foreground == 0) {
/* start backgrounding */
int ret, pid;

ret = pipe(background_pipefd);
if (ret)
fatal_with_errno(EXIT_FAILURE, "pipe creation failed");

pid = background_fork();
if (pid > 0) {
/* parent: wait for child to send success or exit */
char ch;

close(background_pipefd[1]);
// Wait for child
ret = read(background_pipefd[0], &ch, 1);

close(background_pipefd[0]);
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
_exit(ret == 1 ? EXIT_SUCCESS : EXIT_FAILURE);
}
}
#endif

dstate_setinfo("driver.state", "init.device");
upsdrv_callbacks.upsdrv_initups();
dstate_setinfo("driver.state", "init.quiet");
Expand Down Expand Up @@ -3192,11 +3220,23 @@ int main(int argc, char **argv)

switch (foreground) {
case 0:
#ifndef WIN32
/* close handles */
background_child();

/* notify parent of success */
i = write(background_pipefd[1], "G", 1);
if (i < 1)
upslogx(LOG_ERR, "Unable to call parent pipe for shutdown");
close(background_pipefd[1]);
#else
background();
#endif
/* We had saved a PID before backgrounding, but
* it changes when backgrounding - so save again
*/
writepid(pidfn);

break;

/* >0: Keep the initial PID; don't care about "!dump_data" here
Expand Down
4 changes: 4 additions & 0 deletions include/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,10 @@ void open_syslog(const char *progname);
/* close ttys and become a daemon */
void background(void);

/* Support functions for backgrounding */
int background_fork(void);
void background_child(void);

/* allow tagging the (forked) process in logs to ease debugging */
const char *getproctag(void);
/* save a copy of tag, or call with NULL to clean and free the internal buffer;
Expand Down
Loading