コード例 #1
0
ファイル: mswindows.c プロジェクト: aljex/aljex-client
/* Determines if we are the child and if so performs the child logic.
   Return values:
     < 0  error
       0  parent
     > 0  child
*/
static int
fake_fork_child (void)
{
  HANDLE section, event;
  struct fake_fork_info *info;
  char *name;

  name = make_section_name (GetCurrentProcessId ());
  section = OpenFileMapping (FILE_MAP_WRITE, FALSE, name);
  xfree (name);
  /* It seems that Windows 9x and NT set last-error inconsistently when
     OpenFileMapping() fails; so we assume it failed because the section
     object does not exist.  */
  if (!section)
    return 0;                   /* We are the parent.  */

  info = MapViewOfFile (section, FILE_MAP_WRITE, 0, 0, 0);
  if (!info)
    {
      CloseHandle (section);
      return -1;
    }

  event = info->event;

  info->logfile_changed = false;
  if (!opt.lfilename)
    {
      /* See utils:fork_to_background for explanation. */
      FILE *new_log_fp = unique_create (DEFAULT_LOGFILE, false, &opt.lfilename);
      if (new_log_fp)
        {
          info->logfile_changed = true;
          strncpy (info->lfilename, opt.lfilename, sizeof (info->lfilename));
          info->lfilename[sizeof (info->lfilename) - 1] = '\0';
          fclose (new_log_fp);
        }
    }

  UnmapViewOfFile (info);
  CloseHandle (section);

  /* Inform the parent that we've done our part.  */
  if (!SetEvent (event))
    return -1;

  CloseHandle (event);
  return 1;                     /* We are the child.  */
}
コード例 #2
0
ファイル: userfile.cpp プロジェクト: EQ4/sequencer64
bool
userfile::parse (perform & /* a_perf */)
{
    std::ifstream file(m_name.c_str(), std::ios::in | std::ios::ate);
    if (! file.is_open())
    {
        fprintf(stderr, "? error opening [%s]\n", m_name.c_str());
        return false;
    }
    file.seekg(0, std::ios::beg);                       /* seek to start */
    line_after(file, "[user-midi-bus-definitions]");    /* find the tag  */
    int buses = 0;
    sscanf(m_line, "%d", &buses);                       /* atavistic!    */
    for (int bus = 0; bus < buses; ++bus)
    {
        std::string label = make_section_name("user-midi-bus", bus);
        line_after(file, label);
        if (g_user_settings.add_bus(m_line))
        {
            next_data_line(file);
            int instruments = 0;
            int instrument;
            int channel;
            sscanf(m_line, "%d", &instruments);
            for (int j = 0; j < instruments; j++)
            {
                next_data_line(file);
                sscanf(m_line, "%d %d", &channel, &instrument);
                g_user_settings.set_bus_instrument(bus, channel, instrument);
            }
        }
        else
        {
            fprintf
            (
                stderr, "? error adding %s (line = '%s')\n",
                label.c_str(), m_line
            );
        }
    }

    line_after(file, "[user-instrument-definitions]");
    int instruments = 0;
    sscanf(m_line, "%d", &instruments);
    for (int i = 0; i < instruments; i++)
    {
        std::string label = make_section_name("user-instrument", i);
        line_after(file, label);
        if (g_user_settings.add_instrument(m_line))
        {
            next_data_line(file);
            char ccname[SEQ64_LINE_MAX];
            int ccs = 0;
            sscanf(m_line, "%d", &ccs);
            for (int j = 0; j < ccs; j++)
            {
                int c = 0;
                next_data_line(file);

                // sscanf(m_line, "%d", &c);
                // sscanf(m_line, "%[^\n]", ccname);

                ccname[0] = 0;                              // clear the buffer
                sscanf(m_line, "%d %[^\n]", &c, ccname);
                if (c >= 0 && c < MIDI_CONTROLLER_MAX)      // 128
                {
                    g_user_settings.set_instrument_controllers
                    (
                        i, c, std::string(ccname), true
                    );
                }
                else
                {
                    fprintf
                    (
                        stderr, "? illegal controller value %d for '%s'\n",
                        c, label.c_str()
                    );
                }
            }
        }
        else
        {
            fprintf
            (
                stderr, "? error adding %s (line = '%s')\n",
                label.c_str(), m_line
            );
        }
    }

    /*
     * TODO: More (new) variables to follow!
     */

    g_user_settings.set_globals();
    dump_setting_summary();
    file.close();
    return true;
}
コード例 #3
0
ファイル: userfile.cpp プロジェクト: ahlstromcj/sequencer64
bool
userfile::parse (perform & /* a_perf */)
{
    std::ifstream file(m_name.c_str(), std::ios::in | std::ios::ate);
    if (! file.is_open())
    {
        fprintf(stderr, "? error opening [%s]\n", m_name.c_str());
        return false;
    }
    file.seekg(0, std::ios::beg);                       /* seek to start */

    /*
     * Header commentary is skipped during parsing.
     *
     * \change ca 2016-04-04
     *      Next, if we're using the manual or auto ALSA port options
     *      specified in the RC file, we do want to override the ports that
     *      the queries of the ALSA system find.  Otherwise, we might want to
     *      reveal the names obtained by port detection for ALSA, and do not
     *      want to override the names of the ports that are found.
     */

    if (! rc().reveal_alsa_ports())
    {
        /*
         * [user-midi-bus-definitions]
         */

        line_after(file, "[user-midi-bus-definitions]");    /* find the tag  */
        int buses = 0;
        sscanf(m_line, "%d", &buses);                       /* atavistic!    */

        /*
         * [user-midi-bus-x]
         */

        for (int bus = 0; bus < buses; ++bus)
        {
            std::string label = make_section_name("user-midi-bus", bus);
            line_after(file, label);
            if (usr().add_bus(m_line))
            {
                (void) next_data_line(file);
                int instruments = 0;
                int instrument;
                int channel;
                sscanf(m_line, "%d", &instruments);
                for (int j = 0; j < instruments; ++j)
                {
                    (void) next_data_line(file);
                    sscanf(m_line, "%d %d", &channel, &instrument);
                    usr().set_bus_instrument(bus, channel, instrument);
                }
            }
            else
            {
                fprintf
                (
                    stderr, "? error adding %s (line = '%s')\n",
                    label.c_str(), m_line
                );
            }
        }
    }

    /*
     * [user-instrument-definitions]
     */

    line_after(file, "[user-instrument-definitions]");
    int instruments = 0;
    sscanf(m_line, "%d", &instruments);

    /*
     * [user-instrument-x]
     */

    for (int i = 0; i < instruments; ++i)
    {
        std::string label = make_section_name("user-instrument", i);
        line_after(file, label);
        if (usr().add_instrument(m_line))
        {
            char ccname[SEQ64_LINE_MAX];
            int ccs = 0;
            (void) next_data_line(file);
            sscanf(m_line, "%d", &ccs);
            for (int j = 0; j < ccs; ++j)
            {
                int c = 0;
                (void) next_data_line(file);
                ccname[0] = 0;                              // clear the buffer
                sscanf(m_line, "%d %[^\n]", &c, ccname);
                if (c >= 0 && c < SEQ64_MIDI_CONTROLLER_MAX)      // 128
                {
                    usr().set_instrument_controllers
                    (
                        i, c, std::string(ccname), true
                    );
                }
                else
                {
                    fprintf
                    (
                        stderr, "? illegal controller value %d for '%s'\n",
                        c, label.c_str()
                    );
                }
            }
        }
        else
        {
            fprintf
            (
                stderr, "? error adding %s (line = '%s')\n",
                label.c_str(), m_line
            );
        }
    }

    /*
     * [user-interface-settings]
     *
     * These are new items stored in the user file.  Only variables whose
     * effects we can be completely sure of are read from this section, and
     * used, at this time.  More to come.
     */

    if (! rc().legacy_format())
    {
        int scratch = 0;
        line_after(file, "[user-interface-settings]");
        sscanf(m_line, "%d", &scratch);
        usr().grid_style(scratch);

        (void) next_data_line(file);
        sscanf(m_line, "%d", &scratch);
        usr().grid_brackets(scratch);

        (void) next_data_line(file);
        sscanf(m_line, "%d", &scratch);
        usr().mainwnd_rows(scratch);

        (void) next_data_line(file);
        sscanf(m_line, "%d", &scratch);
        usr().mainwnd_cols(scratch);

        (void) next_data_line(file);
        sscanf(m_line, "%d", &scratch);
        usr().max_sets(scratch);

        (void) next_data_line(file);
        sscanf(m_line, "%d", &scratch);
        usr().mainwid_border(scratch);

        (void) next_data_line(file);
        sscanf(m_line, "%d", &scratch);
        usr().mainwid_spacing(scratch);

        (void) next_data_line(file);
        sscanf(m_line, "%d", &scratch);
        usr().control_height(scratch);

        (void) next_data_line(file);
        sscanf(m_line, "%d", &scratch);
        usr().zoom(scratch);

        /*
         * This boolean affects the behavior of the scale, key, and background
         * sequence features, but their actual values are stored in the MIDI
         * file, not in the "user" configuration file.
         */

        (void) next_data_line(file);
        sscanf(m_line, "%d", &scratch);
        usr().global_seq_feature(scratch != 0);

        /*
         * The user-interface font is now selectable at run time.  Old versus
         * new font.
         */

        (void) next_data_line(file);
        sscanf(m_line, "%d", &scratch);
        usr().use_new_font(scratch != 0);

        (void) next_data_line(file);
        sscanf(m_line, "%d", &scratch);
        usr().allow_two_perfedits(scratch != 0);

        (void) next_data_line(file);
        sscanf(m_line, "%d", &scratch);
        usr().perf_h_page_increment(scratch);

        (void) next_data_line(file);
        sscanf(m_line, "%d", &scratch);
        usr().perf_v_page_increment(scratch);

        /*
         *  Here, we start checking the lines, on the theory that these
         *  very new (2016-02-14) items might mess up people who already have
         *  older Sequencer64 "user" configuration files.
         */

        if (next_data_line(file))
        {
            sscanf(m_line, "%d", &scratch);                 /* now an int   */
            usr().progress_bar_colored(scratch);            /* pick a color */
            if (next_data_line(file))
            {
                sscanf(m_line, "%d", &scratch);
                usr().progress_bar_thick(scratch != 0);
            }
            if (next_data_line(file))
            {
                sscanf(m_line, "%d", &scratch);
                if (scratch <= 1)                           /* boolean?     */
                {
                    usr().inverse_colors(scratch != 0);
                    if (next_data_line(file))
                        sscanf(m_line, "%d", &scratch);     /* get redraw   */
                }
                if (scratch < SEQ64_MINIMUM_REDRAW)
                    scratch = SEQ64_MINIMUM_REDRAW;
                else if (scratch > SEQ64_MAXIMUM_REDRAW)
                    scratch = SEQ64_MAXIMUM_REDRAW;

                usr().window_redraw_rate(scratch);
            }
            if (next_data_line(file))
            {
                sscanf(m_line, "%d", &scratch);
                if (scratch <= 1)                           /* boolean?     */
                    usr().use_more_icons(scratch != 0);
            }
        }
        usr().normalize();    /* calculate derived values */
    }
    else
    {
        /*
         * Legacy values.  Compare to user_settings::set_defaults().
         */

        usr().grid_style(0);
        usr().grid_brackets(1);
        usr().mainwnd_rows(4);
        usr().mainwnd_cols(8);
        usr().max_sets(32);
        usr().mainwid_border(0);
        usr().mainwid_spacing(2);
        usr().control_height(0);
        usr().zoom(SEQ64_DEFAULT_ZOOM);
        usr().global_seq_feature(false);
        usr().use_new_font(false);
        usr().allow_two_perfedits(false);
        usr().perf_h_page_increment(1);
        usr().perf_v_page_increment(1);
        usr().progress_bar_colored(0);
        usr().progress_bar_thick(false);
        usr().inverse_colors(false);
        usr().window_redraw_rate(c_redraw_ms);
    }

    /*
     * [user-midi-settings]
     */

    if (! rc().legacy_format())
    {
        line_after(file, "[user-midi-settings]");
        int scratch = 0;
        sscanf(m_line, "%d", &scratch);
        usr().midi_ppqn(scratch);

        next_data_line(file);
        sscanf(m_line, "%d", &scratch);
        usr().midi_beats_per_bar(scratch);

        next_data_line(file);
        sscanf(m_line, "%d", &scratch);
        usr().midi_beats_per_minute(scratch);

        next_data_line(file);
        sscanf(m_line, "%d", &scratch);
        usr().midi_beat_width(scratch);

        next_data_line(file);
        sscanf(m_line, "%d", &scratch);
        usr().midi_buss_override(char(scratch));
    }

    /*
     * We have all of the data.  Close the file.
     */

    dump_setting_summary();
    file.close();                       /* End Of File, EOF, done! */
    return true;
}
コード例 #4
0
ファイル: mswindows.c プロジェクト: aljex/aljex-client
/* Windows doesn't support the fork() call; so we fake it by invoking
   another copy of Wget with the same arguments with which we were
   invoked.  The child copy of Wget should perform the same initialization
   sequence as the parent; so we should have two processes that are
   essentially identical.  We create a specially named section object that
   allows the child to distinguish itself from the parent and is used to
   exchange information between the two processes.  We use an event object
   for synchronization.  */
