Skip to content
Draft
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
48 changes: 29 additions & 19 deletions common/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -797,29 +797,24 @@ 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)
{
int pid;

pid = background_fork();
#ifndef WIN32
if (pid != 0) {
/* parent */
Expand All @@ -829,8 +824,26 @@ void background(void)
close(STDERR_FILENO);
_exit(EXIT_SUCCESS);
}
#else /* WIN32 */
NUT_WIN32_INCOMPLETE_MAYBE_NOT_APPLICABLE();
#endif /* WIN32 */
background_child();
}

/* 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);

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

/* make fds 0-2 (typically) point somewhere defined */
# ifdef HAVE_DUP2
Expand Down Expand Up @@ -887,9 +900,6 @@ void background(void)
# ifdef HAVE_SETSID
setsid(); /* make a new session to dodge signals */
# endif
#else /* WIN32 */
NUT_WIN32_INCOMPLETE_MAYBE_NOT_APPLICABLE();
#endif /* WIN32 */

upslogx(LOG_INFO, "Startup successful: %s", getmyprocbasename());
}
Expand Down
36 changes: 35 additions & 1 deletion drivers/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2184,6 +2184,7 @@ int main(int argc, char **argv)
struct passwd *new_uid = NULL;
int opt_ret = 0, do_forceshutdown = 0, i;
int update_count = 0;
int background_pipefd[2];

# ifndef WIN32
int cmd = 0;
Expand Down Expand Up @@ -2995,6 +2996,31 @@ int main(int argc, char **argv)
* when its a pdu! */
dstate_setinfo("device.type", "ups");

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

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

switch (foreground) {
case 0:
background();
/* We had saved a PID before backgrounding, but
* it changes when backgrounding - so save again
*/
writepid(pidfn);

/* 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]);
break;

/* >0: Keep the initial PID; don't care about "!dump_data" here
Expand Down
5 changes: 5 additions & 0 deletions drivers/usbhid-ups.c
Original file line number Diff line number Diff line change
Expand Up @@ -1971,9 +1971,13 @@ void upsdrv_cleanup(void)
comm_driver->close_dev(udev);
Free_ReportDesc(pDesc);
free_report_buffer(reportbuf);
pDesc = NULL;
reportbuf = NULL;
#if !((defined SHUT_MODE) && SHUT_MODE)
USBFreeExactMatcher(exact_matcher);
USBFreeRegexMatcher(regex_matcher);
exact_matcher = NULL;
regex_matcher = NULL;

free(curDevice.Vendor);
free(curDevice.Product);
Expand All @@ -1983,6 +1987,7 @@ void upsdrv_cleanup(void)
# if (defined WITH_USB_BUSPORT) && (WITH_USB_BUSPORT)
free(curDevice.BusPort);
# endif
memset(&curDevice, '\0', sizeof(curDevice));
#endif /* !SHUT_MODE => USB */
}

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