void NextBarDlg::install2Dialog(PSZ FileName, BOOL bObject)
{
 CHAR    Buffer[260];
 PSZ     pszTemp;
 BOOL    Batch=FALSE;
 ULONG   AppType;

 Icon.setText("");
 Parms.setText("");

 if(bObject) {
   event->session = SSF_TYPE_WPSOBJECT;
   WinSetDlgItemText(hwnd, NHX_TITLE, FileName);
   WinSetDlgItemText(hwnd, NHX_PROG, FileName); }
 else {
   DosQueryAppType(FileName, &AppType);
   event->session = SSF_TYPE_DEFAULT;
   if ((AppType & 0x7) == FAPPTYP_WINDOWAPI)
      event->session = SSF_TYPE_PM;
   else if ((AppType & 0x7) == FAPPTYP_WINDOWCOMPAT)
      event->session = SSF_TYPE_WINDOWABLEVIO;
   else if (AppType & FAPPTYP_DOS)
      event->session = SSF_TYPE_WINDOWEDVDM;
   else if (AppType & FAPPTYP_WINDOWSREAL)
      event->session = PROG_WINDOW_REAL;
   else if (AppType & FAPPTYP_WINDOWSPROT)
      event->session = PROG_WINDOW_PROT;
   else if (AppType & FAPPTYP_WINDOWSPROT31)
      event->session = PROG_31_ENH; }

 if(!bObject) {
   if(strstr(FileName, ".CMD")) {
     Batch = TRUE;
     event->session = SSF_TYPE_WINDOWABLEVIO;
     if(strchr(FileName, ' ')) {
       strcpy(Buffer, "/c \"\"");
       strcat(Buffer, FileName);
       strcat(Buffer, "\"\""); }
     else {
       strcpy(Buffer, "/c ");
       strcat(Buffer, FileName); }}
   else if(strstr(FileName, ".BAT")) {
     Batch = TRUE;
     event->session = SSF_TYPE_WINDOWEDVDM;
     strcpy(Buffer, "/c ");
     strcat(Buffer, FileName); }
   if (Batch) {
     WinSetDlgItemText(hwnd, NHX_PARMS, Buffer);
     WinSetDlgItemText(hwnd, NHX_PROG, ""); }
   else
     WinSetDlgItemText(hwnd, NHX_PROG, FileName);
   strcpy(Buffer, FileName);
   pszTemp = FileName+strlen(FileName);
   for( ; (*pszTemp!='\\') && (pszTemp>=FileName); pszTemp--);
   WinSetDlgItemText(hwnd, NHX_TITLE, (pszTemp+1));
   *pszTemp='\0';
   WinSetDlgItemText(hwnd, NHX_WORKDIR, FileName); }

 setButtons();
}
Exemplo n.º 2
0
static string
app_type (string prog, int *app)
{
#ifdef OS2
  int res, app;

  res = DosSearchPath (0x02 | 0x01, "PATH", prog, buf, len);
  if (res != 0)
    return -1;

  res = DosQueryAppType (buf, &app);
  if (res != 0)
    return -1;

  switch (app & 0x07)			/* Quick guess. */
    {
    case 0x00: return (P_SESSION | P_DEFAULT);
    case 0x01: return (P_SESSION | P_FULLSCREEN);
    case 0x02: return (P_SESSION | P_WINDOWED);
    case 0x03: return (P_PM);
    }
#endif /* OS2 */

  *app = 0; /* Irrelevant.  */
  return prog;
}
Exemplo n.º 3
0
ULONG ulExecProg (CHAR *szProgName)
   {
   ULONG        ulBootDrive;
   ULONG        ulAppType;
   CHAR         szCmdName[CCHMAXPATH];
   CHAR         szLine[CCHMAXPATH];
   PSZ          pszScanEnv;
   RESULTCODES  rcTermination;
   APIRET       rcFailure = 0;
   PCHAR        pszEnvironment;

/*
 *  Diese Routine versucht eine Shell zu starten.
 */

   pszEnvironment = MakeEnv (pShareInitOS2->pszEnvironment);

   if ( !(rcFailure = ScanEnv(ENV_SAMWORKPLACE, &pszScanEnv, pszEnvironment)) )
      {
      rcFailure = DosQueryAppType(pszScanEnv, &ulAppType);

      if ( !rcFailure )
         if ( ( (ulAppType & 7) == FAPPTYP_NOTSPEC) ||
              ( (ulAppType & 7) == FAPPTYP_WINDOWAPI) )
            rcFailure = DosExecPgm (szLine,           /* Object name buffer */
                                 sizeof(szLine),      /* Length of object name buffer */
                                 EXEC_ASYNCRESULT,    /* Execution flags */
                                 "",                  /* Argument string */
                                 pszEnvironment,       /* Environment */
                                 &rcTermination,      /* Termination codes */
                                 pszScanEnv);         /* Program file name */
         else
            rcFailure = 1;
      }

   if (rcFailure)
      {
      WinAlarm (HWND_DESKTOP, WA_ERROR);
      DebugS (1, "DosExecPgm <1> failed");
      }

   if (rcFailure)
      {
      rcFailure = DosExecPgm (szLine,              /* Object name buffer */
                              sizeof(szLine),      /* Length of object name buffer */
                              EXEC_ASYNCRESULT,    /* Execution flags */
                              "",                  /* Argument string */
                              pszEnvironment,       /* Environment */
                              &rcTermination,      /* Termination codes */
                              szProgName);         /* Program file name */
      }

   if (rcFailure)
      {
      if (!(rcFailure = DosScanEnv (ENV_SAMWORKPLACE, &pszScanEnv)))
         rcFailure = DosExecPgm (szLine,        /* Object name buffer */
                           sizeof(szLine),      /* Length of object name buffer */
                           EXEC_ASYNCRESULT,    /* Execution flags */
                           "",                  /* Argument string */
                           pszEnvironment,       /* Environment */
                           &rcTermination,      /* Termination codes */
                           pszScanEnv);         /* Program file name */
      }

   if (rcFailure)
      {
      DebugS (1, "DosExecPgm <2> failed");
      DosQuerySysInfo (QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &ulBootDrive, sizeof (ULONG));

      memset (szCmdName, '\0', sizeof(szCmdName));
      szCmdName[0] = (CHAR) (ulBootDrive - 1) + 'A';
      strcpy (szCmdName+1, ":\\OS2\\PMSHELL.EXE");

      rcFailure = DosExecPgm (szLine,           /* Object name buffer */
                           sizeof(szLine),      /* Length of object name buffer */
                           EXEC_ASYNCRESULT,    /* Execution flags */
                           "",                  /* Argument string */
                           pszEnvironment,       /* Environment */
                           &rcTermination,      /* Termination codes */
                           szCmdName);          /* Program file name */
      }

/* Falls Shell nicht gestartet werden konnte, wird cmd.exe aufgerufen */

   if (rcFailure)
      {
      DebugS (1, "DosExecPgm <3> failed");
      if (!(rcFailure = DosScanEnv ("COMSPEC", &pszScanEnv)))
         rcFailure = DosExecPgm (szLine,        /* Object name buffer */
                           sizeof(szLine),      /* Length of object name buffer */
                           EXEC_ASYNCRESULT,    /* Execution flags */
                           "/K",                /* Argument string */
                           pszEnvironment,       /* Environment */
                           &rcTermination,      /* Termination codes */
                           pszScanEnv);         /* Program file name */
      }

   if (rcFailure)
      {
      DebugS (1, "DosExecPgm <4> failed");
      DosQuerySysInfo (QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &ulBootDrive, sizeof (ULONG));

      memset (szCmdName, '\0', sizeof(szCmdName));
      szCmdName[0] = (CHAR) (ulBootDrive - 1) + 'A';
      strcpy (szCmdName+1, ":\\OS2\\CMD.EXE");

      rcFailure = DosExecPgm (szLine,        /* Object name buffer */
                        sizeof(szLine),      /* Length of object name buffer */
                        EXEC_ASYNCRESULT,    /* Execution flags */
                        "/K",                /* Argument string */
                        pszEnvironment,       /* Environment */
                        &rcTermination,      /* Termination codes */
                        szCmdName);          /* Program file name */
      }

   DosFreeMem(pszEnvironment);

   if (rcFailure)
      {
      intSammyRetCode = rcFailure;
      WinPostQueueMsg (hmq, WM_CLOSE, 0L, 0L);
      DebugS (1, "DosExecPgm <5> failed");
      }

   return (rcFailure ? 0 : rcTermination.codeTerminate);
   }
