static void report_gui_build(report_gui_t *rg, int browse) { char *argv[] = {NULL, NULL, NULL}; /* Only once... */ if ( rg->builder != NULL ) return; /* Check output file presence */ if ( access(rg->out->file->name, R_OK) != 0 ) { eprintf("Test Output file not found:\n%s", rg->out->file->name); return; } rg->build_then_browse = browse; /* Build HTML document */ argv[0] = "testfarm-report"; argv[1] = rg->out->file->name; rg->builder = child_spawn(argv, -1, -1, -1, (child_handler_t *) report_gui_build_terminated, rg); if ( rg->builder == NULL ) { status_mesg("Cannot execute report generator \"%s\"", argv[0]); } else { gtk_widget_set_sensitive(rg->rtv_build, 0); gtk_widget_set_sensitive(rg->rtv_view, 0); gtk_widget_set_sensitive(rg->rtv_view2, 0); } }
static void report_gui_proc_spawn(report_gui_proc_t *proc, char *argv[]) { int stdin_pipe[2]; /* Ensure everything is closed */ report_gui_proc_terminated(0, proc); /* Create command pipe */ if ( pipe(stdin_pipe) ) { fprintf(stderr, "Unable to create pipe for \"%s\": %s", argv[0], strerror(errno)); return; } fcntl(stdin_pipe[0], F_SETFD, 0); /* Disable close-on-exec mode on read endpoint */ fcntl(stdin_pipe[1], F_SETFD, FD_CLOEXEC); /* Enable close-on-exec mode on write endpoint */ proc->child = child_spawn(argv, stdin_pipe[0], -1 /* stdout */, -1 /* stderr */, (child_handler_t *) report_gui_proc_terminated, proc); /* Close now useless pipe endpoint */ close(stdin_pipe[0]); if ( proc->child == NULL ) { close(stdin_pipe[1]); status_mesg("Cannot execute process \"%s\"", argv[0]); } else { proc->stdin = stdin_pipe[1]; } }
static void report_gui_view(report_gui_t *rg) { static int null_stdout = -1; static int null_stderr = -1; char *argv[] = {NULL, NULL, NULL}; char *url; int size; /* Open /dev/null if not already done */ if (null_stdout < 0) { null_stdout = open("/dev/null", O_WRONLY); if (null_stdout < 0) { perror("Cannot open '/dev/null' for stdout redirection"); } } if (null_stdout >= 0) { fprintf(stderr, "Browser stdout redirected to /dev/null (fd=%d)\n", null_stdout); } if (null_stderr < 0) { null_stderr = open("/dev/null", O_WRONLY); if (null_stderr < 0) { perror("Cannot open '/dev/null' for stderr redirection"); } } if (null_stderr >= 0) { fprintf(stderr, "Browser stderr redirected to /dev/null (fd=%d)\n", null_stderr); } /* Build URL */ size = strlen(rg->report_name) + 6; url = (char *) malloc(size); snprintf(url, size, "file:%s", rg->report_name); /* Spawn HTML browser */ argv[0] = get_browser(); argv[1] = url; fprintf(stderr, "Start Test Report viewer: %s %s\n", argv[0], argv[1]); if (child_spawn(argv, -1 /* stdin */, null_stdout /* stdout */, null_stderr /* stderr */, (child_handler_t *) NULL, NULL) == NULL) { status_mesg("Cannot execute browser \"%s\"", argv[0]); } free(url); }
int skaclient_startf (skaclient_t_ref a, char const *prog, char const *const *argv, char const *const *envp, char const *banner, unsigned int bannerlen, uint32 options, struct taia const *deadline, struct taia *stamp) { int fds[2] ; unsigned int pid = child_spawn(prog, argv, envp, 0, 0, fds) ; if (!pid) return 0 ; a->pid = pid ; a->options = options ; skaclientin_init(&a->in, fds[0]) ; bufalloc_init(&a->out, &fd_write, fds[1]) ; if (!skaclient_readbanner(a, banner, bannerlen, deadline, stamp)) goto fail ; return 1 ; fail: { register int e = errno ; skaclient_end(a) ; errno = e ; } return 0 ; }
SAL_IMPLEMENT_MAIN_WITH_ARGS( argc, argv ) { sal_Bool bSentArgs = sal_False; const char* pUsePlugin; rtl_uString *pPipePath = NULL; Args *args; int status = 0; struct splash* splash = NULL; struct sigaction sigpipe_action; struct sigaction sigterm_action; /* turn SIGPIPE into an error */ memset(&sigpipe_action, 0, sizeof(struct sigaction)); sigpipe_action.sa_handler = SIG_IGN; sigemptyset(&sigpipe_action.sa_mask); sigaction(SIGPIPE, &sigpipe_action, NULL); memset(&sigterm_action, 0, sizeof(struct sigaction)); sigterm_action.sa_handler = &sigterm_handler; sigemptyset(&sigterm_action.sa_mask); sigaction(SIGTERM, &sigterm_action, NULL); args = args_parse (); args->pAppPath = get_app_path( argv[0] ); if ( !args->pAppPath ) { fprintf( stderr, "ERROR: Can't read app link\n" ); exit( 1 ); } #ifndef ENABLE_QUICKSTART_LIBPNG /* we can't load and render it anyway */ args->bInhibitSplash = sal_True; #endif pUsePlugin = getenv( "SAL_USE_VCLPLUGIN" ); if ( pUsePlugin && !strcmp(pUsePlugin, "svp") ) args->bInhibitSplash = sal_True; if ( !args->bInhibitPipe && getenv("LIBO_XDGAPP") == NULL ) { int fd = 0; pPipePath = get_pipe_path( args->pAppPath ); if ( ( fd = connect_pipe( pPipePath ) ) >= 0 ) { // Wait for answer char resp[ strlen( "InternalIPC::SendArguments" ) + 1]; ssize_t n = read( fd, resp, SAL_N_ELEMENTS( resp ) ); if (n == (ssize_t) SAL_N_ELEMENTS( resp ) && (memcmp( resp, "InternalIPC::SendArguments", SAL_N_ELEMENTS( resp ) - 1) == 0)) { rtl_uString *pCwdPath = NULL; osl_getProcessWorkingDir( &pCwdPath ); // Then send args bSentArgs = send_args( fd, pCwdPath ); } close( fd ); } } if ( !bSentArgs ) { /* we have to prepare for, and exec the binary */ int nPercent = 0; ChildInfo *info; sal_Bool bAllArgs = sal_True; sal_Bool bShortWait, bRestart; /* sanity check pieces */ system_checks(); /* load splash image and create window */ if ( !args->bInhibitSplash ) { splash = splash_create(args->pAppPath, argc, argv); } /* pagein */ if (!args->bInhibitPagein) exec_pagein (args); /* javaldx */ #if HAVE_FEATURE_JAVA if (!args->bInhibitJavaLdx) exec_javaldx (args); #endif do { bRestart = sal_False; /* fast updates if we have somewhere to update it to */ bShortWait = splash ? sal_True : sal_False; /* Periodically update the splash & the percent according to what status_fd says, poll quickly only while starting */ info = child_spawn (args, bAllArgs, bShortWait); g_pProcess = info->child; while (!child_exited_wait (info, bShortWait)) { ProgressStatus eResult; splash_draw_progress( splash, nPercent ); eResult = read_percent( info, &nPercent ); if (eResult != ProgressContinue) { splash_destroy(splash); splash = NULL; bShortWait = sal_False; } } status = child_get_exit_code(info); g_pProcess = NULL; // reset switch (status) { case EXITHELPER_CRASH_WITH_RESTART: // re-start with just -env: parameters bRestart = sal_True; bAllArgs = sal_False; break; case EXITHELPER_NORMAL_RESTART: // re-start with all arguments bRestart = sal_True; bAllArgs = sal_True; break; default: break; } child_info_destroy (info); } while (bRestart); } /* cleanup */ if ( pPipePath ) rtl_uString_release( pPipePath ); args_free (args); return status; }
static int sub_item_spawn(sub_item_t *sub, char **argv, char **errmsg) { int stdin_pipe[2]; int stdout_pipe[2]; child_t *child; int size; /* Check access to command */ if ( access(argv[0], X_OK) == -1 ) { *errmsg = "Cannot access command for execution"; return -1; } /* Create standard input pipe */ if ( pipe(stdin_pipe) == -1 ) { *errmsg = "Cannot create standard input pipe"; return -1; } /* Create standard output pipe */ if ( pipe(stdout_pipe) == -1 ) { close(stdin_pipe[0]); close(stdin_pipe[1]); *errmsg = "Cannot create standard output pipe"; return -1; } /* Enable close-on-exec mode on local pipe endpoints */ fcntl(stdin_pipe[1], F_SETFD, FD_CLOEXEC); fcntl(stdout_pipe[0], F_SETFD, FD_CLOEXEC); /* Create process */ child = child_spawn(argv, stdin_pipe[0], stdout_pipe[1], -1, (child_handler_t *) sub_sigchld, sub); if ( child == NULL ) { close(stdin_pipe[0]); close(stdin_pipe[1]); close(stdout_pipe[0]); close(stdout_pipe[1]); *errmsg = "Cannot fork subprocess"; return -1; } /* Feed command line */ sub->cmd = NULL; size = 0; while ( *argv != NULL ) { char *str = *argv; int len = strlen(str); sub->cmd = (char *) realloc(sub->cmd, size+len+2); strcpy(&((sub->cmd)[size]), str); size += len; argv++; if ( *argv != NULL ) sub->cmd[size++] = ' '; }; /* Set child descriptor */ sub->child = child; /* Feed standard i/o descriptors */ close(stdin_pipe[0]); sub->stdin_fd = stdin_pipe[1]; //fcntl(sub->stdin_fd, F_SETFL, O_NONBLOCK); close(stdout_pipe[1]); sub->stdout_fd = stdout_pipe[0]; fcntl(sub->stdout_fd, F_SETFL, O_NONBLOCK); return 0; }
int main (int argc, char const *const *argv, char const *const *envp) { unsigned int nb = 0, ex = 1 ; unsigned int timeout = 0 ; PROG = "s6-setlock" ; for (;;) { register int opt = subgetopt(argc, argv, "nNrwt:") ; if (opt == -1) break ; switch (opt) { case 'n' : nb = 1 ; break ; case 'N' : nb = 0 ; break ; case 'r' : ex = 0 ; break ; case 'w' : ex = 1 ; break ; case 't' : if (!uint0_scan(subgetopt_here.arg, &timeout)) dieusage() ; nb = 2 ; break ; default : dieusage() ; } } argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ; if (argc < 2) dieusage() ; if (nb < 2) { int fd = open_create(argv[0]) ; if (fd == -1) strerr_diefu2sys(111, "open_create ", argv[0]) ; if ((*f[ex][nb])(fd) == -1) strerr_diefu2sys(1, "lock ", argv[0]) ; } else { char const *cargv[3] = { "s6lockd-helper", argv[0], 0 } ; char const *cenvp[2] = { ex ? "S6LOCK_EX=1" : 0, 0 } ; iopause_fd x = { .events = IOPAUSE_READ } ; tain_t deadline ; int p[2] ; unsigned int pid ; char c ; tain_now_g() ; tain_from_millisecs(&deadline, timeout) ; tain_add_g(&deadline, &deadline) ; pid = child_spawn(S6_LIBEXECPREFIX "s6lockd-helper", cargv, cenvp, p, 2) ; if (!pid) strerr_diefu2sys(111, "spawn ", S6_LIBEXECPREFIX "s6lockd-helper") ; x.fd = p[0] ; for (;;) { register int r = iopause_g(&x, 1, &deadline) ; if (r < 0) strerr_diefu1sys(111, "iopause") ; if (!r) { kill(pid, SIGTERM) ; errno = ETIMEDOUT ; strerr_diefu1sys(1, "acquire lock") ; } r = sanitize_read(fd_read(p[0], &c, 1)) ; if (r < 0) strerr_diefu1sys(111, "read ack from helper") ; if (r) break ; } if (c != '!') strerr_dief1x(111, "helper sent garbage ack") ; fd_close(p[0]) ; if (uncoe(p[1]) < 0) strerr_diefu1sys(111, "uncoe fd to helper") ; } pathexec_run(argv[1], argv+1, envp) ; strerr_dieexec(111, argv[1]) ; }