{
Copyright (C) 1999 Free Software Foundation, Inc.

Author: Frank Heckenbach <frank@pascal.gnu.de>

Pascal interface to the pexecute and pwait functions.

This Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation, version 2.

This Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with this Library; see the file COPYING.LIB.  If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.
}

unit PExecute;

interface

uses GPC;

const
  PExecute_First   = 1;
  PExecute_Last    = 2;
  PExecute_One     = PExecute_First or PExecute_Last;
  PExecute_Search  = 4;
  PExecute_Verbose = 8;

{
  PExecute: execute a program.

  Program and ArgV are the arguments to execv/execvp.

  Flags and PExecute_Search is non-zero if $PATH should be searched
  (It's not clear that GCC passes this flag correctly).
  Flags and PExecute_First is nonzero for the first process in chain.
  Flags and PExecute_Last is nonzero for the last process in chain.

  The result is the pid on systems like Unix where we fork/exec and on systems
  like WIN32 and OS2 where we use spawn.  It is up to the caller to wait for
  the child.

  The result is the WExitStatus on systems like MSDOS where we spawn and wait
  for the child here.

  Upon failure, ErrMsg is set to the text of the error message,
  and -1 is returned.  `errno' is available to the caller to use.

  PWait: cover function for wait.

  PID is the process id of the task to wait for.
  Status is the `status' argument to wait.
  Flags is currently unused (allows future enhancement without breaking
  upward compatibility).  Pass 0 for now.

  The result is the pid of the child reaped,
  or -1 for failure (errno says why).

  On systems that don't support waiting for a particular child, PID is
  ignored.  On systems like MSDOS that don't really multitask PWait
  is just a mechanism to provide a consistent interface for the caller.
}

function PExecute (ProgramName : CString; ArgV: PCStrings; var ErrMsg : String; Flags : Integer) : Integer; asmname '_p_pexecute';
function PWait (PID : Integer; var Status : Integer; Flags : Integer) : Integer; C;

{ Extract information from the status returned by PWait }
function WIfSignaled (Status : Integer) : Boolean; asmname '_p_WIfSignaled';
function WTermSig    (Status : Integer) : Integer; asmname '_p_WTermSig';
function WIfExited   (Status : Integer) : Boolean; asmname '_p_WIfExited';
function WExitStatus (Status : Integer) : Integer; asmname '_p_WExitStatus';

implementation

{$L pexecutc.c}

function PExecuteC (ProgramName : CString; ArgV: PCStrings; This_PName, Temp_Base : CString;
                    var ErrMsg_Fmt, ErrMsg_Arg : CString; Flags : Integer) : Integer; asmname 'pexecute';

function PExecute (ProgramName : CString; ArgV: PCStrings; var ErrMsg : String; Flags : Integer) : Integer;
var
  ErrMsg_Fmt, ErrMsg_Arg : CString;
  i : Integer;
begin
  PExecute := PExecuteC (ProgramName, ArgV, CParameters^[0],
    GetTempDirectory + 'ccXXXXXX', ErrMsg_Fmt, ErrMsg_Arg, Flags);
  if ErrMsg_Fmt = nil
    then ErrMsg := ''
    else
      begin
        ErrMsg := CString2String (ErrMsg_Fmt);
        i := Pos ('%s', ErrMsg);
        if (ErrMsg_Arg <> nil) and (i <> 0) then
          begin
            Delete (ErrMsg, i, 2);
            Insert (CString2String (ErrMsg_Arg), ErrMsg, i)
          end
      end
end;

end.
