Exemple #1
0
/**
 * Forks and runs the given application, waits for a maximum of timeout seconds for process to finish.
 *
 * @param argv The arguments values, the first one is the application path or name
 */
void bb_run_fork_wait(char** argv, int timeout) {
  check_handler();
  // Fork and attempt to run given application
  pid_t ret = fork();
  if (ret == 0) {
    // Fork went ok, child process replace
    bb_run_exec(argv);
  } else {
    if (ret > 0) {
      // Fork went ok, parent process continues
      bb_log(LOG_DEBUG, "Process %s started, PID %i.\n", argv[0], ret);
      pidlist_add(ret);
      //sleep until process finishes or timeout reached
      int i = 0;
      while (bb_is_running(ret) && ((i < timeout) || (timeout == 0)) && dowait) {
        usleep(1000000);
        i++;
      }
      //make a single attempt to kill the process if timed out, without waiting
      if (bb_is_running(ret)) {
        bb_stop(ret);
      }
    } else {
      // Fork failed
      bb_log(LOG_ERR, "Process %s could not be started. fork() failed.\n", argv[0]);
      return;
    }
  }
  return;
}
Exemple #2
0
uint8_t bb_i2c_read( uint8_t addr, uint8_t *buf, uint8_t len )
{
    uint8_t rc = 0;
    
    bb_start();

    bb_out( addr | 0x01 ); // address + R
    if ( get_ack() )
    {
        while ( len > 0 )
        {
            *buf++ = bb_in();
                
            len--;
            if ( len > 0 )
            {
                send_ack();
            }
            else
            {
                send_nak();
            }
        }
    }
    else
    {
        rc = 1;
    }
    
    bb_stop();
    
    return rc;
}
Exemple #3
0
uint8_t bb_i2c_write( uint8_t addr, uint8_t *buf, uint8_t len )
{
    uint8_t rc = 0;

    bb_start();
    
    bb_out( addr );    // address + W
    if ( get_ack() )
    {
        while ( len > 0 )
        {
            bb_out( *buf++ );
            
            if ( get_ack() == 0 )
            {
                rc = 1;
                break;
            }
            
            len--;
        }
    }
    else 
    {
        rc = 1;
    }

    bb_stop();

    return rc;
}
Exemple #4
0
/**
 * Start the X server by fork-exec, turn card on and load driver if needed.
 * If after this method finishes X is running, it was successfull.
 * If it somehow fails, X should not be running after this method finishes.
 */
void start_secondary(void) {
  char driver[BUFFER_SIZE] = {0};
  /* enable card if the switcher is available */
  if (switcher) {
    if (switch_on() != SWITCH_ON) {
      set_bb_error("Could not enable discrete graphics card");
      return;
    }
    if (pci_config_restore(pci_bus_id_discrete, &pci_config_state_discrete)) {
      bb_log(LOG_WARNING, "Could not restore PCI configuration space: %s\n",
              strerror(errno));
    }
  }

  //if runmode is BB_RUN_EXIT, do not start X, we are shutting down.
  if (bb_status.runmode == BB_RUN_EXIT) {
    return;
  }

  if (pci_get_driver(driver, pci_bus_id_discrete, sizeof driver)) {
    /* if the loaded driver does not equal the driver from config, unload it */
    if (strcasecmp(bb_config.driver, driver)) {
      if (!module_unload(driver)) {
        /* driver failed to unload, aborting */
        return;
      }
    }
  }

  /* load the driver if none was loaded or if the loaded driver did not match
   * the configured one */
  if (strcasecmp(bb_config.driver, driver)) {
    char *module_name = bb_config.module_name;
    char *driver_name = bb_config.driver;
    if (!module_load(module_name, driver_name)) {
      set_bb_error("Could not load GPU driver");
      return;
    }
  }

  //no problems, start X if not started yet
  if (!bb_is_running(bb_status.x_pid)) {
    char pci_id[12];
    static char *x_conf_file;
    snprintf(pci_id, 12, "PCI:%02x:%02x:%o", pci_bus_id_discrete->bus,
            pci_bus_id_discrete->slot, pci_bus_id_discrete->func);
    if (!x_conf_file) {
      x_conf_file = xorg_path_w_driver(bb_config.x_conf_file, bb_config.driver);
    }

    bb_log(LOG_INFO, "Starting X server on display %s.\n", bb_config.x_display);
    char *x_argv[] = {
      XORG_BINARY,
      bb_config.x_display,
      "-config", x_conf_file,
      "-sharevts",
      "-nolisten", "tcp",
      "-noreset",
      "-verbose", "3",
      "-isolateDevice", pci_id,
      "-modulepath",
      bb_config.mod_path,
      NULL
    };
    if (!*bb_config.mod_path) {
      x_argv[12] = 0; //remove -modulepath if not set
    }
    //close any previous pipe, if it (still) exists
    if (bb_status.x_pipe[0] != -1){close(bb_status.x_pipe[0]); bb_status.x_pipe[0] = -1;}
    if (bb_status.x_pipe[1] != -1){close(bb_status.x_pipe[1]); bb_status.x_pipe[1] = -1;}
    //create a new pipe
    if (pipe2(bb_status.x_pipe, O_NONBLOCK)){
      set_bb_error("Could not create output pipe for X");
      return;
    }
    bb_status.x_pid = bb_run_fork_ld_redirect(x_argv, bb_config.ld_path, bb_status.x_pipe[1]);
    //close the end of the pipe that is not ours
    if (bb_status.x_pipe[1] != -1){close(bb_status.x_pipe[1]); bb_status.x_pipe[1] = -1;}
  }

  //check if X is available, for maximum 10 seconds.
  time_t xtimer = time(0);
  Display * xdisp = 0;
  while ((time(0) - xtimer <= 10) && bb_is_running(bb_status.x_pid)) {
    xdisp = XOpenDisplay(bb_config.x_display);
    if (xdisp != 0) {
      break;
    }
    check_xorg_pipe();//make sure Xorg errors come in smoothly
    usleep(100000); //don't retry too fast
  }
  check_xorg_pipe();//make sure Xorg errors come in smoothly

  //check if X is available
  if (xdisp == 0) {
    //X not available
    /// \todo Maybe check X exit status and/or messages?
    if (bb_is_running(bb_status.x_pid)) {
      //X active, but not accepting connections
      set_bb_error("X unresponsive after 10 seconds - aborting");
      bb_stop(bb_status.x_pid);
    } else {
      //X terminated itself
      set_bb_error("X did not start properly");
    }
  } else {
    //X accepted the connetion - we assume it works
    XCloseDisplay(xdisp); //close connection to X again
    bb_log(LOG_INFO, "X successfully started in %i seconds\n", time(0) - xtimer);
    //reset errors, if any
    set_bb_error(0);
  }
}//start_secondary