aboutsummaryrefslogtreecommitdiff
path: root/libbb/vfork_daemon_rexec.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-04-10 21:40:19 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-04-10 21:40:19 +0000
commitc6758a07c68033627a692cda27aebc8f6a662e7f (patch)
tree51bc0b498a5e16f8041604d913e25708cc76058f /libbb/vfork_daemon_rexec.c
parent335b63d8d1876ce4e172ebcc9d64544785682244 (diff)
downloadbusybox-w32-c6758a07c68033627a692cda27aebc8f6a662e7f.tar.gz
busybox-w32-c6758a07c68033627a692cda27aebc8f6a662e7f.tar.bz2
busybox-w32-c6758a07c68033627a692cda27aebc8f6a662e7f.zip
make compressed help code NOMMU- and NOFORK-friendly -
no forking anymore, bunzip2 unpack routine now does all it in memory.
Diffstat (limited to 'libbb/vfork_daemon_rexec.c')
-rw-r--r--libbb/vfork_daemon_rexec.c144
1 files changed, 46 insertions, 98 deletions
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index dabd1a6d6..cf88a2b28 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -102,120 +102,68 @@ int wait_pid(int *wstat, int pid)
102 102
103int spawn_and_wait(char **argv) 103int spawn_and_wait(char **argv)
104{ 104{
105#if ENABLE_FEATURE_EXEC_PREFER_APPLETS
105 int rc; 106 int rc;
107 const struct bb_applet *a = find_applet_by_name(argv[0]);
106 108
107#if ENABLE_FEATURE_EXEC_PREFER_APPLETS 109 if (a && (a->nofork
108 {
109 const struct bb_applet *a = find_applet_by_name(argv[0]);
110 if (a && (a->nofork
111#ifndef BB_NOMMU 110#ifndef BB_NOMMU
112 || a->noexec /* NOEXEC cannot be used on NOMMU */ 111 || a->noexec /* NOEXEC cannot be used on NOMMU */
113#endif 112#endif
114 )) { 113 )) {
115 int argc = 1; 114 int argc = 1;
116 char **pp = argv; 115 char **pp = argv;
117 while (*++pp) 116 while (*++pp)
118 argc++; 117 argc++;
119#ifndef BB_NOMMU 118#ifndef BB_NOMMU
120 if (a->nofork) 119 if (a->nofork)
121#endif 120#endif
122 { 121 {
123 int old_sleep = die_sleep; 122 int old_sleep = die_sleep;
124 int old_x = xfunc_error_retval; 123 int old_x = xfunc_error_retval;
125 die_sleep = -1; /* special flag */ 124 die_sleep = -1; /* special flag */
126 /* xfunc_die() checks for it */ 125 /* xfunc_die() checks for it */
127 126
128 rc = setjmp(die_jmp); 127 rc = setjmp(die_jmp);
129 if (!rc) { 128 if (!rc) {
130 const struct bb_applet *old_a = current_applet; 129 const struct bb_applet *old_a = current_applet;
131 current_applet = a; 130 current_applet = a;
132 applet_name = a->name; 131 applet_name = a->name;
133// what else should we save/restore? 132// what else should we save/restore?
134 rc = a->main(argc, argv); 133// TODO: what if applet will mangle argv vector?
135 current_applet = old_a; 134// xargs needs argv untouched because it frees the vector!
136 applet_name = old_a->name; 135// shouldn't we pass a copy?
137 } else { 136 rc = a->main(argc, argv);
138 /* xfunc died in NOFORK applet */ 137 current_applet = old_a;
139 if (rc == -111) 138 applet_name = old_a->name;
140 rc = 0; 139 } else {
141 } 140 /* xfunc died in NOFORK applet */
142 141 if (rc == -111)
143 die_sleep = old_sleep; 142 rc = 0;
144 xfunc_error_retval = old_x;
145 return rc;
146 } 143 }
144
145 die_sleep = old_sleep;
146 xfunc_error_retval = old_x;
147 return rc;
148 }
147#ifndef BB_NOMMU /* MMU only */ 149#ifndef BB_NOMMU /* MMU only */
148 /* a->noexec is true */ 150 /* a->noexec is true */
149 rc = fork(); 151 rc = fork();
150 if (rc) 152 if (rc)
151 goto w; 153 goto w;
152 /* child */ 154 /* child */
153 current_applet = a; 155 current_applet = a;
154 run_current_applet_and_exit(argc, argv); 156 run_current_applet_and_exit(argc, argv);
155#endif 157#endif
156 }
157
158 } 158 }
159 rc = spawn(argv); 159 rc = spawn(argv);
160 w: 160 w:
161#else /* !FEATURE_EXEC_PREFER_APPLETS */
162 rc = spawn(argv);
163#endif /* FEATURE_EXEC_PREFER_APPLETS */
164 return wait4pid(rc); 161 return wait4pid(rc);
165} 162#else /* !FEATURE_EXEC_PREFER_APPLETS */
166 163 return wait4pid(spawn(argv));
167
168#if 0 //ndef BB_NOMMU
169// Die with an error message if we can't daemonize.
170void xdaemon(int nochdir, int noclose)
171{
172 if (daemon(nochdir, noclose))
173 bb_perror_msg_and_die("daemon");
174}
175#endif 164#endif
176
177#if 0 // def BB_NOMMU
178void vfork_daemon_rexec(int nochdir, int noclose, char **argv)
179{
180 int fd;
181
182 /* Maybe we are already re-execed and come here again? */
183 if (re_execed)
184 return;
185
186 setsid();
187
188 if (!nochdir)
189 xchdir("/");
190
191 if (!noclose) {
192 /* if "/dev/null" doesn't exist, bail out! */
193 fd = xopen(bb_dev_null, O_RDWR);
194 dup2(fd, STDIN_FILENO);
195 dup2(fd, STDOUT_FILENO);
196 dup2(fd, STDERR_FILENO);
197 while (fd > 2)
198 close(fd--);
199 }
200
201 switch (vfork()) {
202 case 0: /* child */
203 /* Make certain we are not a session leader, or else we
204 * might reacquire a controlling terminal */
205 if (vfork())
206 _exit(0);
207 /* High-order bit of first char in argv[0] is a hidden
208 * "we have (alrealy) re-execed, don't do it again" flag */
209 argv[0][0] |= 0x80;
210 execv(CONFIG_BUSYBOX_EXEC_PATH, argv);
211 bb_perror_msg_and_die("exec %s", CONFIG_BUSYBOX_EXEC_PATH);
212 case -1: /* error */
213 bb_perror_msg_and_die("vfork");
214 default: /* parent */
215 exit(0);
216 }
217} 165}
218#endif /* BB_NOMMU */ 166
219 167
220#ifdef BB_NOMMU 168#ifdef BB_NOMMU
221void forkexit_or_rexec(char **argv) 169void forkexit_or_rexec(char **argv)