/*---------------------------------------------------------------------------*/ static int configure(int type, int value) { if((type != WEATHER_METER_ACTIVE) && (type != WEATHER_METER_ANEMOMETER_INT_OVER) && (type != WEATHER_METER_RAIN_GAUGE_INT_OVER) && (type != WEATHER_METER_ANEMOMETER_INT_DIS) && (type != WEATHER_METER_RAIN_GAUGE_INT_DIS)) { PRINTF("Weather: invalid configuration option\n"); return WEATHER_METER_ERROR; } if(type == WEATHER_METER_ACTIVE) { anemometer.value_avg = 0; anemometer.ticks_avg = 0; weather_sensors.anemometer.int_en = 0; weather_sensors.rain_gauge.int_en = 0; weather_sensors.anemometer.ticks = 0; weather_sensors.rain_gauge.ticks = 0; weather_sensors.anemometer.value = 0; weather_sensors.rain_gauge.value = 0; if(!value) { anemometer_int_callback = NULL; rain_gauge_int_callback = NULL; GPIO_DISABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); GPIO_DISABLE_INTERRUPT(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); process_exit(&weather_meter_int_process); enabled = 0; PRINTF("Weather: disabled\n"); return WEATHER_METER_SUCCESS; } /* Configure the wind vane */ adc_zoul.configure(SENSORS_HW_INIT, WIND_VANE_ADC); /* Configure anemometer interruption */ GPIO_SOFTWARE_CONTROL(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); GPIO_SET_INPUT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); GPIO_DETECT_RISING(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); GPIO_TRIGGER_SINGLE_EDGE(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); ioc_set_over(ANEMOMETER_SENSOR_PORT, ANEMOMETER_SENSOR_PIN, IOC_OVERRIDE_DIS); gpio_register_callback(weather_meter_interrupt_handler, ANEMOMETER_SENSOR_PORT, ANEMOMETER_SENSOR_PIN); /* Configure rain gauge interruption */ GPIO_SOFTWARE_CONTROL(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); GPIO_SET_INPUT(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); GPIO_DETECT_RISING(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); GPIO_TRIGGER_SINGLE_EDGE(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); ioc_set_over(RAIN_GAUGE_SENSOR_PORT, RAIN_GAUGE_SENSOR_PIN, IOC_OVERRIDE_DIS); gpio_register_callback(weather_meter_interrupt_handler, RAIN_GAUGE_SENSOR_PORT, RAIN_GAUGE_SENSOR_PIN); process_start(&weather_meter_int_process, NULL); /* Initialize here prior the first second tick */ wind_vane.value_prev = weather_meter_get_wind_dir(); ctimer_set(&ct, CLOCK_SECOND, ct_callback, NULL); GPIO_ENABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); GPIO_ENABLE_INTERRUPT(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); nvic_interrupt_enable(ANEMOMETER_SENSOR_VECTOR); nvic_interrupt_enable(RAIN_GAUGE_SENSOR_VECTOR); enabled = 1; PRINTF("Weather: started\n"); return WEATHER_METER_SUCCESS; } switch(type) { case WEATHER_METER_ANEMOMETER_INT_OVER: weather_sensors.anemometer.int_en = 1; weather_sensors.anemometer.int_thres = value; PRINTF("Weather: anemometer threshold %u\n", value); break; case WEATHER_METER_RAIN_GAUGE_INT_OVER: weather_sensors.rain_gauge.int_en = 1; weather_sensors.rain_gauge.int_thres = value; PRINTF("Weather: rain gauge threshold %u\n", value); break; case WEATHER_METER_ANEMOMETER_INT_DIS: PRINTF("Weather: anemometer int disabled\n"); weather_sensors.anemometer.int_en = 0; break; case WEATHER_METER_RAIN_GAUGE_INT_DIS: PRINTF("Weather: rain gauge int disabled\n"); weather_sensors.rain_gauge.int_en = 0; break; default: return WEATHER_METER_ERROR; } return WEATHER_METER_SUCCESS; }
bool process_code(vm_t * vm, bool verbose) { for (vm->regs.pc = 0; vm->regs.pc < (reg_t) vm->code_size;) { u8 opcode = vm->code[vm->regs.pc]; inst c_inst = get_instruction(opcode); bool pstat = false; switch (c_inst.name) { // op reg, reg case ADD: case SUB: case MUL: case DIV: case XOR: case MOV: { pstat = process_reg_reg(c_inst, vm, true); break; } // op reg, immb case ADDIB: case SUBIB: case MULIB: case DIVIB: case XORIB: case MOVIB: { pstat = process_reg_immb(c_inst, vm, true); break; } // op reg, immw case ADDIW: case SUBIW: case MULIW: case DIVIW: case XORIW: case MOVIW: { pstat = process_reg_immw(c_inst, vm, true); break; } // op reg, immd case ADDID: case SUBID: case MULID: case DIVID: case XORID: case MOVID: { pstat = process_reg_immd(c_inst, vm, true); break; } // op reg case INC: case DEC: { pstat = process_reg(c_inst, vm, true); break; } case PUSHB: { pstat = process_pushb(c_inst, vm, true); break; } case PUSHW: { pstat = process_pushw(c_inst, vm, true); break; } case PUSHD: { pstat = process_pushd(c_inst, vm, true); break; } case POPB: { pstat = process_popb(c_inst, vm, true); break; } case POPW: { pstat = process_popw(c_inst, vm, true); break; } case POPD: { pstat = process_popd(c_inst, vm, true); break; } case PUSHIB: { pstat = process_pushib(c_inst, vm, true); break; } case PUSHIW: { pstat = process_pushiw(c_inst, vm, true); break; } case PUSHID: { pstat = process_pushid(c_inst, vm, true); break; } case GSTK: { pstat = process_gstk(c_inst, vm, true); break; } case PSTK: { pstat = process_pstk(c_inst, vm, true); break; } case EXIT: { pstat = process_exit(c_inst, vm, true); break; } case SYSCALL: { reg_t scall = vm->regs.r1; reg_t nargs = get_syscall_nargs(scall); pstat = process_syscall(scall, nargs, c_inst, vm, true); break; } case INVALID_OPCODE: { pstat = process_invalid(c_inst, vm, true); break; } default: return false; }; if(verbose) { show_regs(vm); } // previous processed opcode failed || exit if(pstat == false) { return false; } vm->regs.pc++; } return true; }
/*-----------------------------------------------------------------------------------*/ PROCESS_THREAD(simpletelnet_process, ev, data) { struct ctk_widget *w; int sendlen; PROCESS_BEGIN(); ctk_window_new(&telnetwindow, TELNET_WINDOW_WIDTH, TELNET_WINDOW_HEIGHT, "Simple telnet"); strcpy(telnetport, "23"); CTK_WIDGET_ADD(&telnetwindow, &telnethostlabel); CTK_WIDGET_ADD(&telnetwindow, &telnetportlabel); CTK_WIDGET_ADD(&telnetwindow, &telnethosttextentry); CTK_WIDGET_ADD(&telnetwindow, &telnetporttextentry); CTK_WIDGET_ADD(&telnetwindow, &telnetconnectbutton); CTK_WIDGET_ADD(&telnetwindow, &telnetdisconnectbutton); CTK_WIDGET_ADD(&telnetwindow, &telnetlinetextentry); CTK_WIDGET_ADD(&telnetwindow, &telnetsendbutton); CTK_WIDGET_ADD(&telnetwindow, &telnetsep1); CTK_WIDGET_ADD(&telnetwindow, &telnettextarea); CTK_WIDGET_ADD(&telnetwindow, &telnetsep2); CTK_WIDGET_ADD(&telnetwindow, &telnetstatus); CTK_WIDGET_FOCUS(&telnetwindow, &telnethosttextentry); ctk_window_open(&telnetwindow); while(1) { PROCESS_WAIT_EVENT(); if(ev == ctk_signal_button_activate) { w = (struct ctk_widget *)data; if(w == (struct ctk_widget *)&telnetsendbutton) { strcpy(sendline, telnetline); sendlen = (int)strlen(sendline); petsciiconv_toascii(sendline, sendlen); sendline[sendlen++] = ISO_CR; sendline[sendlen++] = ISO_NL; if(telnet_send(&ts_appstate, sendline, sendlen)) { /* Could not send. */ ctk_label_set_text(&telnetstatus, "Could not send"); ctk_window_redraw(&telnetwindow); /* } else {*/ /* Could send */ } } else if(w == (struct ctk_widget *)&telnetdisconnectbutton) { telnet_close(&ts_appstate); show("Closing..."); } else if(w == (struct ctk_widget *)&telnetconnectbutton) { connect(); ctk_window_redraw(&telnetwindow); } #if UIP_UDP } else if(ev == resolv_event_found) { if(strcmp(data, telnethost) == 0) { if(resolv_lookup(telnethost) != NULL) { connect(); } else { show("Host not found"); } } #endif /* UIP_UDP */ } else if( #if CTK_CONF_WINDOWCLOSE ev == ctk_signal_window_close || #endif /* CTK_CONF_WINDOWCLOSE */ ev == PROCESS_EVENT_EXIT) { process_exit(&simpletelnet_process); ctk_window_close(&telnetwindow); LOADER_UNLOAD(); } else if(ev == tcpip_event) { telnet_app(data); } } PROCESS_END(); }
void syscall_exit(int retval){ process_exit(retval); }
/*---------------------------------------------------------------------------*/ void powertrace_stop(void) { process_exit(&powertrace_process); }
/*---------------------------------------------------------------------------*/ static void quit(void) { process_exit(&pinger); LOADER_UNLOAD(); }
/* * When this module is unloaded we must clean up! */ void _fini(void) { process_exit(&udpsend_process); }
static void syscall_handler (struct intr_frame *f) { int32_t* esp = (int32_t*)f->esp; /* Any parameters passed to syscall will be above ESP, see illustration below. Number of arguments each syscall expects is in argc[] array above. syscall number is pointed to by ESP. -------------------------------------- PHYS_BASE ................. <param> <param> ESP ---> <syscall_number> -------------------------------------- */ // verify esp pointer is ok, first parameter: current thread if(esp == NULL || verify_fix_length(esp, sizeof(esp)) == false){ sys_exit(-1); } // esp adress belongs to thread if(pagedir_get_page(thread_current()->pagedir, esp) == NULL){ sys_exit(-1); } // ok syscall nr int32_t syscall_nr = *esp; if(syscall_nr < 0 || syscall_nr >= SYS_NUMBER_OF_CALLS){ sys_exit(-1); } // Make sure our data is not overwriting PHYS_BASE. int expected_args = argc[syscall_nr]; unsigned long highest_addr = esp + (expected_args * sizeof(int)); if(highest_addr >= PHYS_BASE){ sys_exit(-1); } if(pagedir_get_page(thread_current()->pagedir, highest_addr) == NULL){ sys_exit(-1); } /* int i = 1; for(; i <= expected_args; i++){ if(verify_fix_length(&esp[i], sizeof(int) ) == false){ sys_exit(-1); } } */ DEBUG_SYSCALL("# SYSCALL received = %s\n", get_system_call_name(syscall_nr)); switch (syscall_nr) { case SYS_HALT: power_off(); break; case SYS_EXEC: { f->eax = SYS_EXEC_handler(esp); } break; case SYS_WAIT: { int child_pid = *(esp + 1); f->eax = process_wait (child_pid); break; } case SYS_EXIT: { if(is_kernel_vaddr(pg_round_up((void*)esp[1]) )){ sys_exit(-1); } int exit_status = *(esp + 1); process_exit(exit_status); thread_exit(); break; } case SYS_PLIST: process_print_list(); break; case SYS_CREATE: { bool success = false; char *name = (char*)*(esp + 1); if(name == NULL){ sys_exit(-1); } unsigned initial_size = *(esp + 2); if(verify_fix_length(esp[1], initial_size) == false){ sys_exit(-1); } if(verify_variable_length(esp[1]) == false){ sys_exit(-1); } success = filesys_create(name, initial_size); if(success) { DEBUG_SYSCALL("#SYS_CREATE - File with name: %s created. \n", name); } else { DEBUG_SYSCALL("#SYS_CREATE - filesys_create failed: file named \'%s\' already exists or internal memory allocation failed \n", name); } f->eax = success; break; } case SYS_OPEN: { char *name = (char*)*(esp + 1); if(name == NULL){ sys_exit(-1); } if(verify_variable_length(esp[1]) == false){ sys_exit(-1); } struct file *file; file = filesys_open(name); int retVal = -1; if(file != NULL) { DEBUG_SYSCALL("# SYS_OPEN - File with name: '%s' created. \n", name); int fd = flist_add_file(file); retVal = fd; } else { DEBUG_SYSCALL("# SYS_OPEN - filesys_open failed: no file named \'%s\' exists or internal memory allocation failed \n", name); retVal = -1; } f->eax = retVal; break; } case SYS_READ: { int retVal = SYS_READ_handler(esp); f->eax = retVal; break; } case SYS_CLOSE: { int retVal = SYS_CLOSE_handler(esp); f->eax = retVal; break; } case SYS_REMOVE: { int retVal = SYS_REMOVE_handler(esp); f->eax = retVal; break; } case SYS_WRITE: { int retVal = SYS_WRITE_handler(esp); f->eax = retVal; break; } case SYS_SEEK: { f->eax = SYS_SEEK_handler(esp); break; } case SYS_TELL: f->eax = SYS_TELL_handler(esp); break; case SYS_FILESIZE: f->eax = SYS_FILESIZE_handler(esp); break; default: { DEBUG_SYSCALL ("Executed an unknown system call (nr: %i)!\n", syscall_nr); DEBUG_SYSCALL ("Stack top + 0: %d\n", esp[0]); DEBUG_SYSCALL ("Stack top + 1: %d\n", esp[1]); thread_exit (); } } }
/* * When this module is unloaded we must clean up! */ void _fini(void) { process_exit(&test_process); }
/******************************************* Function Implementation ********************************************/ void ptemperature_initialize() { process_exit(&ptemperature_client); //Start client processes next. process_start(&ptemperature_client, NULL); }
void main() { log_init(); fork_init(); /* fork_init() will directly jump to restored thread context if we are a fork child */ mm_init(); install_syscall_handler(); heap_init(); signal_init(); process_init(); tls_init(); vfs_init(); dbt_init(); /* Parse command line */ const char *cmdline = GetCommandLineA(); int len = strlen(cmdline); if (len > BLOCK_SIZE) /* TODO: Test if there is sufficient space for argv[] array */ { kprintf("Command line too long.\n"); process_exit(1, 0); } startup = mm_mmap(NULL, BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS, INTERNAL_MAP_TOPDOWN | INTERNAL_MAP_NORESET, NULL, 0); *(uintptr_t*) startup = 1; char *current_startup_base = startup + sizeof(uintptr_t); memcpy(current_startup_base, cmdline, len + 1); char *envbuf = (char *)ALIGN_TO(current_startup_base + len + 1, sizeof(void*)); char *env0 = envbuf; ENV("TERM=xterm"); char *env1 = envbuf; ENV("HOME=/root"); char *env2 = envbuf; ENV("DISPLAY=127.0.0.1:0"); char *env3 = envbuf; ENV("PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/bin:/sbin"); int argc = 0; char **argv = (char **)ALIGN_TO(envbuf, sizeof(void*)); /* Parse command line */ int in_quote = 0; char *j = current_startup_base; for (char *i = current_startup_base; i <= current_startup_base + len; i++) if (!in_quote && (*i == ' ' || *i == '\t' || *i == '\r' || *i == '\n' || *i == 0)) { *i = 0; if (i > j) argv[argc++] = j; j = i + 1; } else if (*i == '"') { *i = 0; if (in_quote) argv[argc++] = j; in_quote = !in_quote; j = i + 1; } argv[argc] = NULL; char **envp = argv + argc + 1; int env_size = 4; envp[0] = env0; envp[1] = env1; envp[2] = env2; envp[3] = env3; envp[4] = NULL; char *buffer_base = (char*)(envp + env_size + 1); const char *filename = NULL; for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { } else if (!filename) filename = argv[i]; } if (filename) do_execve(filename, argc - 1, argv + 1, env_size, envp, buffer_base, NULL); kprintf("Usage: flinux <executable> [arguments]\n"); process_exit(1, 0); }
void signal_handle_pending() { int i, rc; sigset_t pending, mask; struct sigaction *action; spinlock_acquire(&CURR_THREAD->lock); pending = CURR_THREAD->pending_signals; pending &= ~(CURR_THREAD->signal_mask | CURR_PROC->signal_mask); if (!pending) { return; } for (i = 0; i < NSIG; i++) { if (!(pending & (1 << i))) { continue; } CURR_THREAD->pending_signals &= ~(1 << i); /* Check if the signal is ignored */ action = &CURR_PROC->signal_act[i]; if (action->sa_handler == SIG_IGN || (action->sa_handler == SIG_DFT && SIG_DFT_IGNORE(i))) { continue; } /* If not the default action, we must execute a user-mode * signal handler. */ if (action->sa_handler != SIG_DFT) { /* Save the current mask, and apply a new mask. */ mask = CURR_PROC->signal_mask; CURR_PROC->signal_mask |= action->sa_mask; rc = arch_signal_setup_frame(action, &CURR_THREAD->signal_info[i], mask); if (rc != 0) { signal_force(CURR_THREAD, SIGSEGV, i); } break; } /* Release the lock while handling default action in case * we need to kill the process. */ spinlock_release(&CURR_THREAD->lock); /* Handle the default action */ if (SIG_DFT_TERM(i)) { process_exit(i); } else if (SIG_DFT_CORE(i)) { // TODO: Core dump process_exit(i); } else if (SIG_DFT_STOP(i)) { // TODO: Stop process process_exit(i); } else if (SIG_DFT_CONT(i)) { break; } spinlock_acquire(&CURR_THREAD->lock); } spinlock_release(&CURR_THREAD->lock); }
void test_crash_handler( const char* dump_file ) { FOUNDATION_UNUSED( dump_file ); log_error( HASH_TEST, ERROR_EXCEPTION, "Test crashed" ); process_exit( -1 ); }
static void timedout_ctrl(struct runicast_conn *c, const linkaddr_t *to, uint8_t rexmits) { shell_output_str(&netperf_command, "netperf control connection failed", ""); process_exit(&shell_netperf_process); }
/*---------------------------------------------------------------------------*/ void httpparse_deinit() { memset(&httpreqdata, 0, sizeof(httpreqdata)); process_exit(&http_req_process); }
void sys_exit(int status) { process_exit(status); thread_exit(); }
/*-----------------------------------------------------------------------------------*/ static void netconf_quit(void) { process_exit(&netconf_process); LOADER_UNLOAD(); }
int do_execve(const char *filename, int argc, char *argv[], int env_size, char *envp[], char *buffer_base, void (*initialize_routine)()) { buffer_base = (char*)((uintptr_t)(buffer_base + sizeof(void*) - 1) & -sizeof(void*)); /* Detect file type */ int r; char magic[4]; struct file *f; r = vfs_openat(AT_FDCWD, filename, O_RDONLY, 0, 0, &f); if (r < 0) return r; if (!winfs_is_winfile(f)) { vfs_release(f); return -L_EACCES; } r = f->op_vtable->pread(f, magic, 4, 0); if (r < 4) return -L_EACCES; struct binfmt binary; binary.argv0 = NULL; binary.argv1 = NULL; binary.replace_argv0 = FALSE; binary.buffer_base = buffer_base; binary.has_interpreter = false; binary.executable = (struct elf_header *)alloca(sizeof(struct elf_header)); binary.interpreter = (struct elf_header *)alloca(sizeof(struct elf_header)); /* Load file */ if (magic[0] == ELFMAG0 && magic[1] == ELFMAG1 && magic[2] == ELFMAG2 && magic[3] == ELFMAG3) { log_info("It is an ELF file."); if (initialize_routine) initialize_routine(); r = load_elf(f, &binary); } else if (magic[0] == '#' && magic[1] == '!') { log_info("It is a script file."); if (initialize_routine) initialize_routine(); r = load_script(f, &binary); } else { log_error("Unknown binary magic: %c%c%c%c", magic[0], magic[1], magic[2], magic[3]); return -L_EACCES; } vfs_release(f); if (r < 0) { log_error("FATAL: Load executable failed, cannot continue."); process_exit(1, 0); } /* Execute file */ if (binary.replace_argv0) argv[0] = (char *)filename; run(&binary, argc, argv, env_size, envp); return 0; /* Would never reach here */ }
void collide( lattice_ptr lattice) { double *feq; double *f; double *ftemp; double omega; int is_solid; int n, a; int subs; #if SAY_HI printf("collide() -- Hi!\n"); #endif /* SAY_HI */ for( subs=0; subs<NUM_FLUID_COMPONENTS; subs++) { for( n=0; n<lattice->NumNodes; n++) { feq = lattice->pdf[subs][n].feq; f = lattice->pdf[subs][n].f; ftemp = lattice->pdf[subs][n].ftemp; is_solid = lattice->solids[subs][n].is_solid; if( !is_solid) { // C O L L I D E // f = ftemp - (1/tau[subs])( ftemp - feq) for( a=0; a<Q; a++) { #if 1 f[a] = ftemp[a] - ftemp[a] / lattice->param.tau[subs] + feq[a] / lattice->param.tau[subs] ; #else f[a] = ftemp[a] - ( ( ftemp[a] ) - ( feq[a] ) ) / lattice->param.tau[subs]; #endif } /* for( a=0; a<=8; a++) */ #if PUKE_NEGATIVE_DENSITIES for( a=0; a<Q; a++) { if( *f < 0.) { printf("\n"); printf( "collide() -- Node %d (%d,%d), subs %d, " "has negative density %20.17f " "in direction %d " "at timestep %d. Exiting!\n", n, n%lattice->param.LX, n/lattice->param.LX, subs, f[a], a, lattice->time ); printf("\n"); process_exit(1); } } /* for( a=0; a<Q; a++) */ #endif /* PUKE_NEGATIVE_DENSITIES */ } /* if( !( is_solid & BC_SOLID_NODE)) */ else // is_solid & BC_SOLID_NODE { // B O U N C E B A C K if( lattice->param.bc_slip_north && n >= lattice->NumNodes - lattice->param.LX) { // Slip condition on north boundary. f[1] = ftemp[1]; f[2] = ftemp[4]; f[3] = ftemp[3]; f[4] = ftemp[2]; f[5] = ftemp[8]; f[6] = ftemp[7]; f[7] = ftemp[6]; f[8] = ftemp[5]; } /* if( lattice->param.bc_slip_north && ... ) */ else { if( subs==0) { // Usual non-slip bounce-back condition. /* // N -> S // S -> N // E -> W // W -> E // T -> B // B -> T */ f[ C] = ftemp[ C]; f[ E] = ftemp[ W]; f[ W] = ftemp[ E]; f[ N] = ftemp[ S]; f[ S] = ftemp[ N]; f[ T] = ftemp[ B]; f[ B] = ftemp[ T]; f[NW] = ftemp[SE]; f[NE] = ftemp[SW]; f[SW] = ftemp[NE]; f[SE] = ftemp[NW]; f[TW] = ftemp[BE]; f[TE] = ftemp[BW]; f[BW] = ftemp[TE]; f[BE] = ftemp[TW]; f[TN] = ftemp[BS]; f[TS] = ftemp[BN]; f[BN] = ftemp[TS]; f[BS] = ftemp[TN]; } /* if( subs==0) */ #if NUM_FLUID_COMPONENTS==2 else // subs==1 { #if INAMURO_SIGMA_COMPONENT if( lattice->param.bc_sigma_slip) { // // Slip BC for solute on side walls. // Will this make a difference on Taylor dispersion? // if( lattice->FlowDir == /*Vertical*/2) { if( /*west*/(n )%lattice->param.LX == 0 || /*east*/(n+1)%lattice->param.LX == 0) { // Slip condition on east/west boundary. f[1] = ftemp[3]; f[2] = ftemp[2]; f[3] = ftemp[1]; f[4] = ftemp[4]; f[5] = ftemp[6]; f[6] = ftemp[5]; f[7] = ftemp[8]; f[8] = ftemp[7]; } } else if( lattice->FlowDir == /*Horizontal*/1) { if( /*north*/ n >= lattice->NumNodes - lattice->param.LX || /*south*/ n < lattice->param.LX ) { // Slip condition on north/south boundary. f[1] = ftemp[1]; f[2] = ftemp[4]; f[3] = ftemp[3]; f[4] = ftemp[2]; f[5] = ftemp[8]; f[6] = ftemp[7]; f[7] = ftemp[6]; f[8] = ftemp[5]; } else { // ERROR: Solid exists somewhere other than as side walls. printf("%s (%d) >> " "ERROR: " "bc_sigma_slip is on. " "FlowDir is determined to be horizontal. " "Encountered solid node somewhere other than side walls. " "That situation is not supported. " "Exiting!", __FILE__, __LINE__); process_exit(1); } } else { printf("%s (%d) >> " "FlowDir is indeterminate. " "Cannot apply slip BC (bc_sigma_slip). " "Exiting!", __FILE__, __LINE__); process_exit(1); } } /* if( lattice->param.bc_sigma_slip) */ else { #endif /* INAMURO_SIGMA_COMPONENT */ // Usual non-slip bounce-back condition. f[ E] = ftemp[ W]; f[ W] = ftemp[ E]; f[ N] = ftemp[ S]; f[ S] = ftemp[ N]; f[ T] = ftemp[ B]; f[ B] = ftemp[ T]; f[NW] = ftemp[SE]; f[NE] = ftemp[SW]; f[SW] = ftemp[NE]; f[SE] = ftemp[NW]; f[TW] = ftemp[BE]; f[TE] = ftemp[BW]; f[BW] = ftemp[TE]; f[BE] = ftemp[TW]; f[TN] = ftemp[BS]; f[TS] = ftemp[BN]; f[BN] = ftemp[TS]; f[BS] = ftemp[TN]; #if INAMURO_SIGMA_COMPONENT } /* if( lattice->param.bc_sigma_slip) else */ #endif /* INAMURO_SIGMA_COMPONENT */ } /* if( subs==0) else*/ #endif /* NUM_FLUID_COMPONENTS==2 */ } /* if( lattice->param.bc_slip_north && ... ) else */ } /* if( !( is_solid & BC_SOLID_NODE)) else */ } /* for( n=0; n<lattice_NumNodes; n++) */ #if POROUS_MEDIA if( INAMURO_SIGMA_COMPONENT!=0 || subs==0) { int LX = get_LX( lattice); int LY = get_LY( lattice); int LZ = get_LZ( lattice); double ns; double* nsterm = lattice->nsterm; // Compute the solid density term for fluid component. for( n=0; n<lattice->NumNodes; n++) { if( is_not_solid(lattice, n)) { // ns_flag = 0 ==> uniform ns value read from scalar // ns_flag in {1,2} ==> variable ns_value read from array if( lattice->param.ns_flag == 0) { ns = lattice->param.ns; } else { ns = lattice->ns[n].ns; } /* E */nsterm[Q*n+ E] = ns*( lattice->pdf[subs][n].ftemp[ W] - lattice->pdf[subs][n].f [ E]); /* W */nsterm[Q*n+ W] = ns*( lattice->pdf[subs][n].ftemp[ E] - lattice->pdf[subs][n].f [ W]); /* N */nsterm[Q*n+ N] = ns*( lattice->pdf[subs][n].ftemp[ S] - lattice->pdf[subs][n].f [ N]); /* S */nsterm[Q*n+ S] = ns*( lattice->pdf[subs][n].ftemp[ N] - lattice->pdf[subs][n].f [ S]); /* T */nsterm[Q*n+ T] = ns*( lattice->pdf[subs][n].ftemp[ B] - lattice->pdf[subs][n].f [ T]); /* B */nsterm[Q*n+ B] = ns*( lattice->pdf[subs][n].ftemp[ T] - lattice->pdf[subs][n].f [ B]); /* NW */nsterm[Q*n+NW] = ns*( lattice->pdf[subs][n].ftemp[NE] - lattice->pdf[subs][n].f [NW]); /* NE */nsterm[Q*n+NE] = ns*( lattice->pdf[subs][n].ftemp[NW] - lattice->pdf[subs][n].f [NE]); /* SW */nsterm[Q*n+SW] = ns*( lattice->pdf[subs][n].ftemp[SE] - lattice->pdf[subs][n].f [SW]); /* SE */nsterm[Q*n+SE] = ns*( lattice->pdf[subs][n].ftemp[SW] - lattice->pdf[subs][n].f [SE]); /* TW */nsterm[Q*n+TW] = ns*( lattice->pdf[subs][n].ftemp[TE] - lattice->pdf[subs][n].f [TW]); /* TE */nsterm[Q*n+TE] = ns*( lattice->pdf[subs][n].ftemp[TW] - lattice->pdf[subs][n].f [TE]); /* BW */nsterm[Q*n+BW] = ns*( lattice->pdf[subs][n].ftemp[BE] - lattice->pdf[subs][n].f [BW]); /* BE */nsterm[Q*n+BE] = ns*( lattice->pdf[subs][n].ftemp[BW] - lattice->pdf[subs][n].f [BE]); /* TN */nsterm[Q*n+TN] = ns*( lattice->pdf[subs][n].ftemp[TS] - lattice->pdf[subs][n].f [TN]); /* TS */nsterm[Q*n+TS] = ns*( lattice->pdf[subs][n].ftemp[TN] - lattice->pdf[subs][n].f [TS]); /* BN */nsterm[Q*n+BN] = ns*( lattice->pdf[subs][n].ftemp[BS] - lattice->pdf[subs][n].f [BN]); /* BS */nsterm[Q*n+BS] = ns*( lattice->pdf[subs][n].ftemp[BN] - lattice->pdf[subs][n].f [BS]); } } /* for( n=0; n<lattice_NumNodes; n++) */ for( n=0; n<lattice->NumNodes; n++) { f = lattice->pdf[subs][n].f; if( is_not_solid(lattice, n)) { for( a=1; a<Q; a++) { #if 0 // Store f in ftemp, because the compute_macro vars before // output_frames needs to have the pre-ns version of f. if( is_last_step_of_frame(lattice)) { // This temp copy of f in ftemp prior to application // of ns only needs to be done before outputting a frame, // not after each timestep. lattice->pdf[subs][n].ftemp[a] = f[a]; } #endif // OLD: fout = fc + ns*( fc_(x+cdt) - fc(x)) // f += ns*( f_(x+cdt) - f(x)) // // - - - >o< - - - <------o------> <--<---o--->--> // 1 2 3 4 3 5 6 4 // ------>o<------ // 5 6 // // CUR: fout = fc + ns*( fc_(x) - fc(x)) = (1-ns)*fc + ns*fc_(x) // f += ns*( f_(x) - f(x)) // // - - - >o< - - - <------o------> <--<---o--->--> // 1 2 3 4 3 4 3 4 // // NEW: fout = fc + ns*( fin_(x) - fc(x)) = (1-ns)*fc + ns*fin_(x) // f += ns*( ftemp_(x) - f(x)) // // - - - >o< - - - <------o------> <--<- -o- ->--> // 1 2 3 4 3 1 2 4 // // c.f., Walsh, Stuart D. C. and Burwinkle, Holly and Saar, Martin // O., A new partial-bounceback lattice-Boltzmann method for fluid // flow through heterogeneous media, COMPUTERS & GEOSCIENCES, 2009, // 35, 6, 1186-1193, JUN, ISI:000266544700013 f[a] += nsterm[Q*n+a]; } /* for( a=1; a<Q; a++) */ } /* if( !( bc_type & BC_SOLID_NODE)) */ } /* for( n=0; n<lattice->NumNodes; n++, f+=18) */ } /* if( INAMURO_SIGMA_COMPONENT!=0 || subs==0) */ #endif } /* for( subs=0; subs<NUM_FLUID_COMPONENTS; subs++) */ #if SAY_HI printf("collide() -- Bye!\n"); #endif /* SAY_HI */ } /* void collide( lattice_ptr lattice) */
int process_spawn(process_t* proc) { static const string_const_t unescaped = { STRING_CONST("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.:/\\") }; size_t i, num_args; size_t size; #if FOUNDATION_PLATFORM_WINDOWS wchar_t* wcmdline; wchar_t* wwd; string_t cmdline; #endif #if !FOUNDATION_PLATFORM_POSIX size_t capacity; #endif proc->code = PROCESS_INVALID_ARGS; if (!proc->path.length) return proc->code; //Always escape path on Windows platforms #if FOUNDATION_PLATFORM_POSIX if (string_find_first_not_of(STRING_ARGS(proc->path), STRING_ARGS(unescaped), 0) != STRING_NPOS) #endif { bool preesc = (proc->path.str[0] != '"'); bool postesc = (proc->path.str[ proc->path.length - 1 ] != '"'); if (preesc || postesc) { char* buffer = memory_allocate(HASH_STRING, proc->path.length + 4, 0, MEMORY_PERSISTENT); string_t pathesc = string_concat_varg(buffer, proc->path.length + 4, "\"", (size_t)(preesc ? 1 : 0), STRING_ARGS(proc->path), "\"", (size_t)(postesc ? 1 : 0), nullptr); string_deallocate(proc->path.str); proc->path = pathesc; } } size = array_size(proc->args); for (i = 0, num_args = 0; i < size; ++i) { string_t arg = proc->args[i]; if (!arg.length) continue; ++num_args; #if !FOUNDATION_PLATFORM_POSIX if (string_find_first_not_of(arg.str, arg.length, unescaped.str, unescaped.length, 0) != STRING_NPOS) { if (arg.str[0] != '"') { //Check if we need to escape " characters string_t escarg; size_t pos = string_find(arg.str, arg.length, '"', 0); while (pos != STRING_NPOS) { if (arg.str[ pos - 1 ] != '\\') { string_const_t right = string_substr(STRING_ARGS(arg), 0, pos); string_const_t left = string_substr(STRING_ARGS(arg), pos, STRING_NPOS); capacity = arg.length + 2; escarg = string_allocate(0, capacity); escarg = string_concat(escarg.str, capacity, STRING_ARGS(right), STRING_CONST("\\")); escarg = string_append(STRING_ARGS(escarg), capacity, STRING_ARGS(left)); string_deallocate(arg.str); arg = escarg; } pos = string_find(STRING_ARGS(arg), '"', pos + 2); } escarg = string_allocate_concat_varg(STRING_CONST("\""), STRING_ARGS(arg), STRING_CONST("\""), nullptr); string_deallocate(arg.str); proc->args[i] = escarg; } } #endif } #if FOUNDATION_PLATFORM_WINDOWS # ifndef SEE_MASK_NOASYNC # define SEE_MASK_NOASYNC 0x00000100 # endif capacity = BUILD_MAX_PATHLEN; cmdline = string_allocate(0, capacity); //Don't prepend exe path to parameters if using ShellExecute if (!(proc->flags & PROCESS_WINDOWS_USE_SHELLEXECUTE)) cmdline = string_copy(cmdline.str, capacity, STRING_ARGS(proc->path)); //Build command line string for (i = 0; i < size; ++i) { string_t arg = proc->args[i]; if (!arg.length) continue; if (cmdline.length + arg.length + 2 >= capacity) { string_t newline; capacity *= 2; newline = string_allocate(0, capacity); newline = string_copy(newline.str, capacity, STRING_ARGS(cmdline)); } if (cmdline.length) cmdline = string_append(STRING_ARGS(cmdline), capacity, STRING_CONST(" ")); cmdline = string_append(STRING_ARGS(cmdline), capacity, STRING_ARGS(arg)); } if (!proc->wd.length) proc->wd = string_clone(STRING_ARGS(environment_current_working_directory())); wcmdline = wstring_allocate_from_string(STRING_ARGS(cmdline)); wwd = wstring_allocate_from_string(STRING_ARGS(proc->wd)); if (proc->flags & PROCESS_WINDOWS_USE_SHELLEXECUTE) { SHELLEXECUTEINFOW sei; wchar_t* wverb; wchar_t* wpath; wverb = (proc->verb.length ? wstring_allocate_from_string(STRING_ARGS(proc->verb)) : 0); wpath = wstring_allocate_from_string(STRING_ARGS(proc->path)); ZeroMemory(&sei, sizeof(sei)); sei.cbSize = sizeof(SHELLEXECUTEINFOW); sei.hwnd = 0; sei.fMask = SEE_MASK_NOASYNC | SEE_MASK_FLAG_NO_UI | SEE_MASK_NOCLOSEPROCESS; sei.lpVerb = wverb; sei.lpFile = wpath; sei.lpParameters = wcmdline; sei.lpDirectory = wwd; sei.nShow = SW_SHOWNORMAL; if (!(proc->flags & PROCESS_CONSOLE)) sei.fMask |= SEE_MASK_NO_CONSOLE; if (proc->flags & PROCESS_STDSTREAMS) log_warn(0, WARNING_UNSUPPORTED, STRING_CONST("Unable to redirect standard in/out" " through pipes when using ShellExecute for process spawning")); log_debugf(0, STRING_CONST("Spawn process (ShellExecute): %.*s %.*s"), STRING_FORMAT(proc->path), STRING_FORMAT(cmdline)); if (!ShellExecuteExW(&sei)) { string_const_t errstr = system_error_message(0); log_warnf(0, WARNING_SYSTEM_CALL_FAIL, STRING_CONST("Unable to spawn process (ShellExecute) for executable '%.*s': %s"), STRING_FORMAT(proc->path), STRING_FORMAT(errstr)); } else { proc->hp = sei.hProcess; proc->ht = 0; proc->code = 0; } wstring_deallocate(wverb); wstring_deallocate(wpath); } else { STARTUPINFOW si; PROCESS_INFORMATION pi; BOOL inherit_handles = FALSE; memset(&si, 0, sizeof(si)); memset(&pi, 0, sizeof(pi)); si.cb = sizeof(si); if (proc->flags & PROCESS_STDSTREAMS) { proc->pipeout = pipe_allocate(); proc->pipein = pipe_allocate(); si.dwFlags |= STARTF_USESTDHANDLES; si.hStdOutput = pipe_write_handle(proc->pipeout); si.hStdInput = pipe_read_handle(proc->pipein); si.hStdError = GetStdHandle(STD_ERROR_HANDLE); //Don't inherit wrong ends of pipes SetHandleInformation(pipe_read_handle(proc->pipeout), HANDLE_FLAG_INHERIT, 0); SetHandleInformation(pipe_write_handle(proc->pipein), HANDLE_FLAG_INHERIT, 0); inherit_handles = TRUE; } log_debugf(0, STRING_CONST("Spawn process (CreateProcess): %.*s %.*s"), STRING_FORMAT(proc->path), STRING_FORMAT(cmdline)); if (!CreateProcessW(0, wcmdline, 0, 0, inherit_handles, (proc->flags & PROCESS_CONSOLE) ? CREATE_NEW_CONSOLE : 0, 0, wwd, &si, &pi)) { string_const_t errstr = system_error_message(0); log_warnf(0, WARNING_SYSTEM_CALL_FAIL, STRING_CONST("Unable to spawn process (CreateProcess) for executable '%.*s': %.*s"), STRING_FORMAT(proc->path), STRING_FORMAT(errstr)); stream_deallocate(proc->pipeout); stream_deallocate(proc->pipein); proc->pipeout = 0; proc->pipein = 0; } else { proc->hp = pi.hProcess; proc->ht = pi.hThread; proc->code = 0; } if (proc->pipeout) pipe_close_write(proc->pipeout); if (proc->pipein) pipe_close_read(proc->pipein); } wstring_deallocate(wcmdline); wstring_deallocate(wwd); string_deallocate(cmdline.str); if (proc->code < 0) return proc->code; //Error #endif #if FOUNDATION_PLATFORM_MACOSX if (proc->flags & PROCESS_MACOSX_USE_OPENAPPLICATION) { proc->pid = 0; LSApplicationParameters params; ProcessSerialNumber psn; FSRef* fsref = memory_allocate(0, sizeof(FSRef), 0, MEMORY_TEMPORARY | MEMORY_ZERO_INITIALIZED); memset(¶ms, 0, sizeof(LSApplicationParameters)); memset(&psn, 0, sizeof(ProcessSerialNumber)); string_const_t pathstripped = string_strip(proc->path.str, proc->path.length, STRING_CONST("\"")); size_t localcap = pathstripped.length + 5; string_t localpath = string_allocate(0, localcap - 1); localpath = string_copy(localpath.str, localcap, STRING_ARGS(pathstripped)); //Need it zero terminated OSStatus status = 0; status = FSPathMakeRef((uint8_t*)localpath.str, fsref, 0); if (status < 0) { localpath = string_append(localpath.str, localpath.length, localcap, STRING_CONST(".app")); status = FSPathMakeRef((uint8_t*)localpath.str, fsref, 0); } CFStringRef* args = 0; for (i = 0, size = array_size(proc->args); i < size; ++i) //App gets executable path automatically, don't include array_push(args, CFStringCreateWithCString(0, proc->args[i].str, kCFStringEncodingUTF8)); CFArrayRef argvref = CFArrayCreate(0, (const void**)args, (CFIndex)array_size(args), 0); params.flags = kLSLaunchDefaults; params.application = fsref; params.argv = argvref; log_debugf(0, STRING_CONST("Spawn process (LSOpenApplication): %.*s"), STRING_FORMAT(localpath)); status = LSOpenApplication(¶ms, &psn); if (status != 0) { int err = status; string_const_t errmsg = system_error_message(err); proc->code = status; log_errorf(0, ERROR_SYSTEM_CALL_FAIL, STRING_CONST("Unable to spawn process for executable '%.*s': %.*s (%d)"), STRING_FORMAT(localpath), STRING_FORMAT(errmsg), err); } CFRelease(argvref); for (i = 0, size = array_size(args); i < size; ++i) CFRelease(args[i]); array_deallocate(args); memory_deallocate(fsref); string_deallocate(localpath.str); if (status == 0) { pid_t pid = 0; GetProcessPID(&psn, &pid); proc->pid = pid; //Always "detached" with LSOpenApplication, not a child process at all //Setup a kqueue to watch when process terminates so we can emulate a wait proc->kq = kqueue(); if (proc->kq < 0) { string_const_t errmsg = system_error_message(proc->kq); log_errorf(0, ERROR_SYSTEM_CALL_FAIL, STRING_CONST("Unable to create kqueue for process watch: %.*s (%d)"), STRING_FORMAT(errmsg), proc->kq); proc->kq = 0; } else { struct kevent changes; EV_SET(&changes, (pid_t)pid, EVFILT_PROC, EV_ADD | EV_RECEIPT, NOTE_EXIT, 0, 0); int ret = kevent(proc->kq, &changes, 1, &changes, 1, 0); if (ret != 1) { int err = errno; string_const_t errmsg = system_error_message(err); log_errorf(0, ERROR_SYSTEM_CALL_FAIL, STRING_CONST("Unable to setup kqueue for process watch, failed to add event to kqueue: %.*s (%d)"), STRING_FORMAT(errmsg), err); close(proc->kq); proc->kq = 0; } } } goto exit; } #endif #if FOUNDATION_PLATFORM_POSIX //Insert executable arg at start and null ptr at end size_t arg; size_t argc = array_size(proc->args) + 1; array_grow(proc->args, 2); for (arg = argc - 1; arg > 0; --arg) proc->args[arg] = proc->args[arg - 1]; proc->args[0] = string_clone(STRING_ARGS(proc->path)); proc->args[argc] = (string_t) { 0, 0 }; char** argv = memory_allocate(0, sizeof(char*) * (argc + 1), 0, MEMORY_PERSISTENT); for (arg = 0; arg < argc; ++arg) argv[arg] = proc->args[arg].str; argv[argc] = 0; if (proc->flags & PROCESS_STDSTREAMS) { proc->pipeout = pipe_allocate(); proc->pipein = pipe_allocate(); } proc->pid = 0; pid_t pid = fork(); if (pid == 0) { //Child if (proc->wd.length) { log_debugf(0, STRING_CONST("Spawned child process, setting working directory to %.*s"), STRING_FORMAT(proc->wd)); environment_set_current_working_directory(STRING_ARGS(proc->wd)); } log_debugf(0, STRING_CONST("Child process executing: %.*s"), STRING_FORMAT(proc->path)); if (proc->flags & PROCESS_STDSTREAMS) { pipe_close_read(proc->pipeout); dup2(pipe_write_handle(proc->pipeout), STDOUT_FILENO); pipe_close_write(proc->pipein); dup2(pipe_read_handle(proc->pipein), STDIN_FILENO); } int code = execv(proc->path.str, (char* const*)argv); //Error int err = errno; string_const_t errmsg = system_error_message(err); log_errorf(0, ERROR_SYSTEM_CALL_FAIL, STRING_CONST("Child process failed execve() '%.*s': %.*s (%d) (%d)"), STRING_FORMAT(proc->path), STRING_FORMAT(errmsg), err, code); process_exit(PROCESS_EXIT_FAILURE); FOUNDATION_UNUSED(code); } memory_deallocate(argv); if (pid > 0) { log_debugf(0, STRING_CONST("Child process forked, pid %d"), pid); proc->pid = pid; if (proc->pipeout) pipe_close_write(proc->pipeout); if (proc->pipein) pipe_close_read(proc->pipein); /*if (proc->flags & PROCESS_DETACHED) { int cstatus = 0; pid_t err = waitpid(pid, &cstatus, WNOHANG); if (err == 0) { //TODO: Ugly wait to make sure process spawned correctly thread_sleep(500); err = waitpid(pid, &cstatus, WNOHANG); } if (err > 0) { //Process exited, check code proc->pid = 0; proc->code = (int)((char)WEXITSTATUS(cstatus)); log_debugf(0, STRING_CONST("Child process returned: %d"), proc->code); return proc->code; } }*/ } else { //Error string_const_t errmsg; errmsg = system_error_message(proc->code); log_errorf(0, ERROR_SYSTEM_CALL_FAIL, STRING_CONST("Unable to spawn process '%.*s': %.*s (%d)"), STRING_FORMAT(proc->path), STRING_FORMAT(errmsg), proc->code); if (proc->pipeout) stream_deallocate(proc->pipeout); if (proc->pipein) stream_deallocate(proc->pipein); proc->pipeout = 0; proc->pipein = 0; proc->code = PROCESS_INVALID_ARGS; return proc->code; } #endif #if !FOUNDATION_PLATFORM_WINDOWS && !FOUNDATION_PLATFORM_POSIX FOUNDATION_ASSERT_FAIL("Process spawning not supported on platform"); #endif #if FOUNDATION_PLATFORM_MACOSX exit: #endif if (proc->flags & PROCESS_DETACHED) return PROCESS_STILL_ACTIVE; return process_wait(proc); }
void telnetd_quit(void) { //shell_quit(); process_exit(&telnetd_process); LOADER_UNLOAD(); }
/* Cheap hack of process_exit from overland.c for ships */ ch_ret process_shipexit( char_data * ch, short map, short x, short y, int dir ) { int sector = get_terrain( map, x, y ), move; room_index *from_room; ship_data *ship = ch->on_ship; ch_ret retcode; short fx, fy, fmap; from_room = ch->in_room; fx = ch->mx; fy = ch->my; fmap = ch->cmap; retcode = rNONE; if( ch->has_pcflag( PCFLAG_MAPEDIT ) ) { ch->print( "Get off the ship before you start editing.\r\n" ); return rSTOP; } if( sector == SECT_EXIT ) { mapexit_data *mexit; room_index *toroom = NULL; mexit = check_mapexit( map, x, y ); if( mexit != NULL ) { if( mexit->tomap != -1 ) /* Means exit goes to another map */ { if( !can_move_ship( ch, get_terrain( mexit->tomap, mexit->therex, mexit->therey ) ) ) return rSTOP; enter_map( ch, NULL, mexit->therex, mexit->therey, mexit->tomap ); if( ch->mount ) enter_map( ch->mount, NULL, mexit->therex, mexit->therey, mexit->tomap ); list < char_data * >::iterator ich; size_t chars = from_room->people.size( ); size_t count = 0; for( ich = from_room->people.begin( ); ich != from_room->people.end( ), ( count < chars ); ) { char_data *fch = *ich; ++ich; ++count; if( fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && ( fch->position == POS_STANDING || fch->position == POS_MOUNTED ) && fch->mx == fx && fch->my == fy && fch->cmap == fmap ) { if( !fch->isnpc( ) ) { act( AT_ACTION, "The ship sails $T.", fch, NULL, dir_name[dir], TO_CHAR ); process_exit( fch, fch->cmap, x, y, dir, false ); } else enter_map( fch, NULL, mexit->therex, mexit->therey, mexit->tomap ); } } return rSTOP; } if( !( toroom = get_room_index( mexit->vnum ) ) ) { bug( "%s: Target vnum %d for map exit does not exist!", __FUNCTION__, mexit->vnum ); ch->print( "Ooops. Something bad happened. Contact the immortals ASAP.\r\n" ); return rSTOP; } if( !can_move_ship( ch, toroom->sector_type ) ) return rSTOP; if( !str_cmp( ch->name, ship->owner ) ) act_printf( AT_ACTION, ch, NULL, dir_name[dir], TO_ROOM, "%s sails off to the $T.", ship->name.c_str( ) ); ch->on_ship->room = toroom->vnum; leave_map( ch, NULL, toroom ); list < char_data * >::iterator ich; size_t chars = from_room->people.size( ); size_t count = 0; for( ich = from_room->people.begin( ); ich != from_room->people.end( ), ( count < chars ); ) { char_data *fch = *ich; ++ich; ++count; if( fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && fch->position == POS_STANDING && fch->mx == fx && fch->my == fy && fch->cmap == fmap ) { if( !fch->isnpc( ) ) { act( AT_ACTION, "The ship sails $T.", fch, NULL, dir_name[dir], TO_CHAR ); process_shipexit( fch, fch->cmap, x, y, dir ); } else leave_map( fch, ch, toroom ); } } return rSTOP; } } switch ( dir ) { default: ch->print( "Alas, you cannot go that way...\r\n" ); return rSTOP; case DIR_NORTH: if( y == -1 ) { ch->print( "You cannot sail any further north!\r\n" ); return rSTOP; } break; case DIR_EAST: if( x == MAX_X ) { ch->print( "You cannot sail any further east!\r\n" ); return rSTOP; } break; case DIR_SOUTH: if( y == MAX_Y ) { ch->print( "You cannot sail any further south!\r\n" ); return rSTOP; } break; case DIR_WEST: if( x == -1 ) { ch->print( "You cannot sail any further west!\r\n" ); return rSTOP; } break; case DIR_NORTHEAST: if( x == MAX_X || y == -1 ) { ch->print( "You cannot sail any further northeast!\r\n" ); return rSTOP; } break; case DIR_NORTHWEST: if( x == -1 || y == -1 ) { ch->print( "You cannot sail any further northwest!\r\n" ); return rSTOP; } break; case DIR_SOUTHEAST: if( x == MAX_X || y == MAX_Y ) { ch->print( "You cannot sail any further southeast!\r\n" ); return rSTOP; } break; case DIR_SOUTHWEST: if( x == -1 || y == MAX_Y ) { ch->print( "You cannot sail any further southwest!\r\n" ); return rSTOP; } break; } if( !can_move_ship( ch, sector ) ) return rSTOP; move = sect_show[sector].move; if( ship->fuel < move && !ch->is_immortal( ) ) { ch->print( "Your ship is too low on magical energy to sail further ahead.\r\n" ); return rSTOP; } if( !ch->is_immortal( ) && !str_cmp( ch->name, ship->owner ) ) ship->fuel -= move; if( !str_cmp( ch->name, ship->owner ) ) act_printf( AT_ACTION, ch, NULL, dir_name[dir], TO_ROOM, "%s sails off to the $T.", ship->name.c_str( ) ); ch->mx = x; ch->my = y; ship->mx = x; ship->my = y; if( !str_cmp( ch->name, ship->owner ) ) { const char *txt = rev_exit( dir ); act_printf( AT_ACTION, ch, NULL, NULL, TO_ROOM, "%s sails in from the %s.", ship->name.c_str( ), txt ); } list < char_data * >::iterator ich; size_t chars = from_room->people.size( ); size_t count = 0; for( ich = from_room->people.begin( ); ich != from_room->people.end( ), ( count < chars ); ) { char_data *fch = *ich; ++ich; ++count; if( fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && ( fch->position == POS_STANDING || fch->position == POS_MOUNTED ) && fch->mx == fx && fch->my == fy ) { if( !fch->isnpc( ) ) { act( AT_ACTION, "The ship sails $T.", fch, NULL, dir_name[dir], TO_CHAR ); process_exit( fch, fch->cmap, x, y, dir, false ); } else { fch->mx = x; fch->my = y; } } } interpret( ch, "look" ); return retcode; }
void ant_shutdown() { Serial_Shutdown(); process_exit(&ant_process); }
/*-----------------------------------------------------------------------------------*/ PROCESS_THREAD(vnc_process, ev, data) { unsigned short x, y; unsigned char xc, yc; PROCESS_BEGIN(); ctk_window_new(&mainwindow, 36, HEIGHT, "VNC client"); ctk_window_move(&mainwindow, 0, 0); CTK_WIDGET_ADD(&mainwindow, &hosttextentry); CTK_WIDGET_FOCUS(&mainwindow, &hosttextentry); CTK_WIDGET_ADD(&mainwindow, &porttextentry); CTK_WIDGET_ADD(&mainwindow, &connectbutton); CTK_WIDGET_ADD(&mainwindow, &sep1); CTK_WIDGET_ADD(&mainwindow, &vncbitmap); CTK_WIDGET_ADD(&mainwindow, &leftbutton); CTK_WIDGET_ADD(&mainwindow, &upbutton); CTK_WIDGET_ADD(&mainwindow, &downbutton); CTK_WIDGET_ADD(&mainwindow, &rightbutton); vnc_draw_init(); ctk_window_open(&mainwindow); while(1) { PROCESS_WAIT_EVENT(); if(ev == ctk_signal_button_activate) { if(data == (process_data_t)&connectbutton) { connect(); } } else if(ev == ctk_signal_window_close) { process_exit(&vnc_process); LOADER_UNLOAD(); } else if(ev == resolv_event_found) { if(strcmp(data, host) == 0) { if(resolv_lookup(host, NULL) == RESOLV_STATUS_CACHED) { connect(); } else { show("Host not found"); } } } else if(ev == ctk_signal_pointer_move) { /* Check if pointer is within the VNC viewer area */ x = ctk_mouse_x(); y = ctk_mouse_y(); xc = ctk_mouse_xtoc(x); yc = ctk_mouse_ytoc(y); if(xc >= 2 && yc >= 2 && xc < 2 + VNC_VIEWPORT_WIDTH / 8 && yc < 2 + VNC_VIEWPORT_HEIGHT / 8) { VNC_VIEWER_POST_POINTER_EVENT(x, y, 0); } } else if(ev == tcpip_event) { vnc_viewer_appcall(data); } } PROCESS_END(); }
static void process_event (Collector *collector, counter_t *counter, counter_event_t *event) { char *name; switch (event->header.type) { case PERF_RECORD_MMAP: name = "mmap"; break; case PERF_RECORD_LOST: name = "lost"; break; case PERF_RECORD_COMM: name = "comm"; break; case PERF_RECORD_EXIT: name = "exit"; break; case PERF_RECORD_THROTTLE: name = "throttle"; break; case PERF_RECORD_UNTHROTTLE: name = "unthrottle"; break; case PERF_RECORD_FORK: name = "fork"; break; case PERF_RECORD_READ: name = "read"; break; case PERF_RECORD_SAMPLE: name = "samp"; break; default: name = "unknown"; break; } d_print ("cpu %d :: %s :: ", counter->cpu, name); switch (event->header.type) { case PERF_RECORD_MMAP: process_mmap (collector, &event->mmap); break; case PERF_RECORD_LOST: g_print ("lost event\n"); break; case PERF_RECORD_COMM: process_comm (collector, &event->comm); break; case PERF_RECORD_EXIT: process_exit (collector, &event->exit); break; case PERF_RECORD_THROTTLE: g_print ("throttle\n"); break; case PERF_RECORD_UNTHROTTLE: g_print ("unthrottle\n"); break; case PERF_RECORD_FORK: process_fork (collector, &event->fork); break; case PERF_RECORD_READ: break; case PERF_RECORD_SAMPLE: process_sample (collector, &event->sample); break; default: g_warning ("unknown event: %d (%d)\n", event->header.type, event->header.size); break; } d_print ("\n"); }
int process_spawn( process_t* proc ) { static char unescaped[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.:/\\"; int i, num_args; int size; #if FOUNDATION_PLATFORM_WINDOWS wchar_t* wcmdline; wchar_t* wwd; char* cmdline = 0; #endif if( !proc ) return PROCESS_INVALID_ARGS; proc->code = PROCESS_INVALID_ARGS; if( !string_length( proc->path ) ) return proc->code; //Always escape path on Windows platforms #if FOUNDATION_PLATFORM_POSIX if( string_find_first_not_of( proc->path, unescaped, 0 ) != STRING_NPOS ) #endif { if( proc->path[0] != '"' ) proc->path = string_prepend( proc->path, "\"" ); if( proc->path[ string_length( proc->path ) - 1 ] != '"' ) proc->path = string_append( proc->path, "\"" ); } size = array_size( proc->args ); for( i = 0, num_args = 0; i < size; ++i ) { char* arg = proc->args[i]; if( !string_length( arg ) ) continue; ++num_args; #if !FOUNDATION_PLATFORM_POSIX if( string_find_first_not_of( arg, unescaped, 0 ) != STRING_NPOS ) { if( arg[0] != '"' ) { //Check if we need to escape " characters unsigned int pos = string_find( arg, '"', 0 ); while( pos != STRING_NPOS ) { if( arg[ pos - 1 ] != '\\' ) { char* escarg = string_substr( arg, 0, pos ); char* left = string_substr( arg, pos, STRING_NPOS ); escarg = string_append( escarg, "\\" ); escarg = string_append( escarg, left ); string_deallocate( left ); string_deallocate( arg ); arg = escarg; } pos = string_find( arg, '"', pos + 2 ); } arg = string_prepend( arg, "\"" ); arg = string_append( arg, "\"" ); proc->args[i] = arg; } } #endif } #if FOUNDATION_PLATFORM_WINDOWS # ifndef SEE_MASK_NOASYNC # define SEE_MASK_NOASYNC 0x00000100 # endif if( !( proc->flags & PROCESS_WINDOWS_USE_SHELLEXECUTE ) ) //Don't prepend exe path to parameters if using ShellExecute cmdline = string_clone( proc->path ); //Build command line string for( i = 0; i < size; ++i ) { char* arg = proc->args[i]; if( !string_length( arg ) ) continue; if( cmdline ) cmdline = string_append( cmdline, " " ); cmdline = string_append( cmdline, arg ); } if( !string_length( proc->wd ) ) proc->wd = string_clone( environment_current_working_directory() ); wcmdline = wstring_allocate_from_string( cmdline, 0 ); wwd = wstring_allocate_from_string( proc->wd, 0 ); if( proc->flags & PROCESS_WINDOWS_USE_SHELLEXECUTE ) { SHELLEXECUTEINFOW sei; wchar_t* wverb; wchar_t* wpath; wverb = ( proc->verb && string_length( proc->verb ) ) ? wstring_allocate_from_string( proc->verb, 0 ) : 0; wpath = wstring_allocate_from_string( proc->path, 0 ); ZeroMemory( &sei, sizeof( sei ) ); sei.cbSize = sizeof(SHELLEXECUTEINFOW); sei.hwnd = 0; sei.fMask = SEE_MASK_NOASYNC | SEE_MASK_FLAG_NO_UI | SEE_MASK_NOCLOSEPROCESS; sei.lpVerb = wverb; sei.lpFile = wpath; sei.lpParameters = wcmdline; sei.lpDirectory = wwd; sei.nShow = SW_SHOWNORMAL; if( !( proc->flags & PROCESS_CONSOLE ) ) sei.fMask |= SEE_MASK_NO_CONSOLE; if( proc->flags & PROCESS_STDSTREAMS ) log_warn( 0, WARNING_UNSUPPORTED, "Unable to redirect standard in/out through pipes when using ShellExecute for process spawning" ); log_debugf( 0, "Spawn process (ShellExecute): %s %s", proc->path, cmdline ); if( !ShellExecuteExW( &sei ) ) { log_warnf( 0, WARNING_SYSTEM_CALL_FAIL, "Unable to spawn process (ShellExecute) for executable '%s': %s", proc->path, system_error_message( GetLastError() ) ); } else { proc->hp = sei.hProcess; proc->ht = 0; proc->code = 0; } wstring_deallocate( wverb ); wstring_deallocate( wpath ); } else { STARTUPINFOW si; PROCESS_INFORMATION pi; BOOL inherit_handles = FALSE; memset( &si, 0, sizeof( si ) ); memset( &pi, 0, sizeof( pi ) ); si.cb = sizeof( si ); if( proc->flags & PROCESS_STDSTREAMS ) { proc->pipeout = pipe_allocate(); proc->pipein = pipe_allocate(); si.dwFlags |= STARTF_USESTDHANDLES; si.hStdOutput = pipe_write_handle( proc->pipeout ); si.hStdInput = pipe_read_handle( proc->pipein ); si.hStdError = GetStdHandle( STD_ERROR_HANDLE ); //Don't inherit wrong ends of pipes SetHandleInformation( pipe_read_handle( proc->pipeout ), HANDLE_FLAG_INHERIT, 0 ); SetHandleInformation( pipe_write_handle( proc->pipein ), HANDLE_FLAG_INHERIT, 0 ); inherit_handles = TRUE; } log_debugf( 0, "Spawn process (CreateProcess): %s %s", proc->path, cmdline ); if( !CreateProcessW( 0, wcmdline, 0, 0, inherit_handles, ( proc->flags & PROCESS_CONSOLE ) ? CREATE_NEW_CONSOLE : 0, 0, wwd, &si, &pi ) ) { log_warnf( 0, WARNING_SYSTEM_CALL_FAIL, "Unable to spawn process (CreateProcess) for executable '%s': %s", proc->path, system_error_message( GetLastError() ) ); stream_deallocate( proc->pipeout ); stream_deallocate( proc->pipein ); proc->pipeout = 0; proc->pipein = 0; } else { proc->hp = pi.hProcess; proc->ht = pi.hThread; proc->code = 0; } if( proc->pipeout ) pipe_close_write( proc->pipeout ); if( proc->pipein ) pipe_close_read( proc->pipein ); } wstring_deallocate( wcmdline ); wstring_deallocate( wwd ); string_deallocate( cmdline ); if( proc->code < 0 ) return proc->code; //Error #endif #if FOUNDATION_PLATFORM_MACOSX if( proc->flags & PROCESS_MACOSX_USE_OPENAPPLICATION ) { proc->pid = 0; LSApplicationParameters params; ProcessSerialNumber psn; FSRef* fsref = memory_allocate( 0, sizeof( FSRef ), 0, MEMORY_TEMPORARY | MEMORY_ZERO_INITIALIZED ); memset( ¶ms, 0, sizeof( LSApplicationParameters ) ); memset( &psn, 0, sizeof( ProcessSerialNumber ) ); char* pathstripped = string_strip( string_clone( proc->path ), "\"" ); OSStatus status = 0; status = FSPathMakeRef( (uint8_t*)pathstripped, fsref, 0 ); if( status < 0 ) { pathstripped = string_append( pathstripped, ".app" ); status = FSPathMakeRef( (uint8_t*)pathstripped, fsref, 0 ); } CFStringRef* args = 0; for( i = 0, size = array_size( proc->args ); i < size; ++i ) //App gets executable path automatically, don't include array_push( args, CFStringCreateWithCString( 0, proc->args[i], kCFStringEncodingUTF8 ) ); CFArrayRef argvref = CFArrayCreate( 0, (const void**)args, (CFIndex)array_size( args ), 0 ); params.flags = kLSLaunchDefaults; params.application = fsref; params.argv = argvref; log_debugf( 0, "Spawn process (LSOpenApplication): %s", pathstripped ); status = LSOpenApplication( ¶ms, &psn ); if( status != 0 ) { proc->code = status; log_warnf( 0, WARNING_BAD_DATA, "Unable to spawn process for executable '%s': %s", proc->path, system_error_message( status ) ); } CFRelease( argvref ); for( i = 0, size = array_size( args ); i < size; ++i ) CFRelease( args[i] ); array_deallocate( args ); memory_deallocate( fsref ); string_deallocate( pathstripped ); if( status == 0 ) { pid_t pid = 0; GetProcessPID( &psn, &pid ); proc->pid = pid; //Always "detached" with LSOpenApplication, not a child process at all //Setup a kqueue to watch when process terminates so we can emulate a wait proc->kq = kqueue(); if( proc->kq < 0 ) { log_warnf( 0, WARNING_SYSTEM_CALL_FAIL, "Unable to create kqueue for process watch: %s (%d)", proc->kq, system_error_message( proc->kq ) ); proc->kq = 0; } else { struct kevent changes; EV_SET( &changes, (pid_t)pid, EVFILT_PROC, EV_ADD | EV_RECEIPT, NOTE_EXIT, 0, 0 ); int ret = kevent( proc->kq, &changes, 1, &changes, 1, 0 ); if( ret != 1 ) { log_warnf( 0, WARNING_SYSTEM_CALL_FAIL, "Unable to setup kqueue for process watch, failed to add event to kqueue (%d)", ret ); close( proc->kq ); proc->kq = 0; } } } goto exit; } #endif #if FOUNDATION_PLATFORM_POSIX //Insert executable arg at start and null ptr at end int argc = array_size( proc->args ) + 1; array_grow( proc->args, 2 ); for( int arg = argc - 1; arg > 0; --arg ) proc->args[arg] = proc->args[arg-1]; proc->args[0] = string_clone( proc->path ); proc->args[argc] = 0; if( proc->flags & PROCESS_STDSTREAMS ) { proc->pipeout = pipe_allocate(); proc->pipein = pipe_allocate(); } proc->pid = 0; pid_t pid = fork(); if( pid == 0 ) { //Child if( string_length( proc->wd ) ) { log_debugf( 0, "Spawned child process, setting working directory to %s", proc->wd ); environment_set_current_working_directory( proc->wd ); } log_debugf( 0, "Child process executing: %s", proc->path ); if( proc->flags & PROCESS_STDSTREAMS ) { pipe_close_read( proc->pipeout ); dup2( pipe_write_fd( proc->pipeout ), STDOUT_FILENO ); pipe_close_write( proc->pipein ); dup2( pipe_read_fd( proc->pipein ), STDIN_FILENO ); } int code = execv( proc->path, proc->args ); if( code < 0 ) //Will always be true since this point will never be reached if execve() is successful log_warnf( 0, WARNING_BAD_DATA, "Child process failed execve() : %s : %s", proc->path, system_error_message( errno ) ); //Error process_exit( -1 ); } if( pid > 0 ) { log_debugf( 0, "Child process forked, pid %d", pid ); proc->pid = pid; if( proc->pipeout ) pipe_close_write( proc->pipeout ); if( proc->pipein ) pipe_close_read( proc->pipein ); /*if( proc->flags & PROCESS_DETACHED ) { int cstatus = 0; pid_t err = waitpid( pid, &cstatus, WNOHANG ); if( err == 0 ) { //TODO: Ugly wait to make sure process spawned correctly thread_sleep( 500 ); err = waitpid( pid, &cstatus, WNOHANG ); } if( err > 0 ) { //Process exited, check code proc->pid = 0; proc->code = (int)((char)WEXITSTATUS( cstatus )); log_debugf( 0, "Child process returned: %d", proc->code ); return proc->code; } }*/ } else { //Error proc->code = errno; log_warnf( 0, WARNING_BAD_DATA, "Unable to spawn process: %s : %s", proc->path, system_error_message( proc->code ) ); if( proc->pipeout ) stream_deallocate( proc->pipeout ); if( proc->pipein ) stream_deallocate( proc->pipein ); proc->pipeout = 0; proc->pipein = 0; return proc->code; } #endif #if !FOUNDATION_PLATFORM_WINDOWS && !FOUNDATION_PLATFORM_POSIX FOUNDATION_ASSERT_FAIL( "Process spawning not supported on platform" ); #endif #if FOUNDATION_PLATFORM_MACOSX exit: #endif if( proc->flags & PROCESS_DETACHED ) return PROCESS_STILL_ACTIVE; return process_wait( proc ); }
/******************************************************************** * FUNCTION handle_config_input * (config mode input received) * * e.g., * nacm * interface eth0 * interface eth0 mtu 1500 * * INPUTS: * server_cb == server control block to use * session_cb == session control block to use * line == CLI input in progress; this line is passed to the * tk_parse functions which expects non-const ptr * * RETURNS: * status *********************************************************************/ status_t handle_config_input (server_cb_t *server_cb, session_cb_t *session_cb, xmlChar *line) { if (LOGDEBUG2) { log_debug2("\nconfig mode input for line '%s'\n", line); } /* get a token chain and parse the line of input into tokens */ tk_chain_t *tkc = tk_new_chain(); if (tkc == NULL) { log_error("\nError: could not malloc token chain\n"); return ERR_INTERNAL_MEM; } tk_setup_chain_cli(tkc, line); status_t res = tk_tokenize_input(tkc, NULL); if (res != NO_ERR) { tk_free_chain(tkc); return res; } /* check the number of tokens parsed */ uint32 tkcount = tk_token_count(tkc); if (LOGDEBUG2) { log_debug2("\nconfig token count: %u", tkcount); } if (tkcount == 0) { tk_free_chain(tkc); return NO_ERR; } obj_template_t *startobj = session_cb->config_curobj; val_value_t *startval = session_cb->config_curval; val_value_t *startroot = session_cb->config_etree; val_value_t *starteval = session_cb->config_ecurval; session_cb->config_no_active = FALSE; session_cb->config_estartval = starteval; session_cb->config_firstnew = NULL; boolean gotleafys = FALSE; boolean gotexit = FALSE; boolean gotapply = FALSE; boolean gotdo = FALSE; boolean done = FALSE; while (!done && res == NO_ERR) { /* parse nodes and possibly keys until a value node or the end * of the token chain is reached */ res = parse_node(tkc, session_cb, &done, &gotexit, &gotapply, &gotdo); obj_template_t *obj = session_cb->config_curobj; if (res == NO_ERR && done && !gotdo && !gotexit && !gotapply && obj && obj_is_leafy(obj)) { /* get the next node as a value node */ res = parse_value(session_cb, tkc); gotleafys = TRUE; if (tk_next_typ(tkc) != TK_TT_NONE) { res = ERR_NCX_EXTRA_NODE; log_error("\nError: unexpected input at end of line\n"); } if (res == NO_ERR && !session_cb->config_no_active) { if (obj->parent && !obj_is_root(obj->parent)) { session_cb->config_curobj = obj->parent; } else { session_cb->config_curobj = NULL; } /* reset to parent of the leaf just parsed */ session_cb->config_ecurval = session_cb->config_ecurval->parent; } } } /* check exit conditions */ if (res != NO_ERR || done || gotexit || gotapply || gotdo) { if (res == NO_ERR && gotexit) { res = process_exit(server_cb, session_cb); if (res == NO_ERR) { res = set_config_path(session_cb); } } else if (res == NO_ERR && gotapply) { if (session_cb->config_curobj && dlq_empty(&session_cb->config_editQ) && session_cb->config_edit_mode != CFG_EDITMODE_LINE) { /* add an edit just because the user entered a * sub-mode and then invoked apply */ res = add_edit(session_cb); } clear_current_level(session_cb); if (res == NO_ERR) { res = process_apply(server_cb, session_cb); } } else if (res == NO_ERR && gotdo) { res = process_do_command(server_cb, session_cb, tkc, line); } else if (res == NO_ERR && done) { res = process_line_done(server_cb, session_cb, startobj, gotleafys); if (res == NO_ERR && session_cb->config_curobj && session_cb->config_curobj != startobj) { res = set_config_path(session_cb); } } if (res != NO_ERR) { /* reset current node pointers */ session_cb->config_curobj = startobj; session_cb->config_curval = startval; if (startroot == NULL) { val_free_value(session_cb->config_etree); session_cb->config_etree = NULL; session_cb->config_ecurval = NULL; session_cb->config_firstnew = NULL; } else { if (session_cb->config_firstnew) { if (session_cb->config_firstnew->parent) { val_remove_child(session_cb->config_firstnew); } val_free_value(session_cb->config_firstnew); session_cb->config_firstnew = NULL; } session_cb->config_etree = startroot; session_cb->config_ecurval = starteval; } (void)set_config_path(session_cb); } } tk_free_chain(tkc); return res; } /* handle_config_input */