/** * Main event loop for OpenVPN in client mode, where only one VPN tunnel * is active. * @ingroup eventloop * * @param c - The context structure of the single active VPN tunnel. */ static void tunnel_point_to_point(struct context *c) { context_clear_2(c); /* set point-to-point mode */ c->mode = CM_P2P; /* initialize tunnel instance */ init_instance_handle_signals(c, c->es, CC_HARD_USR1_TO_HUP); if (IS_SIG(c)) { return; } /* main event loop */ while (true) { perf_push(PERF_EVENT_LOOP); /* process timers, TLS, etc. */ pre_select(c); P2P_CHECK_SIG(); /* set up and do the I/O wait */ io_wait(c, p2p_iow_flags(c)); P2P_CHECK_SIG(); /* timeout? */ if (c->c2.event_set_status == ES_TIMEOUT) { perf_pop(); continue; } /* process the I/O which triggered select */ process_io(c); P2P_CHECK_SIG(); perf_pop(); } uninit_management_callback(); /* tear down tunnel instance (unless --persist-tun) */ close_instance(c); }
int main(int argc, char *argv[]) { struct command_hdr hdr; int len, last_opt, i, add_dash_opt; int input_fds[MAX_FDS], output_fds[MAX_FDS]; int input_fds_count, output_fds_count; char tempdir[50] = "/tmp/qubes-gpg-split.XXXXXX"; char fifo_in[50], fifo_out[50]; int devnull; int input_pipe, output_pipe; char *qrexec_client_path = QREXEC_CLIENT_PATH, *qcp; char *remote_domain; pid_t pid; remote_domain = getenv("QUBES_GPG_DOMAIN"); if (!remote_domain) { fprintf(stderr, "ERROR: Destination domain not defined! Set it with QUBES_GPG_DOMAIN env variable.\n"); exit(1); } add_dash_opt = 0; last_opt = parse_options(argc, argv, input_fds, &input_fds_count, output_fds, &output_fds_count, 1); if (last_opt < argc) { // open the first non-option argument as stdin int input_file; if (strcmp(argv[last_opt], "-") != 0) { /* open only when not already pointing at stdin */ input_file = open(argv[last_opt], O_RDONLY); if (input_file < 0) { perror("open"); exit(1); } dup2(input_file, 0); close(input_file); } add_dash_opt = 1; } len = 0; memset(hdr.command, 0, sizeof hdr.command); for (i = 0; i < last_opt; i++) { if (len + strlen(argv[i]) < COMMAND_MAX_LEN) { strcpy(&hdr.command[len], argv[i]); len += strlen(argv[i]) + 1; } else { fprintf(stderr, "ERROR: Command line too long\n"); exit(1); } } if (add_dash_opt) { if (len + 2 < COMMAND_MAX_LEN) { strcpy(&hdr.command[len], "-"); len += 2; } else { fprintf(stderr, "ERROR: Command line too long\n"); exit(1); } } hdr.len = len ? len - 1 : 0; atexit(unlink_temps); #ifndef DEBUG // setup fifos and run qrexec client if ((client_tempdir = mkdtemp(tempdir)) == NULL) { perror("mkdtemp"); exit(1); } #else client_tempdir = tempdir; mkdir(tempdir, 0700); #endif snprintf(fifo_in, sizeof fifo_in, "%s/input", client_tempdir); if (mkfifo(fifo_in, 0600) < 0) { perror("mkfifo"); exit(1); } fifo_in_created = 1; snprintf(fifo_out, sizeof fifo_out, "%s/output", client_tempdir); if (mkfifo(fifo_out, 0600) < 0) { perror("mkfifo"); exit(1); } fifo_out_created = 1; switch (pid = fork()) { case -1: perror("fork"); exit(1); case 0: devnull = open("/dev/null", O_RDONLY); if (devnull < 0) { perror("open /dev/null"); exit(1); } dup2(devnull, 0); close(devnull); devnull = open("/dev/null", O_WRONLY); if (devnull < 0) { perror("open /dev/null"); exit(1); } dup2(devnull, 1); close(devnull); qcp = getenv("QREXEC_CLIENT_PATH"); if (qcp) qrexec_client_path = qcp; execl(qrexec_client_path, "qrexec_client_vm", remote_domain, "qubes.Gpg", PIPE_CAT_PATH, fifo_in, fifo_out, (char *) NULL); perror("exec"); exit(1); } // parent #ifdef DEBUG fprintf(stderr, "in: %s out: %s\n", fifo_in, fifo_out); #endif input_pipe = open(fifo_in, O_RDONLY); if (input_pipe < 0) { perror("open"); exit(1); } output_pipe = open(fifo_out, O_WRONLY); if (output_pipe < 0) { perror("open"); exit(1); } len = write(output_pipe, &hdr, sizeof(hdr)); if (len != sizeof(hdr)) { perror("write header"); exit(1); } #ifdef DEBUG fprintf(stderr, "input[0]: %d, in count: %d\n", input_fds[0], input_fds_count); fprintf(stderr, "input_pipe: %d\n", input_pipe); #endif return process_io(input_pipe, output_pipe, input_fds, input_fds_count, output_fds, output_fds_count); }
int Exec::exec() { int stdin_fd[2]; int stdout_fd[2]; int stderr_fd[2]; // FIXME: Bad, we potentially leak file descriptors if (pipe(stdout_fd) < 0 || pipe(stderr_fd) < 0 || pipe(stdin_fd) < 0) throw std::runtime_error("Exec:exec(): pipe failed"); pid_t pid = fork(); if (pid < 0) { // error int errnum = errno; // Cleanup close(stdout_fd[0]); close(stdout_fd[1]); close(stderr_fd[0]); close(stderr_fd[1]); close(stdin_fd[0]); close(stdin_fd[1]); std::ostringstream out; out << "Exec::exec(): fork failed: " << strerror(errno); throw std::runtime_error(out.str()); } else if (pid == 0) { // child close(stdin_fd[1]); close(stdout_fd[0]); close(stderr_fd[0]); dup2(stdin_fd[0], STDIN_FILENO); close(stdin_fd[0]); dup2(stdout_fd[1], STDOUT_FILENO); close(stdout_fd[1]); dup2(stderr_fd[1], STDERR_FILENO); close(stderr_fd[1]); // Create C-style array for arguments std::unique_ptr<char*[]> c_arguments(new char*[m_arguments.size()+2]); c_arguments[0] = strdup(m_program.c_str()); for(std::vector<std::string>::size_type i = 0; i < m_arguments.size(); ++i) c_arguments[i+1] = strdup(m_arguments[i].c_str()); c_arguments[m_arguments.size()+1] = NULL; // Execute the program if (m_absolute_path) { execv(c_arguments[0], c_arguments.get()); } else { execvp(c_arguments[0], c_arguments.get()); } int error_code = errno; // FIXME: this ain't proper, need to exit(1) on failure and signal error to parent somehow // execvp() only returns on failure std::cout << "Exec::exec(): " << m_program << ": " << strerror(error_code) << std::endl; _exit(EXIT_FAILURE); } else // if (pid > 0) { // parent close(stdin_fd[0]); close(stdout_fd[1]); close(stderr_fd[1]); try { process_io(stdin_fd[1], stdout_fd[0], stderr_fd[0]); } catch(std::exception& err) { int child_status = 0; waitpid(pid, &child_status, 0); throw; } int child_status = 0; waitpid(pid, &child_status, 0); return WEXITSTATUS(child_status); } }
static void update(void *arg, long period) { gpio_t *pgpio = (gpio_t*)arg; int i; static int io_period = 0; static int fb_delay[MAX_AXIS] = {0}; static int pos_err_old[MAX_AXIS] = {0}; // static int* pTmr = NULL; // if( !pTmr ) // pTmr = mapIoRegister( TIMER_BASE, 0x44 ); static int update = 0, update_cnt = 0; // if(*(pTmr + TCNTO0) != 0 ) // printf("TCON=%x, TCFG0=%x, TCFG1=%x, CNTB=%d, CMPB=%d, TCNTO0=%d\n", *(pTmr + TCON ), *(pTmr + TCFG0 ), *(pTmr + TCFG1 ), *(pTmr + TCNTB0 ), *(pTmr + TCMPB0 ), *(pTmr + TCNTO0) ); if(pgpio->pfiq->underrun) { fprintf(stderr, "FIFO underrun!!!\n"); pgpio->pfiq->underrun = 0; } // Update IO states only after desired period and if FIFO is half-full if (++io_period > io_update_period ) { process_io(); io_period = 0; } // If FIFO has maimum size, pause motion controller execution if(pgpio->pfiq->mdata.buffsize < fifo_deep) { *(pgpio->traj_wait) = 1; } else { *(pgpio->traj_wait) = 0; return; } for(i=0; i < num_axis; i++) { if(axis_map[i] >= 0) { // Copy actual position to the feedback *(pgpio->fb_pos[axis_map[i]]) = *(pgpio->cmd_pos[axis_map[i]]); if ( step_pins[i] >0 && dir_pins[i] > 0 ) { long long aux, aux2, dist; aux = (long long) (*(pgpio->cmd_pos[axis_map[i]])*1000000.0f); // Calculate distance to go at this iteration dist = (aux - cmd_pos_prev[i])*(long long)step_per_unit[i]/10000LL; // Calculate absolut position from program start cmd_pos_accum[i] += dist; // Set desired position for FIQ stepgen pgpio->pfiq->mdata.buffer[pgpio->pfiq->mdata.PutPtr][i].cmd_position = cmd_pos_accum[i]/10000LL; //Check if last calculated correction of the position is already appliyed if(fb_delay[i] <= 0) { // Due to FIQ jitter (cache miss, seems), we need correct position of the stepgen. // Position error is calculated in the FIQ as following: pos_error = cmd_position - step_cnt // Correction applyed by one step per the FIFO cycle // Create dead band if error in range -1..1 to avoid rotor oscilation // Check if already added correction is applied int errDelta = pgpio->pfiq->pos_error[i] - pos_err_old[i]; if(errDelta != 0) { if(pgpio->pfiq->pos_error[i] < -1) { dist -= 100LL; } if(pgpio->pfiq->pos_error[i] > 1) { dist += 100LL; } pos_err_old[i] = pgpio->pfiq->pos_error[i]; } fb_delay[i] = pgpio->pfiq->mdata.buffsize; } else fb_delay[i]--; // Calculate DSS adder value aux2 = dist * (1LL<<31)/1000000LL; // Strore adder and direction values in the FIFO if(aux2 > 0) { pgpio->pfiq->mdata.buffer[pgpio->pfiq->mdata.PutPtr][i].adder = aux2; pgpio->pfiq->mdata.buffer[pgpio->pfiq->mdata.PutPtr][i].direction = 0; } else { pgpio->pfiq->mdata.buffer[pgpio->pfiq->mdata.PutPtr][i].adder = - aux2; pgpio->pfiq->mdata.buffer[pgpio->pfiq->mdata.PutPtr][i].direction = 1; } if( scaner_compat !=0 && i == 0 ) { if(*(pgpio->scan_sync) != 0) pgpio->pfiq->mdata.buffer[pgpio->pfiq->mdata.PutPtr][i].scan_sync = 1; else pgpio->pfiq->mdata.buffer[pgpio->pfiq->mdata.PutPtr][i].scan_sync = 0; } // Store last postion cmd_pos_prev[i] = aux; } } #if 0 if(update /* && (abs(pgpio->pfiq->pos_error[i]) > 10 )*/ ) { fprintf(stderr, "putPtr=%d, buffsize=%d, step_cnt[%d]=%lld, pos_err[%d]=%lld\n" , pgpio->pfiq->mdata.PutPtr , pgpio->pfiq->mdata.buffsize //, i //, pgpio->pfiq->mdata.buffer[pgpio->pfiq->mdata.PutPtr][i].cmd_position , i , pgpio->pfiq->step_count[i], i, pgpio->pfiq->pos_error[i] ); } #endif } #if 0 update = 0; if(++update_cnt >= 500) { // printf("scan_sync=%d\n", *(pgpio->scan_sync) ); update_cnt = 0; update = 1; }; #endif // To avoid simultaneous access to the buffsize, we increment it in the FIQ handler pgpio->pfiq->mdata.ringbuff_update = 1; // Increment put position if(++pgpio->pfiq->mdata.PutPtr >= fifo_deep) { pgpio->pfiq->mdata.PutPtr = 0; } }
NETLIB_API void idle_slave(bool _can_block) { process_io(_can_block); }
NETLIB_API void idle(bool _can_block) { process_io(_can_block); thread::sleep(0); }
void backend() { struct timeval timeout; int i, nb; volatile int first_call = 1; int there_is_a_port = 0; error_context_t econ; debug_message("Initializations complete.\n\n"); for (i = 0; i < 5; i++) { if (external_port[i].port) { debug_message("Accepting connections on port %d.\n", external_port[i].port); there_is_a_port = 1; } } if (!there_is_a_port) debug_message("No external ports specified.\n"); init_user_conn(); /* initialize user connection socket */ #ifdef SIGHUP signal(SIGHUP, startshutdownMudOS); #endif clear_state(); save_context(&econ); if (SETJMP(econ.context)) restore_context(&econ); if (!t_flag && first_call) { first_call = 0; call_heart_beat(); } while (1) { /* Has to be cleared if we jumped out of process_user_command() */ current_interactive = 0; set_eval(max_cost); if (obj_list_replace || obj_list_destruct) remove_destructed_objects(); /* * shut down MudOS if MudOS_is_being_shut_down is set. */ if (MudOS_is_being_shut_down) shutdownMudOS(0); if (slow_shut_down_to_do) { int tmp = slow_shut_down_to_do; slow_shut_down_to_do = 0; slow_shut_down(tmp); } /* * select */ make_selectmasks(); timeout.tv_sec = 1; timeout.tv_usec = 0; #ifndef hpux nb = select(FD_SETSIZE, &readmask, &writemask, (fd_set *) 0, &timeout); #else nb = select(FD_SETSIZE, (int *) &readmask, (int *) &writemask, (int *) 0, &timeout); #endif /* * process I/O if necessary. */ if (nb > 0) { process_io(); } /* * process user commands. */ for (i = 0; process_user_command() && i < max_users; i++) ; /* * call outs */ call_out(); #ifdef PACKAGE_ASYNC check_reqs(); #endif } } /* backend() */
void backend() { struct timeval timeout; int i, nb; volatile int first_call = 1; int there_is_a_port = 0; error_context_t econ; debug_message("Initializations complete.\n\n"); for (i = 0; i < 5; i++) { if (external_port[i].port) { debug_message("Accepting connections on port %d.\n", external_port[i].port); there_is_a_port = 1; } } if (!there_is_a_port) debug_message("No external ports specified.\n"); init_user_conn(); /* initialize user connection socket */ #ifdef SIGHUP signal(SIGHUP, startshutdownMudOS); #endif clear_state(); save_context(&econ); if (SETJMP(econ.context)) restore_context(&econ); if (!t_flag && first_call) { first_call = 0; call_heart_beat(); } while (1) { /* Has to be cleared if we jumped out of process_user_command() */ current_interactive = 0; eval_cost = max_cost; if (obj_list_replace || obj_list_destruct) remove_destructed_objects(); /* * shut down MudOS if MudOS_is_being_shut_down is set. */ if (MudOS_is_being_shut_down) shutdownMudOS(0); if (slow_shut_down_to_do) { int tmp = slow_shut_down_to_do; slow_shut_down_to_do = 0; slow_shut_down(tmp); } /* * select */ make_selectmasks(); if (heart_beat_flag) { /* use zero timeout if a heartbeat is * pending. */ timeout.tv_sec = 0; /* this should avoid problems with longjmp's * too */ timeout.tv_usec = 0; } else { /* * not using infinite timeout so that we'll have insurance in the * unlikely event a heartbeat happens between now and the * select(). Note that SIGALRMs (for heartbeats) do make select() * drop through. (Except on Windows) */ #ifdef WIN32 timeout.tv_sec = HEARTBEAT_INTERVAL/1000000; timeout.tv_usec = HEARTBEAT_INTERVAL%1000000; #else timeout.tv_sec = 60; timeout.tv_usec = 0; #endif } #ifndef hpux nb = select(FD_SETSIZE, &readmask, &writemask, (fd_set *) 0, &timeout); #else nb = select(FD_SETSIZE, (int *) &readmask, (int *) &writemask, (int *) 0, &timeout); #endif /* * process I/O if necessary. */ if (nb > 0) { process_io(); } /* * process user commands. */ for (i = 0; process_user_command() && i < max_users; i++) ; /* * call heartbeat if appropriate. */ if (heart_beat_flag) call_heart_beat(); } } /* backend() */