[BusyBox] Re: busybox-cvs Digest, Vol 29, Issue 4
Rainer Weikusat
rainer.weikusat at sncag.com
Tue Aug 2 13:59:58 UTC 2005
"Vladimir N. Oleynik" <dzo at simtreas.ru> writes:
> pgf,
>
> What for you commiting all patches successively?
>
>
>> + /* there is no way for bb_getopt_ulflags() to
>> + * return us the argument string for long options
>> + * which don't have a short option equivalent.
>
> Its False. Have way: using non printable short option.
>
>> commiting:
>> 0000073: Add option to inetd applet to run in foreground
>> this option was already there for uclinux -- this just exposes
>> it in the normal case as well.
>
> Idioten patch. Absolytelly unecessary.
What actually is unecessary is that each and every program contains a
virtually identical sequence of code to turn it into a background
process, especially given that there is at least one program that
always runs in the background, namely, init, and which already
contains everything required to be a 'supervisor' process. For special
tasks that should run in the background, a tool can be used to just
start them that way (please note that the code below needs
POSIXLY_CORRECT=1 in the environment, to work around serious GNU
getopt braindamage, and that it contains some features that are specific
to the enviroment it usually operates in).
-------------------------------
/*
run a program in a background session
*/
char const eli_daemon_rscid[] = "$Id: daemon.c,v 1.6 2005/07/14 10:46:51 rw Exp $";
/* includes */
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <eli.h>
/* macros */
#define LOCK_PREFIX "\x1nlock-" /* also defined in nlock.c */
#define LOCK_PREFIX_LEN (sizeof(LOCK_PREFIX) - 1)
/* variables */
extern char **environ;
static int close_fds;
/* functions */
static int sys_die(char const *fnc, char const *sysc) __attribute__ ((noreturn));
static int sys_die(char const *fnc, char const *sysc)
{
syslog(LOG_ERR, "%s: %s: %m(%d)", fnc, sysc, errno);
exit(1);
}
static void usage(void)
{
syslog(LOG_NOTICE, "Usage: daemon [-c] [-f] <program> <arg> ...");
syslog(LOG_NOTICE, " c - remove lock parameters from environment");
syslog(LOG_NOTICE, " f - close descriptors except 0, 1, and 2");
exit(1);
}
static void remove_lock_params(void)
{
char **e_run, **e_last;
e_last = e_run = environ;
if (!*e_last) return;
while (e_last[1]) ++e_last;
e_run = environ;
while (e_run < e_last)
if (strncmp(*e_run, LOCK_PREFIX, LOCK_PREFIX_LEN) == 0) {
*e_run = *e_last;
*e_last-- = NULL;
} else
++e_run;
if (strncmp(*e_run, LOCK_PREFIX, LOCK_PREFIX_LEN) == 0) *e_run = NULL;
}
static char **parse_args(int argc, char **argv)
{
int c, had_c;
had_c = 0;
while ((c = getopt(argc, argv, "cf?h")) != -1)
switch (c) {
case 'c':
if (!had_c) remove_lock_params();
had_c = 1;
break;
case 'f':
close_fds = 1;
break;
case 'h':
case '?':
usage();
}
return argv + optind;
}
/* main */
int main(int argc, char **argv)
{
static int fds_to_pass[] = {
0, 1, 2, -1
};
char **cmdv;
int rc, is_std_fd;
openlog("daemon", LOG_PID | LOG_CONS | LOG_PERROR, LOG_DAEMON);
if (argc < 2) usage();
cmdv = parse_args(argc, argv);
rc = fork();
switch (rc) {
case -1:
sys_die(__FUNCTION__, "fork");
case 0:
break;
default:
_exit(0);
}
setsid();
signal(SIGHUP, SIG_IGN);
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
rc = open("/dev/null", O_RDWR, 0);
rc != -1 || sys_die(__FUNCTION__, "open");
is_std_fd = 0;
if (rc != 0) dup2(rc, 0);
else is_std_fd = 1;
if (rc != 1) dup2(rc, 1);
else is_std_fd = 1;
if (rc != 2) dup2(rc, 2);
else is_std_fd = 1;
if (!is_std_fd) close(rc);
if (close_fds) eli_close_unneeded_fds(fds_to_pass);
execvp(*cmdv, cmdv);
sys_die(__FUNCTION__, "execvp");
return 0;
}
More information about the busybox
mailing list