⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os2execd.c

📁 dos下执行OS/2程序
💻 C
字号:
/* os2execd.c */

/* Copyright (c) 1992-1993 by Eberhard Mattes */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <direct.h>
#include <process.h>
#define INCL_DOSMISC
#define INCL_DOSNMPIPES
#define INCL_DOSPROCESS
#define INCL_DOSQUEUES
#define INCL_WINWINDOWMGR
#define INCL_WINSWITCHLIST
#include <os2.h>

#define FALSE 0
#define TRUE  1

typedef unsigned char byte;

static byte buf[4096];
static CHAR args[4096+256];
static CHAR prog_buf[256];
static PCHAR org_env;
static PCHAR new_env;
static HPIPE hp;

static USHORT org_env_size;
static USHORT new_env_size;
static USHORT new_env_alloc;

static void send (byte cmd, byte *src, int len);
static void out_of_mem (void);
int main (int argc, char *argv[]);


static void out_of_mem (void)
{
  fprintf (stderr, "Out of memory\n");
  exit (2);
}


static void send (byte cmd, byte *src, int len)
{
  USHORT rc, cb;

  buf[0] = (byte)((len + 1) % 256);
  buf[1] = (byte)((len + 1) / 256);
  buf[2] = cmd;
  memmove (buf+3, src, len);
  rc = DosWrite (hp, buf, len+3, &cb);
  if (rc != 0)
    {
      fprintf (stderr, "DosWrite: rc=%hu\n", rc);
      exit (2);
    }
}


static void no_inherit (HFILE hf)
{
  USHORT state;

  if (DosQFHandState (hf, &state) == 0)
    DosSetFHandState (hf, state | OPEN_FLAGS_NOINHERIT);
}