static void
fake_fork (void)
{
  char exe[MAX_PATH + 1];
  DWORD exe_len, le;
  SECURITY_ATTRIBUTES sa;
  HANDLE section, event, h[2];
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  struct fake_fork_info *info;
  char *name;
  BOOL rv;

  section = pi.hProcess = pi.hThread = NULL;

  /* Get the fully qualified name of our executable.  This is more reliable
     than using argv[0].  */
  exe_len = GetModuleFileName (GetModuleHandle (NULL), exe, sizeof (exe));
  if (!exe_len || (exe_len >= sizeof (exe)))
    return;

  sa.nLength = sizeof (sa);
  sa.lpSecurityDescriptor = NULL;
  sa.bInheritHandle = TRUE;

  /* Create an anonymous inheritable event object that starts out
     non-signaled.  */
  event = CreateEvent (&sa, FALSE, FALSE, NULL);
  if (!event)
    return;

  /* Create the child process detached form the current console and in a
     suspended state.  */
  xzero (si);
  si.cb = sizeof (si);
  rv = CreateProcess (exe, GetCommandLine (), NULL, NULL, TRUE,
                      CREATE_SUSPENDED | DETACHED_PROCESS,
                      NULL, NULL, &si, &pi);
  if (!rv)
    goto cleanup;

  /* Create a named section object with a name based on the process id of
     the child.  */
  name = make_section_name (pi.dwProcessId);
  section =
      CreateFileMapping (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
                         sizeof (struct fake_fork_info), name);
  le = GetLastError();
  xfree (name);
  /* Fail if the section object already exists (should not happen).  */
  if (!section || (le == ERROR_ALREADY_EXISTS))
    {
      rv = FALSE;
      goto cleanup;
    }

  /* Copy the event handle into the section object.  */
  info = MapViewOfFile (section, FILE_MAP_WRITE, 0, 0, 0);
  if (!info)
    {
      rv = FALSE;
      goto cleanup;
    }

  info->event = event;

  UnmapViewOfFile (info);

  /* Start the child process.  */
  rv = ResumeThread (pi.hThread);
  if (!rv)
    {
      TerminateProcess (pi.hProcess, (DWORD) -1);
      goto cleanup;
    }

  /* Wait for the child to signal to us that it has done its part.  If it
     terminates before signaling us it's an error.  */

  h[0] = event;
  h[1] = pi.hProcess;
  rv = WAIT_OBJECT_0 == WaitForMultipleObjects (2, h, FALSE, 5 * 60 * 1000);
  if (!rv)
    goto cleanup;

  info = MapViewOfFile (section, FILE_MAP_READ, 0, 0, 0);
  if (!info)
    {
      rv = FALSE;
      goto cleanup;
    }

  /* Ensure string is properly terminated.  */
  if (info->logfile_changed &&
      !memchr (info->lfilename, '\0', sizeof (info->lfilename)))
    {
      rv = FALSE;
      goto cleanup;
    }

  printf (_("Continuing in background, pid %lu.\n"), pi.dwProcessId);
  if (info->logfile_changed)
    printf (_("Output will be written to `%s'.\n"), info->lfilename);

  UnmapViewOfFile (info);

cleanup:

  if (event)
    CloseHandle (event);
  if (section)
    CloseHandle (section);
  if (pi.hThread)
    CloseHandle (pi.hThread);
  if (pi.hProcess)
    CloseHandle (pi.hProcess);

  /* We're the parent.  If all is well, terminate.  */
  if (rv)
    exit (0);

  /* We failed, return.  */
}