/*===========================================================================*
 *                                                                           *
 *  sflproco.imp - Process control functions for OS/2                        *
 *                                                                           *
 *  Copyright (c) 1991-2010 iMatix Corporation                               *
 *                                                                           *
 *  ------------------ GPL Licensed Source Code ------------------           *
 *  iMatix makes this software available under the GNU General               *
 *  Public License (GPL) license for open source projects.  For              *
 *  details of the GPL license please see www.gnu.org or read the            *
 *  file license.gpl provided in this package.                               *
 *                                                                           *
 *  This program is free software; you can redistribute it and/or            *
 *  modify it under the terms of the GNU General Public License as           *
 *  published by the Free Software Foundation; either version 3 of           *
 *  the License, or (at your option) any later version.                      *
 *                                                                           *
 *  This program 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 General Public License for more details.                             *
 *                                                                           *
 *  You should have received a copy of the GNU General Public                *
 *  License along with this program in the file 'license.gpl'; if            *
 *  not, see <http://www.gnu.org/licenses/>.                                 *
 *                                                                           *
 *  You can also license this software under iMatix's General Terms          *
 *  of Business (GTB) for commercial projects.  If you have not              *
 *  explicitly licensed this software under the iMatix GTB you may           *
 *  only use it under the terms of the GNU General Public License.           *
 *                                                                           *
 *  For more information, send an email to info@imatix.com.                  *
 *  --------------------------------------------------------------           *
 *===========================================================================*/

/*  OS/2 implementation of the SFL process_create_full() function            */
/*  This function receives input in the form of a pointer to a PROCESS_DATA  */
/*  structure called procinfo.  See sflproc.c for details.                   */

#   if (!defined (__EMX__))
#       error This function requires the EMX runtime
#   endif

    ARGLIST
        *arglist;                       /*  Argument list                    */
    int
        process = 0,                    /*  Process number                   */
        old_stdin  = NULL_HANDLE,       /*  Dup'd handle for old stdin       */
        old_stdout = NULL_HANDLE,       /*  Dup'd handle for old stdout      */
        old_stderr = NULL_HANDLE;       /*  Dup'd handle for old stderr      */
    Bool
        free_envv = FALSE;              /*  True if we should free envv      */
    const char
        *path,                          /*  Path to search                   */
        *shell,                         /*  Shell to use                     */
        **searchext,                    /*  Extensions to search             */
        *interpreter;                   /*  Name of script interpreter       */
    char
        *full_filename,                 /*  Full filename to run             */
        **argv,                         /*  Arguments for program            */
        **envv,                         /*  Environment for program          */
        *curdir = NULL;                 /*  Current working directory        */

    /*  First, check that minimum arguments needed to do something are set   */
    ASSERT (procinfo);
    if (!procinfo)
        return (NULL_PROCESS);

    ASSERT (procinfo-> filename);
    if (!procinfo-> filename)
      {
        procinfo-> error = EINVAL;
        return (NULL_PROCESS);
      }
    /*  Initialise return information                                        */
    procinfo-> pid        = NULL_PROCESS;
    procinfo-> error      = 0;
    procinfo-> returncode = -1;

    /*  For comparison... Unix version splits into parent & child here...    */

#   include "sflprocx.imp"              /*  Get implementation core          */

    /*  If requested, change to a different root directory, and/or work dir  */
    if (procinfo-> error == 0
    && (procinfo-> rootdir || procinfo-> workdir))
      {
        int
            rc = 0;

        curdir = _getcwd2 (NULL, 256);
        if (curdir == NULL)
            procinfo-> error = errno? errno: EACCES;
        else
          {
            if (procinfo-> rootdir)
                rc = _chdir2 (procinfo-> rootdir);
            if (procinfo-> workdir && rc == 0)
                rc = chdir (procinfo-> workdir);
            if (rc == -1)
              {
                procinfo-> error = errno? errno: EACCES;
                _chdir2 (curdir);       /*  Try to restore existing dir      */
              }
          }
      }

    /*  Now spawn the process                                                */
    if (procinfo-> error == 0)
      {
        int
            spawn_mode;

        /*  Build final argv[] from arglist                                  */
        argv = arglist_to_table (arglist);
        if (argv)
          {
            /*  Spawn the new program, and pick-up its process ID                */
            if (procinfo-> createdaemon)
                spawn_mode = P_DETACH;
            else
                spawn_mode = P_NOWAIT;

            {
              char **ptr = argv;
              fprintf(stderr, "About to run: (%s) ", full_filename);
              for (ptr = argv; *ptr; ptr++)
                 fprintf(stderr, "[%s] ", *ptr);

              fprintf(stderr, "\n");
            }
            process = spawnve (spawn_mode, full_filename, argv, envv);
            procinfo-> pid = ((PROCESS) process);
            if (process <= -1)
                procinfo-> error = errno? errno: EACCES;
            else
            if (procinfo-> wait)
                procinfo-> returncode = waitpid (process, 0, 0);

            mem_free (argv);
          }
        else
          procinfo-> error = errno;
      }

    /*  Put things back the way they were before                             */
    restore_redirection (old_stdin, old_stdout, old_stderr);
    if (curdir != NULL)                 /*  If directory changed, restore it */
      {
        _chdir2 (curdir);
        free (curdir);
      }
    if (free_envv)
        strtfree (envv);
    arglist_free (arglist);
        
    /*  Now, return the process ID or NULL_PROCESS if there was an error     */
    if (procinfo-> error == 0)
        return ((PROCESS) process);
    else
        return (NULL_PROCESS);

