Author Topic: Can _PipeShellResult be enhanced to get stderr and stdin?  (Read 244 times)

flethuseo

  • Senior Community Member
  • Posts: 176
  • Hero Points: 2
Can _PipeShellResult be enhanced to get stderr and stdin?
« on: March 01, 2018, 02:03:03 am »
I'm finding myself using this command a lot lately _PipeShellResult. I'm wondering if there are ways that it can be enhanced to get output to standard error, and allow input through stdin, the way the .process buffer does.

/**
 * Execute cmdline and return output from stdout.
 * <p>
 * IMPORTANT:
 * If the process never exits, then you will have to
 * break the Slick-C&reg; macro (Ctrl+Alt+Shift+F2).
 * <p>
 * Note:

 * Only stdout is read. If the process only outputs on stderr,
 * you will get an empty string back.
 *
 * @param cmdline Command line to execute.
 * @param status  Status/exit code of shelled process.
 * @param options (optional). Options are:
 *                'A' = Asynchronous (do not wait for execution
 *                to complete). 'C' = Execute in a
 *                console window. 'H' = Hide application window.
 *                Defaults to "".
 *
 * @return _str output from stdout of shelled process.
 *
 * @example _PipeShellResult("cd", status) returns
 * the current working directory as reported
 * by the operating system shell.
 */
_str _PipeShellResult(_str cmdline, int& status, _str options="")
{
   async := ( 0 != pos('A',upcase(options),1,'e') );
   console := ( 0 != pos('C',upcase(options),1,'e') );
   hide := ( 0 != pos('H',upcase(options),1,'e') );

   int hin, hout, herr;
   _str opt = '';
   if( console ) {
      opt = opt'C';
   }
   if( hide ) {
      opt = opt'H';
   }
   int hprocess = _PipeProcess(cmdline,hin,hout,herr,opt);
   if( hprocess<0 ) {
      // Error
      status=hprocess;
      return "";
   }
   exited := false;
   _str line = "";
   _str next = "";
   for(;;) {
      status=_PipeReadLine(line,hin);
      exited=_PipeIsProcessExited(hprocess)!=0;
      if( status<0 || line!="" || exited ) {
         break;
      }
      delay(1);
   }
   // Wait for process to exit before attempting to read any more
   while( !async && !exited ) {
      exited=_PipeIsProcessExited(hprocess) != 0;
      delay(1);
   }
   while( !async && status==0 ) {
      status=_PipeReadLine(next,hin);
      if (!status && next=="") {
         if( line != "" ) line :+= "\n";
         status=_PipeReadLine(next,hin);
      }
      if( !status ) {
         if( line != "" ) line :+= "\n";
         line :+= next;
      }
      if( next=="" && exited ) {
         break;
      }
      delay(1);
   }
   int exit_status = _PipeEndProcess(hprocess);;
   _PipeClose(hin);
   _PipeClose(hout);
   _PipeClose(herr);
   // Favor earlier errors over the exit code of the process
   if( !async && status==0 ) {
      status=exit_status;
   }
   return line;
}


Thanks,
tEd