119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * logsave.c --- A program which saves the output of a program until 319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * /var/log is mounted. 419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 2003 Theodore Ts'o. 619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %Begin-Header% 819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This file may be redistributed under the terms of the GNU Public 919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * License. 1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %End-Header% 1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdio.h> 1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdlib.h> 1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <unistd.h> 1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h> 1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/types.h> 1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/wait.h> 1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <fcntl.h> 2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <time.h> 2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <errno.h> 2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_GETOPT_H 2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <getopt.h> 2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#else 2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectextern char *optarg; 2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectextern int optind; 2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint outfd = -1; 3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint outbufsize = 0; 3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectvoid *outbuf = 0; 3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint verbose = 0; 3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint do_skip = 0; 3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint skip_mode = 0; 3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void usage(char *progname) 3719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("Usage: %s [-v] [-d dir] logfile program\n", progname); 3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define SEND_LOG 0x01 4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define SEND_CONSOLE 0x02 4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define SEND_BOTH 0x03 4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void send_output(const char *buffer, int c, int flag) 4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *n; 4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (c == 0) 5119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project c = strlen(buffer); 5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 5319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (flag & SEND_CONSOLE) 5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project write(1, buffer, c); 5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!(flag & SEND_LOG)) 5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (outfd > 0) 5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project write(outfd, buffer, c); 5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else { 6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project n = realloc(outbuf, outbufsize + c); 6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (n) { 6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project outbuf = n; 6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project memcpy(((char *)outbuf)+outbufsize, buffer, c); 6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project outbufsize += c; 6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int do_read(int fd) 7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int c; 7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char buffer[4096], *cp, *sep; 7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project c = read(fd, buffer, sizeof(buffer)-1); 7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (c <= 0) 7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return c; 7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (do_skip) { 7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project send_output(buffer, c, SEND_CONSOLE); 7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project buffer[c] = 0; 8019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cp = buffer; 8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (*cp) { 8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (skip_mode) { 8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cp = strchr(cp, '\002'); 8419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!cp) 8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cp++; 8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project skip_mode = 0; 8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project continue; 8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sep = strchr(cp, '\001'); 9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (sep) 9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *sep = 0; 9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project send_output(cp, 0, SEND_LOG); 9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (sep) { 9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cp = sep + 1; 9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project skip_mode = 1; 9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else 9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else 10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project send_output(buffer, c, SEND_BOTH); 10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return c; 10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int run_program(char **argv) 10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int fds[2]; 10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int status, rc, pid; 10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char buffer[80]; 11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pipe(fds) < 0) { 11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project perror("pipe"); 11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pid = fork(); 11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pid < 0) { 11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project perror("vfork"); 11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pid == 0) { 12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dup2(fds[1],1); /* fds[1] replaces stdout */ 12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dup2(fds[1],2); /* fds[1] replaces stderr */ 12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project close(fds[0]); /* don't need this here */ 12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project execvp(argv[0], argv); 12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project perror(argv[0]); 12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 13019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project close(fds[1]); 13119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (!(waitpid(pid, &status, WNOHANG ))) { 13319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project do_read(fds[0]); 13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project do_read(fds[0]); 13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project close(fds[0]); 13719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 13819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ( WIFEXITED(status) ) { 13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project rc = WEXITSTATUS(status); 14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (rc) { 14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project send_output(argv[0], 0, SEND_BOTH); 14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sprintf(buffer, " died with exit status %d\n", rc); 14319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project send_output(buffer, 0, SEND_BOTH); 14419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 14519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (WIFSIGNALED(status)) { 14719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project send_output(argv[0], 0, SEND_BOTH); 14819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sprintf(buffer, "died with signal %d\n", 14919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project WTERMSIG(status)); 15019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project send_output(buffer, 0, SEND_BOTH); 15119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project rc = 1; 15219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 15319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project rc = 0; 15419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return rc; 15619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 15719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 15819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int copy_from_stdin(void) 15919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 16019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int c, bad_read = 0; 16119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 16219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (1) { 16319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project c = do_read(0); 16419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((c == 0 ) || 16519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ((c < 0) && ((errno == EAGAIN) || (errno == EINTR)))) { 16619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (bad_read++ > 3) 16719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 16819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project continue; 16919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 17019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (c < 0) { 17119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project perror("read"); 17219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 17319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 17419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bad_read = 0; 17519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 17619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 17719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 17819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 17919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 18019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 18119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint main(int argc, char **argv) 18219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 18319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int c, pid, rc; 18419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *outfn, **cpp; 18519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int openflags = O_CREAT|O_WRONLY|O_TRUNC; 18619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int send_flag = SEND_LOG; 18719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int do_stdin; 18819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project time_t t; 18919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 19019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while ((c = getopt(argc, argv, "+asv")) != EOF) { 19119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project switch (c) { 19219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 'a': 19319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project openflags &= ~O_TRUNC; 19419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project openflags |= O_APPEND; 19519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 19619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 's': 19719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project do_skip = 1; 19819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 19919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 'v': 20019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project verbose++; 20119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project send_flag |= SEND_CONSOLE; 20219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 20319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 20419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 20519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (optind == argc || optind+1 == argc) 20619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project usage(argv[0]); 20719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project outfn = argv[optind]; 20819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project optind++; 20919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project argv += optind; 21019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project argc -= optind; 21119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 21219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project outfd = open(outfn, openflags, 0644); 21319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project do_stdin = !strcmp(argv[0], "-"); 21419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 21519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project send_output("Log of ", 0, send_flag); 21619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (do_stdin) 21719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project send_output("stdin", 0, send_flag); 21819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else { 21919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (cpp = argv; *cpp; cpp++) { 22019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project send_output(*cpp, 0, send_flag); 22119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project send_output(" ", 0, send_flag); 22219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 22319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 22419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project send_output("\n", 0, send_flag); 22519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project t = time(0); 22619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project send_output(ctime(&t), 0, send_flag); 22719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project send_output("\n", 0, send_flag); 22819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 22919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (do_stdin) 23019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project rc = copy_from_stdin(); 23119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else 23219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project rc = run_program(argv); 23319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 23419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project send_output("\n", 0, send_flag); 23519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project t = time(0); 23619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project send_output(ctime(&t), 0, send_flag); 23719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project send_output("----------------\n", 0, send_flag); 23819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 23919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (outbuf) { 24019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pid = fork(); 24119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pid < 0) { 24219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project perror("fork"); 24319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 24419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 24519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pid) { 24619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (verbose) 24719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("Backgrounding to save %s later\n", 24819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project outfn); 24919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(rc); 25019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 25119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project setsid(); /* To avoid getting killed by init */ 25219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (outfd < 0) { 25319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project outfd = open(outfn, openflags, 0644); 25419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sleep(1); 25519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 25619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project write(outfd, outbuf, outbufsize); 25719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project free(outbuf); 25819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 25919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project close(outfd); 26019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 26119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(rc); 26219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 263