int main (int argc, char *argv[])
{
  USHORT rc, cb;
  byte header[2], result[12], *p, *q;
  int sys_rc, drive, i, len, verbose, def_sw, cur_sw, quit, output;
  CHAR failname[256], *shell, *prog;
  RESULTCODES results;
  SEL env_sel;
  USHORT cmd_off;
  HWND hwndActive;
  HFILE saved_stdout, saved_stderr, pipe_read, pipe_write, hf;
  PID pid;

  puts ("os2execd -- Version 1.1a -- Copyright (c) 1992-1993 by Eberhard Mattes");
  verbose = FALSE; def_sw = FALSE; quit = FALSE;
  for (i = 1; i < argc; ++i)
    if (strcmp (argv[i], "-v") == 0)
      verbose = TRUE;
    else if (strcmp (argv[i], "-s") == 0)
      def_sw = TRUE;
    else
      {
        fprintf (stderr, "Usage: os2execd [-s] [-v]\n\n");
        fprintf (stderr, "  -s  Switch windows\n");
        fprintf (stderr, "  -v  Verbose\n");
        return (2);
      }
  shell = getenv ("COMSPEC");
  if (shell == NULL)
    shell = "cmd.exe";
  if (DosGetEnv (&env_sel, &cmd_off) != 0)
    {
      fprintf (stderr, "DosGetEnv failed\n");
      return (2);
    }
  org_env = MAKEP (env_sel, 0);
  org_env_size = 0;
  while (org_env[org_env_size++] != 0)
    while (org_env[org_env_size++] != 0)
      ;
  new_env_size = new_env_alloc = org_env_size;
  new_env = malloc (new_env_alloc);
  if (new_env == NULL) out_of_mem ();
  memmove (new_env, org_env, org_env_size);
  rc = DosMakeNmPipe ("/pipe/os2exec.em", &hp,
                      NP_ACCESS_DUPLEX | NP_NOINHERIT,
                      NP_WAIT | NP_READMODE_BYTE | NP_TYPE_BYTE
                      | NP_UNLIMITED_INSTANCES,
                      4096, 4096, 0L);
  if (rc != 0)
    {
      fprintf (stderr, "DosMakeNmPipe: rc=%hu\n", rc);
      return (2);
    }
new:
  rc = DosConnectNmPipe (hp);
  if (rc != 0)
    {
      fprintf (stderr, "DosConnectNmPipe: rc=%hu\n", rc);
      return (2);
    }
  if (verbose)
    fprintf (stderr, "--- Connected\n");
  cur_sw = def_sw; output = FALSE;
  for (;;)
    {
      rc = DosRead (hp, header, sizeof (header), &cb);
      if (rc != 0)
        {
          fprintf (stderr, "DosRead: rc=%hu\n", rc);
          return (2);
        }
      if (cb != 2)
        break;
      rc = DosRead (hp, buf, header[0] + 256 * header[1], &cb);
      if (rc != 0)
        {
          fprintf (stderr, "DosRead: rc=%hu\n", rc);
          return (2);
        }
      if (cb == 0)
        break;
      buf[cb] = 0;
      if (verbose)
        {
          fprintf (stderr, "--- Message: <");
          fwrite (buf, cb, 1, stderr);
          fprintf (stderr, ">\n");
        }
      switch (buf[0])
        {
        case 'A':       /* Return code acknowledgement */
          if (verbose)
            fprintf (stderr, "--- Return code acknowledged\n");
          goto done;

        case 'C':       /* Command: CMD.EXE */
        case 'X':       /* Command: DosExecPgm */
          if (verbose)
            fprintf (stderr, "--- Command: %s\n", buf+1);
          if (cur_sw)
            {
              hwndActive = WinQueryActiveWindow (HWND_DESKTOP, FALSE);
              WinSwitchToProgram (WinQuerySwitchHandle (0, getpid ()));
            }
          if (buf[0] == 'C')
            {
              prog = shell;
              p = args;
              strcpy (p, shell); p = strchr (p, 0) + 1;
              strcpy (p, "/c ");
              strcat (p, buf+1); p = strchr (p, 0) + 1;
              *p = 0;
            }
          else
            {
              q = buf + 1;
              while (*q == ' ' || *q == '\t')
                ++q;
              for (i = 0; i < sizeof (prog_buf) - 5; ++i)
                {
                  if (*q == 0 || *q == ' ' || *q == '\t')
                    break;
                  prog_buf[i] = *q;
                  ++q;
                }
              prog_buf[i] = 0;
              prog = prog_buf;
              p = args;
              strcpy (p, prog); p = strchr (p, 0) + 1;
              strcpy (p, q); p = strchr (p, 0) + 1;
              *p = 0;
              i = FALSE;
              for (q = prog_buf; *q != 0; ++q)
                if (*q == ':' || *q == '\\' || *q == ':')
                  i = FALSE;
                else if (*q == '.')
                  i = TRUE;
              if (!i)
                strcat (prog_buf, ".exe");
            }
          if (verbose)
            fprintf (stderr, "--- Program: %s\n", prog);
          if (output)
            {
              DosMakePipe (&pipe_read, &pipe_write, 4096);
              saved_stdout = saved_stderr = 0xffff;
              DosDupHandle (1, &saved_stdout);
              DosDupHandle (2, &saved_stderr);
              hf = 1;
              DosDupHandle (pipe_write, &hf);
              hf = 2;
              DosDupHandle (pipe_write, &hf);
              DosClose (pipe_write);
              no_inherit (pipe_read);
              no_inherit (saved_stdout);
              no_inherit (saved_stderr);

              rc = DosExecPgm (failname, sizeof (failname),
                               EXEC_ASYNCRESULT,
                               args, new_env, &results, prog);
              hf = 1;
              DosDupHandle (saved_stdout, &hf);
              hf = 2;
              DosDupHandle (saved_stderr, &hf);
              if (rc == 0)
                {
                  USHORT rc2, nread;

                  for (;;)
                    {
                      rc2 = DosRead (pipe_read, args, 256, &nread);
                      if (rc2 != 0) /* ERROR_BROKEN_PIPE */
                        break;
                      if (nread == 0)
                        break;
                      send ('O', args, nread);
                    }
                  DosCwait (DCWA_PROCESS, DCWW_WAIT, &results, &pid, 0);
                }
              DosClose (pipe_read);
            }
          else
            rc = DosExecPgm (failname, sizeof (failname),
                             EXEC_SYNC,
                             args, new_env, &results, prog);
          if (rc != 0)
            {
              fprintf (stderr, "--- DosExecPgm failed, rc=%hu\n", rc);
              sys_rc = -1;
            }
          else
            sys_rc = results.codeResult;
          if (cur_sw && hwndActive != NULL)
            WinSwitchToProgram (WinQuerySwitchHandle (hwndActive, 0));
          sprintf (result, "%d", sys_rc);
          send ('R', result, strlen (result));
          fputchar ('\n');
          memmove (new_env, org_env, org_env_size);
          new_env_size = org_env_size;
          output = FALSE;
          break;

        case 'E':
          p = strchr (buf+1, '=');
          if (p != NULL)
            {
              len = (p - (buf+1)) + 1;
              i = 0;
              while (new_env[i] != 0)
                if (memcmp (new_env+i, buf+1, len) == 0)
                  break;
                else
                  i += strlen (new_env+i) + 1;
              if (new_env[i] != 0)
                {
                  len = strlen (new_env+i) + 1;
                  memmove (new_env + i, new_env + i + len,
                           new_env_size - (i + len));
                  new_env_size -= len;
                }
              len = strlen (buf+1) + 1;
              if (new_env_size + len > new_env_alloc)
                {
                  new_env_alloc = new_env_size + len;
                  new_env = realloc (new_env, new_env_alloc);
                  if (new_env == NULL) out_of_mem ();
                }
              memmove (new_env + new_env_size - 1, buf + 1, len);
              new_env_size += len;
              new_env[new_env_size-1] = 0;
            }
          break;

        case 'Q':       /* Quit */
          if (verbose)
            fprintf (stderr, "--- Quit\n");
          send ('A', "", 0);
          quit = TRUE;
          goto done;

        case 'W':       /* Working directory */
          p = buf + 1;
          drive = toupper (p[0]);
          if (drive >= 'A' && drive <= 'Z' && p[1] == ':')
            {
              if (verbose)
                fprintf (stderr, "--- Change drive: %c\n", drive);
              _chdrive (drive - 'A' + 1);
              p += 2;
            }
          if (verbose)
            fprintf (stderr, "--- Change directory: %s\n", p);
          chdir (p);
          break;

        case 'S':       /* Switch windows */
          switch (buf[1])
            {
            case 'Y':
              cur_sw = TRUE;
              if (verbose)
                fprintf (stderr, "--- Switch windows: YES\n");
              break;
            case 'N':
              cur_sw = FALSE;
              if (verbose)
                fprintf (stderr, "--- Switch windows: NO\n");
              break;
            case 'D':
              cur_sw = def_sw;
              if (verbose)
                fprintf (stderr, "--- Switch windows: DEFAULT\n");
              break;
            default:
              if (verbose)
                fprintf (stderr, "--- Switch windows: ERROR\n");
              break;
            }
          break;

        case 'O':       /* Send output */
          output = TRUE;
          break;
        }
    }
done:
  if (verbose)
    fprintf (stderr, "--- Disconnect\n");
  rc = DosDisConnectNmPipe (hp);
  if (rc != 0)
    {
      fprintf (stderr, "DosDisConnectNmPipe: rc=%hu\n", rc);
      return (2);
    }
  if (!quit)
    goto new;
  
  rc = DosClose (hp);
  if (rc != 0)
    {
      fprintf (stderr, "DosClose: rc=%hu\n", rc);
      return (2);
    }
  return (0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -