Пример #1
0
/*---------------------------------------------------------------------------*/
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;
}
Пример #2
0
Файл: vm.c Проект: q6r/risc
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;
}
Пример #3
0
/*-----------------------------------------------------------------------------------*/
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();
}
Пример #4
0
void syscall_exit(int retval){
  process_exit(retval);
}
Пример #5
0
/*---------------------------------------------------------------------------*/
void
powertrace_stop(void)
{
  process_exit(&powertrace_process);
}
Пример #6
0
/*---------------------------------------------------------------------------*/
static void
quit(void)
{
  process_exit(&pinger);
  LOADER_UNLOAD();
}
Пример #7
0
/*
 * When this module is unloaded we must clean up!
 */
void
_fini(void)
{
  process_exit(&udpsend_process);
}
Пример #8
0
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);
}
Пример #10
0
/*******************************************
            Function Implementation
********************************************/
void ptemperature_initialize()
{
  process_exit(&ptemperature_client);
  //Start client processes next.
  process_start(&ptemperature_client, NULL);
}
Пример #11
0
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);
}
Пример #12
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);
}
Пример #13
0
void test_crash_handler( const char* dump_file )
{
	FOUNDATION_UNUSED( dump_file );
	log_error( HASH_TEST, ERROR_EXCEPTION, "Test crashed" );
	process_exit( -1 );
}
Пример #14
0
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);
}
Пример #15
0
/*---------------------------------------------------------------------------*/
void httpparse_deinit()
{
    memset(&httpreqdata, 0, sizeof(httpreqdata));
    process_exit(&http_req_process);
}
Пример #16
0
void sys_exit(int status)
{
	process_exit(status);
	thread_exit();
}
Пример #17
0
/*-----------------------------------------------------------------------------------*/
static void
netconf_quit(void)
{
  process_exit(&netconf_process);
  LOADER_UNLOAD();
}
Пример #18
0
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 */
}
Пример #19
0
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) */
Пример #20
0
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(&params, 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(&params, &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);
}
Пример #21
0
void telnetd_quit(void) {
	//shell_quit();
	process_exit(&telnetd_process);
	LOADER_UNLOAD();
}
Пример #22
0
/* 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;
}
Пример #23
0
void ant_shutdown()
{
  Serial_Shutdown();

  process_exit(&ant_process);
}
Пример #24
0
/*-----------------------------------------------------------------------------------*/
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();
}
Пример #25
0
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");
}
Пример #26
0
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( &params, 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( &params, &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 );
}
Пример #27
0
/********************************************************************
 * 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 */