Revision eb505be1 os-posix.c

b/os-posix.c
39 39

  
40 40
static struct passwd *user_pwd;
41 41
static const char *chroot_dir;
42
static int daemonize;
43
static int fds[2];
42 44

  
43 45
void os_setup_early_signal_handling(void)
44 46
{
......
160 162
    case QEMU_OPTION_chroot:
161 163
        chroot_dir = optarg;
162 164
        break;
165
    case QEMU_OPTION_daemonize:
166
        daemonize = 1;
167
        break;
163 168
    }
164 169
    return;
165 170
}
......
196 201
    }
197 202

  
198 203
}
204

  
205
void os_daemonize(void)
206
{
207
    if (daemonize) {
208
	pid_t pid;
209

  
210
	if (pipe(fds) == -1)
211
	    exit(1);
212

  
213
	pid = fork();
214
	if (pid > 0) {
215
	    uint8_t status;
216
	    ssize_t len;
217

  
218
	    close(fds[1]);
219

  
220
	again:
221
            len = read(fds[0], &status, 1);
222
            if (len == -1 && (errno == EINTR))
223
                goto again;
224

  
225
            if (len != 1)
226
                exit(1);
227
            else if (status == 1) {
228
                fprintf(stderr, "Could not acquire pidfile: %s\n", strerror(errno));
229
                exit(1);
230
            } else
231
                exit(0);
232
	} else if (pid < 0)
233
            exit(1);
234

  
235
	close(fds[0]);
236
	qemu_set_cloexec(fds[1]);
237

  
238
	setsid();
239

  
240
	pid = fork();
241
	if (pid > 0)
242
	    exit(0);
243
	else if (pid < 0)
244
	    exit(1);
245

  
246
	umask(027);
247

  
248
        signal(SIGTSTP, SIG_IGN);
249
        signal(SIGTTOU, SIG_IGN);
250
        signal(SIGTTIN, SIG_IGN);
251
    }
252
}
253

  
254
void os_setup_post(void)
255
{
256
    int fd = 0;
257

  
258
    if (daemonize) {
259
	uint8_t status = 0;
260
	ssize_t len;
261

  
262
    again1:
263
	len = write(fds[1], &status, 1);
264
	if (len == -1 && (errno == EINTR))
265
	    goto again1;
266

  
267
	if (len != 1)
268
	    exit(1);
269

  
270
        if (chdir("/")) {
271
            perror("not able to chdir to /");
272
            exit(1);
273
        }
274
	TFR(fd = qemu_open("/dev/null", O_RDWR));
275
	if (fd == -1)
276
	    exit(1);
277
    }
278

  
279
    os_change_root();
280
    os_change_process_uid();
281

  
282
    if (daemonize) {
283
        dup2(fd, 0);
284
        dup2(fd, 1);
285
        dup2(fd, 2);
286

  
287
        close(fd);
288
    }
289
}
290

  
291
void os_pidfile_error(void)
292
{
293
    if (daemonize) {
294
        uint8_t status = 1;
295
        if (write(fds[1], &status, 1) != 1) {
296
            perror("daemonize. Writing to pipe\n");
297
        }
298
    } else
299
        fprintf(stderr, "Could not acquire pid file: %s\n", strerror(errno));
300
}

Also available in: Unified diff