static int lconnect(lua_State *L) { HANDLE pipe = connect_pipe(luaL_checkstring(L,1)); if (pipe == INVALID_HANDLE_VALUE) return luaL_error(L, "connect failed"); lua_pushlightuserdata(L, pipe); return 1; }
int launch_one_cmd(t_cmd *cmd, t_cmd *next) { int ret; connect_file(cmd); connect_pipe(cmd, next); if ((ret = exec_builtin(cmd)) == -1) { return (launch_fork(cmd)); } cmd->return_val = ret; return (0); }
int init_supervisor(supervisor_thread_t *thiz, tesr_config_t *config) { LOG_LOC; int ret = 0; if(thiz && config) { thiz->config = config; if(thiz->config->num_workers == 0) { LOG_WARN("you are running in single threaded mode (num_workers=0)\n"); } ret = bind_dgram_socket(&thiz->sd, &thiz->addr, thiz->config->recv_port); if (ret == 0) { LOG_ERROR("could not bind dgram socket\n"); exit(EXIT_FAILURE); } else { thiz->queue = create_queue(); init_queue(thiz->queue); connect_pipe(&thiz->int_fd, &thiz->ext_fd); thiz->event_loop = EV_DEFAULT; //or ev_default_loop (0); //Set up rate limiting thiz->rate_limiter = create_rate_limiter(); init_rate_limiter(thiz->rate_limiter, thiz->config->irl_max, thiz->config->irl_inactivity_timeout, thiz->config->irl_garbage_collect_count); //Initialize pthread thiz->next_thread_idx = 0; thiz->worker_threads = create_worker_array(thiz->config->num_workers); //We must initialize workers last as we pass the supervisor data to them int th=0; for(th=0; th < thiz->config->num_workers; th++) { thiz->worker_threads[th] = create_worker(); init_worker(thiz->worker_threads[th], thiz, th); pthread_attr_t attr; pthread_attr_init(&attr); pthread_create(&thiz->worker_threads[th]->thread, &attr, worker_thread_run, thiz->worker_threads[th]); } ev_io_init(&thiz->udp_read_watcher, udp_read_cb, thiz->sd, EV_READ); ev_io_init(&thiz->inbox_watcher, udp_write_cb, thiz->int_fd, EV_READ); ev_signal_init(&thiz->sigint_watcher, sigint_cb, SIGINT); ev_signal_init(&thiz->sigchld_watcher, sigchld_cb, SIGCHLD); } } return ret; }
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; }
int main(int argc, char *argv[]) { /* Number of processed to exec */ int num_procs = 5; /* Used to keep track of which * program to exec */ int proc; /* Filename to write to * from exec'd 'tee' process*/ char *filename; /* Pipe file descriptors */ int newpfd[2], oldpfd[2]; /* Status holder for call to waitpid() */ int status; /* Parent pid -- used to check whether * we're in the parent or child process */ pid_t parent, child, sto_pid; /* Struct for use with GNU getopt_long() */ struct option longopts[] = { { "file", required_argument, 0, 'f' }, { 0, 0, 0, 0 } }; /* Variable to hold flag currently * being ready by getopt() */ int c; /* Index of option currently * being considered */ int opt_index = 0; if(argc < 3) usage(stderr, argv[0], "insufficient number of options", EXIT_FAILURE); /* * Loop adapted from example given at * http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html */ while((c = getopt_long(argc, argv, "f:", longopts, &opt_index)) != -1) { switch(c) { case 'f': filename = optarg; break; case('?'): default: usage(stderr, argv[0], "unrecognized option", EXIT_FAILURE); break; } } /* Get pid of parent process * and store so that we can tell * in the following loop whether * we're in a parent or child */ parent = sto_pid = getpid(); /* Loop 'num_procs' times, creating a pipe and * child process each time. */ for(proc = 0; proc < num_procs; proc++) { /* Bail out if we're in a child process */ if(sto_pid != parent) break; if (pipe(newpfd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } /* Create child process */ switch (child = fork()) { case -1: perror("fork"); exit(EXIT_FAILURE); case 0: /* Store child pid */ sto_pid = getpid(); /* If there is a previous child: */ if (proc > 0) { /* Connect the read side of the old pipe * to the stdin of the current child */ connect_pipe(oldpfd[0], STDIN_FILENO, 1); /* Close both ends of the old pipe */ close_pipe(oldpfd[0], 1); close_pipe(oldpfd[1], 1); } /* If there is going to be a subsequent child: */ if (proc < num_procs - 1) { /* Close the read side of the current pipe * (the file description itself is still open * because it )*/ close_pipe(newpfd[0], 1); /* Connect the stdout of the current child * to the write side of the current pipe */ connect_pipe(newpfd[1], STDOUT_FILENO, 1); /* Close the duplicated file descriptor */ close_pipe(newpfd[1], 1); } /* Thanks to questioner Dale and commenters at * http://stackoverflow.com/questions/15188115/multiple-execlp-not-working * for the following switch statement. * Uses 'proc' to decide which executable * to call for current child */ switch(proc) { case 0: execlp("rev", "rev", NULL); break; case 1: execlp("sort", "sort", NULL); break; case 2: execlp("uniq", "uniq", "-c", NULL); break; case 3: execlp("tee", "tee", filename, NULL); break; case 4: execlp("wc", "wc", NULL); break; default: break; } default: /* If there is a previous child, * close old pipe file descriptors */ if(proc > 0) { close_pipe(oldpfd[0], 0); close_pipe(oldpfd[1], 0); } /* If there is a next child, copy * new pipe file descriptors to old * pipe file descriptors. This enables * linking the old output to the new input * on the next loop. */ if(proc < num_procs - 1) { oldpfd[0] = newpfd[0]; oldpfd[1] = newpfd[1]; } /* Wait until the last child has completed */ if(proc == num_procs - 1) { waitpid(child, &status, 0); /* Close last pipe */ close_pipe(newpfd[0], 0); close_pipe(newpfd[1], 0); } break; } } /* If we're in a child process, * call _exit() instead of return */ if(sto_pid != parent) _exit(EXIT_SUCCESS); return 0; }
_WCRTLINK FILE *__F_NAME(_popen,_wpopen)( const CHAR_TYPE *command, const CHAR_TYPE *mode ) /*****************************************************************************************/ { #if defined(__NT__) HANDLE osHandle; BOOL rc; int handleMode; #elif defined(__OS2__) && defined(__386__) APIRET rc; ULONG handleState; #elif defined(__OS2__) && !defined(__386__) USHORT rc; USHORT handleState; #endif FILE * fp; int handles[2]; CHAR_TYPE textOrBinary; CHAR_TYPE readOrWrite; /*** Parse the mode string ***/ switch( mode[0] ) { /* read or write */ case 'r': readOrWrite = 'r'; break; case 'w': readOrWrite = 'w'; break; default: return( NULL ); } switch( mode[1] ) { /* text or binary */ case 't': textOrBinary = 't'; break; case 'b': textOrBinary = 'b'; break; default: textOrBinary = _RWD_fmode == _O_BINARY ? 'b' : 't'; } /*** Create the pipe at the OS level ***/ if( _pipe( handles, 0, textOrBinary == 't' ? _O_TEXT : _O_BINARY ) == -1 ) { return( NULL ); } /*** Make read handle non-inheritable if reading ***/ if( readOrWrite == 'r' ) { #if defined( __NT__ ) rc = DuplicateHandle( GetCurrentProcess(), (HANDLE)_os_handle(handles[0]), GetCurrentProcess(), &osHandle, 0, FALSE, DUPLICATE_SAME_ACCESS ); if( rc == FALSE ) { return( 0 ); } close( handles[0] ); /* don't need this any more */ handleMode = _O_RDONLY | (textOrBinary == 't' ? _O_TEXT : _O_BINARY); handles[0] = _hdopen( (int)osHandle, handleMode ); if( handles[0] == -1 ) { CloseHandle( osHandle ); close( handles[1] ); return( 0 ); } #elif defined( __OS2__ ) rc = DosQFHandState( (HFILE)_os_handle(handles[0]), &handleState ); if( rc != NO_ERROR ) { return( 0 ); } handleState |= OPEN_FLAGS_NOINHERIT; handleState &= 0x00007F88; /* some bits must be zero */ rc = DosSetFHandState( (HFILE)_os_handle(handles[0]), handleState ); if( rc != NO_ERROR ) { return( 0 ); } #endif } /*** Make write handle non-inheritable if writing ***/ else { #if defined (__NT__ ) rc = DuplicateHandle( GetCurrentProcess(), (HANDLE)_os_handle(handles[1]), GetCurrentProcess(), &osHandle, 0, FALSE, DUPLICATE_SAME_ACCESS ); if( rc == FALSE ) { return( 0 ); } close( handles[1] ); /* don't need this any more */ handleMode = _O_WRONLY | (textOrBinary == 't' ? _O_TEXT : _O_BINARY); handles[1] = _hdopen( (int)osHandle, handleMode ); if( handles[1] == -1 ) { CloseHandle( osHandle ); close( handles[0] ); return( 0 ); } #elif defined( __OS2__ ) rc = DosQFHandState( (HFILE)_os_handle(handles[1]), &handleState ); if( rc != NO_ERROR ) { return( 0 ); } handleState |= OPEN_FLAGS_NOINHERIT; handleState &= 0x00007F88; /* some bits must be zero */ rc = DosSetFHandState( (HFILE)_os_handle(handles[1]), handleState ); if( rc != NO_ERROR ) { return( 0 ); } #endif } /*** Create the pipe's FILE* ***/ fp = __F_NAME(fdopen,_wfdopen)( handles[readOrWrite == 'r' ? 0 : 1], mode ); if( fp == NULL ) { close( handles[0] ); close( handles[1] ); return( NULL ); } _FP_PIPEDATA(fp).isPipe = 1; _FP_PIPEDATA(fp).pid = -1; /*** Spawn the process ***/ if( connect_pipe( fp, command, handles, readOrWrite, textOrBinary ) ) { return( fp ); } else { close( handles[0] ); close( handles[1] ); return( NULL ); } }