static int 
os2_system (int as_shell_command, const char *shell, const char *command, char *parm)
{
   register int i, j;
   ULONG        AppType = 0;                    /* Application type flags (returned) */
   APIRET       rc = NO_ERROR;                  /* Return Code */
   char         pathValue[5] = "PATH";          /* For DosSearchPath */
   UCHAR        searchResult[MC_MAXPATHLEN * 2 + 1];     /* For DosSearchPath */
   
   char         *cmdString;
   char         *postFix[3];
   char         *line;
   /* ------------------------------------------------------- */
   STARTDATA    StartData;
   CHAR         ObjBuf[100];
   ULONG        SessionID;
   PID          pid;

   if (command == NULL) {
      /* .ado: just start a shell, we don't need the parameter */
      spawnl (P_WAIT, 
              (char *) shell, 
              (char *) shell, 
              (char *) command, (char *) 0);  
      return 0;
   }

   memset(&StartData, 0, sizeof(StartData)) ;
   StartData.Length             = sizeof(StartData);    
   StartData.Related            = SSF_RELATED_CHILD;
   StartData.FgBg               = SSF_FGBG_BACK;
   StartData.TraceOpt           = SSF_TRACEOPT_NONE;   
   StartData.PgmTitle           = NULL;                
   StartData.TermQ              = NULL;                 
   StartData.InheritOpt         = SSF_INHERTOPT_PARENT;
   StartData.IconFile           = 0;              
   StartData.PgmHandle          = 0;             
   StartData.PgmControl         = SSF_CONTROL_VISIBLE ; 
   StartData.ObjectBuffer       = ObjBuf;          
   StartData.ObjectBuffLen      = 100;            
   StartData.PgmInputs          = parm;

   postFix[0] = ".exe";
   postFix[1] = ".cmd";
   postFix[2] = ".bat";

   i = strlen(command);
   if (command[i-1] == ' ') {
      /* The user has used ALT-RETURN */
      i--;
   }
   cmdString = (char *) malloc(i+1);
   for (j=0; j<i; j++) {
      cmdString[j] = command[j];
   }
   cmdString[j] = (char) 0;

   if ((i < 5) || ((i > 4) && (cmdString[i-4]) != '.')) {
      /* without Extension */
      line = (char *) malloc(i+5);
      rc = 1;
      for (i=0; (i<3 && rc); i++) {
         /* Search for the file */
         strcpy(line, cmdString);
         strcat(line, postFix[i]);
         rc = DosSearchPath((SEARCH_IGNORENETERRS | SEARCH_ENVIRONMENT | SEARCH_CUR_DIRECTORY),
                            (PSZ) pathValue,
                            line,
                            searchResult,
                            sizeof(searchResult));
      }
      free (line);
   } else {         
      /* Just search */
      rc = DosSearchPath((SEARCH_IGNORENETERRS | SEARCH_ENVIRONMENT | SEARCH_CUR_DIRECTORY),
                         (PSZ) pathValue,
                         cmdString,
                         searchResult,
                         sizeof(searchResult));
   }
   free(cmdString);
   if (rc != 0) {
      /* Internal command or the program was written with absolut path */
      return ux_startp(shell, command, parm);
   }

   /* Application to be started */
   StartData.PgmName            = searchResult;
   StartData.Environment        = NULL;
   rc = DosQueryAppType(searchResult, &AppType);
   if (rc == NO_ERROR) {
      StartData.SessionType = PROG_WINDOWABLEVIO;
      if ((AppType & 0x00000007) == FAPPTYP_WINDOWAPI) {
         /* Window API */
         StartData.SessionType = PROG_PM;
         return DosStartSession(&StartData, &SessionID, &pid);
      }
      if ((AppType & 0x00000007) == FAPPTYP_WINDOWCOMPAT) {
         /* Window compat */
         return ux_startp(shell, command, parm);
      }
      if (AppType & 0x0000ffff & FAPPTYP_DOS) {
         /* PC/DOS Format */
        StartData.SessionType = PROG_WINDOWEDVDM;
        return DosStartSession(&StartData, &SessionID, &pid);
      }
      if (AppType & 0x0000ffff & FAPPTYP_WINDOWSREAL) {
         /* Windows real mode app */
        return StartWindowsProg(searchResult, 0);
      }
      if (AppType & 0x0000ffff & FAPPTYP_WINDOWSPROT) {
         /* Windows Protect mode app*/
        return StartWindowsProg(searchResult, 1);
      }
      if (AppType & 0x0000ffff & FAPPTYP_WINDOWSPROT31) {
         /* Windows 3.1 Protect mode app*/
        return StartWindowsProg(searchResult, 2);
      }
      rc = DosStartSession(&StartData, &SessionID, &pid) ;
   } else {
      /* It's not a known exe type or it's a CMD/BAT file */
      i = strlen(searchResult);
      if ((toupper(searchResult[--i]) == 'T') && 
          (toupper(searchResult[--i]) == 'A') &&  
          (toupper(searchResult[--i]) == 'B') &&  
          (searchResult[--i] == '.')   ) {
        StartData.SessionType = PROG_WINDOWEDVDM;
        rc = DosStartSession(&StartData, &SessionID, &pid) ;
      } else {
         rc = ux_startp (shell, command, parm);
      }
   }
   return rc;
}
Exemplo n.º 5
0
// *******************************************************************************
// FUNCTION:     StartApplication
//
// FUNCTION USE: This function is used to start the program
//
// DESCRIPTION:  This function is used to kick off the programs represented
//               by the buttons.  This routine will populate a PROGDETAILS
//               structure and call WinStartApp to start the program.
//
// PARAMETERS:   PCH     The program path and filename to be started
//               PCH     The command line parameters to be passed
//               PCH     The program title
//
// RETURNS:      HAPP
//
// INTERNALS:    NONE
//
// HISTORY:
//
// *******************************************************************************
HAPP StartApplication(PCH szPgmName, PCH szComLine, PCH szProgTitle, ULONG ulPgmType)
{
 APIRET        rc;
 HWND          hwndNotify;
 CHAR          szDir[CCHMAXPATH];
 CHAR          szFile[CCHMAXPATH];
 ULONG         ulAppType;
 HAPP          happ;
 CHAR          szBuffer[250];
 PROGDETAILS   progdetails;


 // Take the full program path and filename
 // and parse it so that the string X:\DIRECTORY\FILE.TXT
 // becomes two strings X:\DIRECTORY and FILE.TXT
 ParsePathFromFileName(szPgmName, szDir, szFile);

 if (ulPgmType != 0)
  {
   ulAppType = ulPgmType;
  }

 else
  {
   // NOTE: Determine the application default type
   //       if the application is a Windows based
   //       application change the default Win session
   //       to be Enhanced Seamless as oppossed to a
   //       yucky WinOS/2 Fullscreen session, since
   //       seamless is groovy!
   rc = DosQueryAppType(szPgmName, &ulAppType);

   if ((ulAppType == FAPPTYP_WINDOWSREAL) ||
       (ulAppType == FAPPTYP_WINDOWSPROT) ||
       (ulAppType == FAPPTYP_WINDOWSPROT31))
    {
     ulAppType  = PROG_31_ENHSEAMLESSVDM;
    }
  }

 progdetails.Length                      = sizeof(PROGDETAILS);  // Length of structure
 progdetails.progt.progc                 = ulAppType;            // Application Program Type
 progdetails.progt.fbVisible             = SHE_VISIBLE;          // Visibility Indicator
 progdetails.pszTitle                    = szProgTitle;          // Program Title
 progdetails.pszExecutable               = szPgmName;            // Executable Path and Filename
 progdetails.pszParameters               = szComLine;            // Command Line Parameters
 progdetails.pszStartupDir               = szDir;                // Working Directory
 progdetails.pszIcon                     = NULL;                 // Program Icon
 progdetails.pszEnvironment              = NULL;                 // Environment String
 progdetails.swpInitial.x                = 0;                    // Initial x Window Position
 progdetails.swpInitial.y                = 0;                    // Initial y Window Position
 progdetails.swpInitial.cx               = 0;                    // Initial cx Window Size
 progdetails.swpInitial.cy               = 0;                    // Initial cy Window Size
 progdetails.swpInitial.hwndInsertBehind = HWND_TOP;             // Window Placement
 progdetails.swpInitial.fl               = SWP_SHOW;             // Initial Window Flags

 happ = WinStartApp(NULLHANDLE,              // Notification window handle
                    &progdetails,            // Program Details Structure
                    NULL,                    // Command Line Parameters for the started application
                    NULL,                    // Reserved
                    SAF_INSTALLEDCMDLINE);   // Start Application Flags

 return happ;
}
Exemplo n.º 6
0
PRProcess * _PR_CreateOS2Process(
    const char *path,
    char *const *argv,
    char *const *envp,
    const PRProcessAttr *attr)
{
    PRProcess *proc = NULL;
    char *cmdLine = NULL;
    char **newEnvp = NULL;
    char *envBlock = NULL;
   
    STARTDATA startData = {0};
    APIRET    rc;
    ULONG     ulAppType = 0;
    PID       pid = 0;
    char     *pszComSpec;
    char      pszEXEName[CCHMAXPATH] = "";
    char      pszFormatString[CCHMAXPATH];
    char      pszObjectBuffer[CCHMAXPATH];
    char     *pszFormatResult = NULL;

    /*
     * Variables for DosExecPgm
     */
    char szFailed[CCHMAXPATH];
    char *pszCmdLine = NULL;
    RESULTCODES procInfo;
    HFILE hStdIn  = 0,
          hStdOut = 0,
          hStdErr = 0;
    HFILE hStdInSave  = -1,
          hStdOutSave = -1,
          hStdErrSave = -1;

    proc = PR_NEW(PRProcess);
    if (!proc) {
        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
        goto errorExit;
    }
   
    if (assembleCmdLine(argv, &cmdLine) == -1) {
        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
        goto errorExit;
    }

#ifdef MOZ_OS2_HIGH_MEMORY
    /*
     * DosQueryAppType() fails if path (the char* in the first argument) is in
     * high memory. If that is the case, the following moves it to low memory.
     */ 
    if ((ULONG)path >= 0x20000000) {
        size_t len = strlen(path) + 1;
        char *copy = (char *)alloca(len);
        memcpy(copy, path, len);
        path = copy;
    }
#endif
   
    if (envp == NULL) {
        newEnvp = NULL;
    } else {
        int i;
        int numEnv = 0;
        while (envp[numEnv]) {
            numEnv++;
        }
        newEnvp = (char **) PR_MALLOC((numEnv+1) * sizeof(char *));
        for (i = 0; i <= numEnv; i++) {
            newEnvp[i] = envp[i];
        }
        qsort((void *) newEnvp, (size_t) numEnv, sizeof(char *), compare);
    }
    if (assembleEnvBlock(newEnvp, &envBlock) == -1) {
        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
        goto errorExit;
    }
  
    rc = DosQueryAppType(path, &ulAppType);
    if (rc != NO_ERROR) {
       char *pszDot = strrchr(path, '.');
       if (pszDot) {
          /* If it is a CMD file, launch the users command processor */
          if (!stricmp(pszDot, ".cmd")) {
             rc = DosScanEnv("COMSPEC", (PSZ *)&pszComSpec);
             if (!rc) {
                strcpy(pszFormatString, "/C %s %s");
                strcpy(pszEXEName, pszComSpec);
                ulAppType = FAPPTYP_WINDOWCOMPAT;
             }
          }
       }
    }
    if (ulAppType == 0) {
       PR_SetError(PR_UNKNOWN_ERROR, 0);
       goto errorExit;
    }
 
    if ((ulAppType & FAPPTYP_WINDOWAPI) == FAPPTYP_WINDOWAPI) {
        startData.SessionType = SSF_TYPE_PM;
    }
    else if (ulAppType & FAPPTYP_WINDOWCOMPAT) {
        startData.SessionType = SSF_TYPE_WINDOWABLEVIO;
    }
    else {
        startData.SessionType = SSF_TYPE_DEFAULT;
    }
 
    if (ulAppType & (FAPPTYP_WINDOWSPROT31 | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSREAL))
    {
        strcpy(pszEXEName, "WINOS2.COM");
        startData.SessionType = PROG_31_STDSEAMLESSVDM;
        strcpy(pszFormatString, "/3 %s %s");
    }
 
    startData.InheritOpt = SSF_INHERTOPT_SHELL;
 
    if (pszEXEName[0]) {
        pszFormatResult = PR_MALLOC(strlen(pszFormatString)+strlen(path)+strlen(cmdLine));
        sprintf(pszFormatResult, pszFormatString, path, cmdLine);
        startData.PgmInputs = pszFormatResult;
    } else {
        strcpy(pszEXEName, path);
        startData.PgmInputs = cmdLine;
    }
    startData.PgmName = pszEXEName;
 
    startData.Length = sizeof(startData);
    startData.Related = SSF_RELATED_INDEPENDENT;
    startData.ObjectBuffer = pszObjectBuffer;
    startData.ObjectBuffLen = CCHMAXPATH;
    startData.Environment = envBlock;
 
    if (attr) {
        /* On OS/2, there is really no way to pass file handles for stdin,
         * stdout, and stderr to a new process.  Instead, we can make it
         * a child process and make the given file handles a copy of our
         * stdin, stdout, and stderr.  The child process then inherits
         * ours, and we set ours back.  Twisted and gross I know. If you
         * know a better way, please use it.
         */
        if (attr->stdinFd) {
            hStdIn = 0;
            DosDupHandle(hStdIn, &hStdInSave);
            DosDupHandle((HFILE) attr->stdinFd->secret->md.osfd, &hStdIn);
        }

        if (attr->stdoutFd) {
            hStdOut = 1;
            DosDupHandle(hStdOut, &hStdOutSave);
            DosDupHandle((HFILE) attr->stdoutFd->secret->md.osfd, &hStdOut);
        }

        if (attr->stderrFd) {
            hStdErr = 2;
            DosDupHandle(hStdErr, &hStdErrSave);
            DosDupHandle((HFILE) attr->stderrFd->secret->md.osfd, &hStdErr);
        }
        /*
         * Build up the Command Line for DosExecPgm
         */
        pszCmdLine = PR_MALLOC(strlen(pszEXEName) +
                               strlen(startData.PgmInputs) + 3);
        sprintf(pszCmdLine, "%s%c%s%c", pszEXEName, '\0',
                startData.PgmInputs, '\0');
        rc = DosExecPgm(szFailed,
                        CCHMAXPATH,
                        EXEC_ASYNCRESULT,
                        pszCmdLine,
                        envBlock,
                        &procInfo,
                        pszEXEName);
        PR_DELETE(pszCmdLine);

        /* Restore our old values.  Hope this works */
        if (hStdInSave != -1) {
            DosDupHandle(hStdInSave, &hStdIn);
            DosClose(hStdInSave);
        }

        if (hStdOutSave != -1) {
            DosDupHandle(hStdOutSave, &hStdOut);
            DosClose(hStdOutSave);
        }

        if (hStdErrSave != -1) {
            DosDupHandle(hStdErrSave, &hStdErr);
            DosClose(hStdErrSave);
        }

        if (rc != NO_ERROR) {
            /* XXX what error code? */
            PR_SetError(PR_UNKNOWN_ERROR, rc);
            goto errorExit;
        }

        proc->md.pid = procInfo.codeTerminate;
    } else {	
        /*
         * If no STDIN/STDOUT redirection is not needed, use DosStartSession
         * to create a new, independent session
         */
        rc = DosStartSession(&startData, &ulAppType, &pid);

        if ((rc != NO_ERROR) && (rc != ERROR_SMG_START_IN_BACKGROUND)) {
            PR_SetError(PR_UNKNOWN_ERROR, rc);
            goto errorExit;
        }
 
        proc->md.pid = pid;
    }

    if (pszFormatResult) {
        PR_DELETE(pszFormatResult);
    }

    PR_DELETE(cmdLine);
    if (newEnvp) {
        PR_DELETE(newEnvp);
    }
    if (envBlock) {
        PR_DELETE(envBlock);
    }
    return proc;

errorExit:
    if (cmdLine) {
        PR_DELETE(cmdLine);
    }
    if (newEnvp) {
        PR_DELETE(newEnvp);
    }
    if (envBlock) {
        PR_DELETE(envBlock);
    }
    if (proc) {
        PR_DELETE(proc);
    }
    return NULL;
}  /* _PR_CreateOS2Process */
Exemplo n.º 7
0
int spawnve(int mode, const char *name, char * const argv[],
            char * const envp[])
{
  int i, j, l, n, prefix_len = 0;
  char *ext, *tmp, *arg1, *execname, *p_arg, *p_env, *prefix = NULL;
  char runtype, freeexec = 0, hswValid = 0, quoteargs = 1;
  ULONG appflags;
  const char * const *p;
  unsigned int runflags = 0;
  int retcode = -1;
  char errbuf[MAXNAMLEN + 1], queue[MAXNAMLEN + 1];
  SWCNTRL swc;
  HSWITCH vioHSW;

  errno = ENOENT;

  /* EMX crashes on very long filenames... */
  if (strlen (name) > MAXNAMLEN - 4)
  {
   errno = ENAMETOOLONG;
   return -1;
  }

  /* Find extension ordinal in exec_ext array */
  ext = _getext2(name);
  for (i = 0; i < EXEC_EXT_COUNT; i++)
  {
   if (strcmp(ext, exec_ext[i]) == 0)
    goto found;
  }
  if (access(name, F_OK) == 0)
   errno = ENOEXEC;
  return -1;

found:
 {
  PTIB tb;
  PPIB pb;

  /* Determine our session type */
  if ((DosGetInfoBlocks(&tb, &pb) == NO_ERROR) &&
      (vioHSW = WinQuerySwitchHandle(NULLHANDLE, pb->pib_ulpid)) &&
      (WinQuerySwitchEntry(vioHSW, &swc) == NO_ERROR))
   hswValid = 1;
 }

 switch (mode & 0xFF)
 {
  case P_WAIT:
   runflags |= spawn_WAIT; break;
  case P_PM:
   runflags |= spawn_SESSION | spawn_TYPE_PM; break;
  case P_OVERLAY:
   runflags |= spawn_WAIT | spawn_OVERLAY; break;
  case P_DETACH:
   runflags |= spawn_DETACH; break;
 }

 if (((runtype = exec_run[i]) == 0) &&
     (DosQueryAppType((PSZ)name, &appflags) == NO_ERROR) &&
     ((runflags & spawn_DETACH) == 0) &&
     (hswValid))
 {
  /* Compare to application type */
  switch (appflags & 7)
  {
   case FAPPTYP_NOTSPEC:  /* Methinks its a DOS proggy */
   {
    if (appflags & FAPPTYP_DOS)
     if (swc.bProgType == PROG_FULLSCREEN)
      runflags |= (spawn_SESSION | spawn_TYPE_VDM);
     else
      runflags |= (spawn_SESSION | spawn_TYPE_WINDOWEDVDM);
    else
     runflags |= (spawn_SESSION | spawn_TYPE_DEFAULT);
    break;
   }
   case FAPPTYP_NOTWINDOWCOMPAT:
   {
    if (swc.bProgType != PROG_FULLSCREEN)
     runflags |= (spawn_SESSION | spawn_TYPE_FULLSCREEN);
    break;
   }
   case FAPPTYP_WINDOWCOMPAT:
   {
    /* That'll do it */
    break;
   }
   case FAPPTYP_WINDOWAPI:
   {
    runflags |= (spawn_SESSION | spawn_TYPE_PM);
    break;
   }
   default:
   {
    runtype = 1; /* Let $COMSPEC decide what to do */
    break;
   }
  }
 }

fallback:
 switch (runtype)
 {
  case 0:
directrun:
   if ((runflags & spawn_SESSION) &&
       (((runflags & spawn_TYPE) == spawn_TYPE_VDM) ||
        ((runflags & spawn_TYPE) == spawn_TYPE_WINDOWEDVDM)))
   {
    /* DOS command interpreter does not understand '/'s */
    execname = savestring((char *)name);
    freeexec = 1;
    for (tmp = execname; *tmp; tmp++)
     if (*tmp == '/') *tmp = '\\';
   } else
    execname = (char *)name;
   break;
  case 1:
   execname = get_string_value ("COMSPEC");
   if (!execname)
   {
    internal_error("COMSPEC variable not defined");
    errno = EACCES;
    return -1;
   }
   prefix_len = strlen(execname) + 1;
   prefix = alloca(prefix_len + 2 + 1 + strlen(name) + 1);
   strcpy(prefix, execname);
   emx_deunixify(prefix);
   strcpy((char *)&prefix[prefix_len - 1], " /c ");
   prefix_len += 2 + 1;
   strcpy((char *)&prefix[prefix_len], name);
   prefix_len += strlen(name) + 1;
   break;
  case 2:
  default:
  {
   /* We must define HAVE_HASH_BANG_EXEC since we`re processing #! here */
   FILE *f;
   char line[MAXNAMLEN + 3];
   line[0] = 0;
   if (!(f = fopen(name, "rt")))
   {
    errno = ENOENT;
    return -1;
   };
   fgets((char *)&line, sizeof(line), f);
   fclose(f);
   if (line[0] != '#')
    /* Try to run as regular executable */
    goto directrun;
   if (line[1] != '!')
   {
    /* Run script using current shell */
    strcpy((char *)&line, "#! ");
    strcat((char *)&line, shell_name);
   }
   n = strlen(line);
   while ((n > 0) && ((line[n - 1] < ' ') || (whitespace(line[n])))) n--;
   for (i = 2; whitespace(line[i]) && i < n; i++)
    ;
   for (j = i; (!whitespace(line[j])) && j < n; j++)
    ;
   l = i; j++;
   tmp = xmalloc(j - i);
   _strncpy(tmp, (char *)&line[i], j - i);

   execname = find_user_command(tmp);
   free(tmp);
   freeexec = 1;

   prefix_len = n - l + 1 + 1 + strlen(name);
   prefix = alloca(prefix_len + 1);
   _strncpy(prefix, (char *)&line[l], n - l + 1);
   strcat(prefix, " ");
   strcat(prefix, name);
   break;
  }
 }

 if ((execname == NULL) || (access(execname, F_OK) != 0))
 {
  if (execname == NULL)
  {
   errno = ENOEXEC;
   return -1;
  }
  execname = savestring(execname);
  freeexec = 1;
  if ((ext_file_status(&execname) & FS_EXISTS) == 0)
  {
   free(execname);
   errno = ENOENT;
   return -1;
  }
 }

 {
  char *qlist = get_string_value ("BASH_NOQUOTEARGS");
  char *tmp, *name = _getname (execname);
  int namelen;

  tmp = _getext (name);
  namelen = (tmp ? (int) (tmp - name) : strlen (name));

  while (qlist)
  {
   tmp = strchr (qlist, ';');
   if (!(j = tmp ? (int) (tmp - qlist) : strlen (qlist)))
    break;
   if ((namelen == j) &&
       (memicmp (qlist, name, namelen) == 0))
   {
    quoteargs = 0;
    break;
   }
   qlist += j;
   while (qlist[0] == ';')
    qlist++;
  }
 }

 /* Prepare command-line string */
 j = prefix_len + 2;
 for (i = 0; i <= 1; i++)
 {
  for (p = (const char **)argv; *p != NULL; ++p)
  {
   if (p != (const char **)argv)
    if (i == 0)			// Add a space before args starting from 1
     j++;
    else
     strcat(p_arg, " ");
   else
    if (prefix_len)
     continue;			// Prefix already contains argv[0]

   // If argv[i] contains a space or tab, we should put it in quotes
   if (strchr(*p, ' ') || strchr(*p, '\t'))
    if (i == 0)
     j += 1 + (quoteargs ? q_strlen(*p) : strlen(*p)) + 1;
    else
    {
     strcat(p_arg, "\"");
     if (quoteargs)
      q_strcat (p_arg, *p);
     else
      strcat (p_arg, *p);
     strcat(p_arg, "\"");
    }
   else
    // If we`re running a EMX program, we should backquote all '"'s in argv[i]
    if (i == 0)
     j += (quoteargs ? q_strlen(*p) : strlen(*p));
    else
     if (quoteargs)
      q_strcat(p_arg, *p);
     else
      strcat(p_arg, *p);
  }
  if (i == 0)
  {
   p_arg = alloca(j);
   if (prefix_len)
   {
    memcpy(p_arg, prefix, prefix_len);
    p_arg[prefix_len] = ' ';
    p_arg[prefix_len + 1] = 0;
   } else
    *p_arg = 0;
  }
 }
 p_arg[strlen(p_arg) + 1] = 0;

#if 0
 printf("quoteargs = %d\n", quoteargs);
 printf("exec{%s}\n", execname);
 printf("args{%s}\n", p_arg);
#endif

 for (arg1 = p_arg; !whitespace(*arg1) && *arg1; arg1++) ;
 *arg1++ = 0;

 /* Prepare environment */
 j = 1;
 for (p = (const char * const *)envp; *p != NULL; ++p)
  j += strlen (*p) + 1;
 p_env = tmp = alloca(j);
 for (p = (const char * const *)envp; *p != NULL; ++p)
 {
  i = strlen (*p);
  memcpy(tmp, *p, i+1);
  tmp += i+1;
 }
 *tmp = 0;

 if (runflags & spawn_SESSION) /* Use DosStartSession */
 {
  HQUEUE hq;

  /* Termination queue management */
  sprintf((char *)&queue, "\\QUEUES\\bash%d", getpid());
  if (DosCreateQueue(&hq, QUE_FIFO | QUE_CONVERT_ADDRESS, (PSZ)queue) == NO_ERROR)
  {
   STARTDATA sd;
   ULONG sid,pid;
   APIRET r;

   memset(&sd, 0, sizeof(sd));
   sd.Length = sizeof(sd);
   sd.Related = (runflags & spawn_WAIT ? SSF_RELATED_CHILD : SSF_RELATED_INDEPENDENT);
   sd.FgBg = SSF_FGBG_FORE;
   sd.PgmName = execname;
   sd.PgmInputs = arg1;
   sd.TermQ = (PBYTE)&queue;
   sd.Environment = p_env;
   sd.InheritOpt = SSF_INHERTOPT_PARENT;
   sd.SessionType = (runflags & spawn_TYPE) >> 16;
   sd.ObjectBuffer = (PSZ)&errbuf;
   sd.ObjectBuffLen = sizeof(errbuf);
#if 0
   sd.PgmControl = SSF_CONTROL_NOAUTOCLOSE;
#endif

   r = DosStartSession(&sd, &sid, &pid);

   if (r == NO_ERROR || r == ERROR_SMG_START_IN_BACKGROUND)
   {
    if (runflags & spawn_WAIT)
    {
     REQUESTDATA rd;
     ULONG Length;
     PUSHORT Info = NULL;
     BYTE Priority;
     ULONG oldVis, oldJump;
     SWP oldpos;

     if (hswValid)
     {
      /* Exclude session from task list */
      oldVis = swc.uchVisibility; swc.uchVisibility = SWL_INVISIBLE;
      oldJump = swc.fbJump; swc.fbJump = SWL_NOTJUMPABLE;
      WinChangeSwitchEntry(vioHSW, &swc);

      /* Minimize session */
      WinQueryWindowPos(swc.hwnd, &oldpos);
      if ((oldpos.fl & SWP_MINIMIZE) == 0)
       WinPostMsg(swc.hwnd, WM_SYSCOMMAND, (MPARAM)SC_MINIMIZE, MPFROM2SHORT(CMDSRC_MENU, FALSE));
     }

     DosReadQueue(hq, &rd, &Length, (PPVOID)&Info, 0,
                  DCWW_WAIT, &Priority, 0);

     if (hswValid)
     {
      /* Restore jumpable & visible status */
      swc.uchVisibility = oldVis;
      swc.fbJump = oldJump;
      WinChangeSwitchEntry(vioHSW, &swc);

      /* Restore session */
      if ((oldpos.fl & SWP_MINIMIZE) == 0)
      {
       WinPostMsg(swc.hwnd, WM_SYSCOMMAND, (MPARAM)SC_RESTORE, MPFROM2SHORT(CMDSRC_MENU, FALSE));
       WinSetWindowPos(swc.hwnd, oldpos.hwndInsertBehind, oldpos.x, oldpos.y,
                       oldpos.cx, oldpos.cy, oldpos.fl);
      }
     }

     retcode = Info[1];
    } else
     retcode = pid;
   } else
    internal_error("Execution failed because of module \"%s\"", (char *)&errbuf);
   DosCloseQueue(hq);
  } else