Beispiel #1
0
Datei: tcc.c Projekt: raldoni/tcc
static int execvp_win32(const char *prog, char **argv)
{
    int ret = spawnvp(P_NOWAIT, prog, (const char *const*)argv);
    if (-1 == ret)
        return ret;
    cwait(&ret, ret, WAIT_CHILD);
    exit(ret);
}
Beispiel #2
0
void main()
  {
     int   process_id;
     int   status;

     process_id = spawnl( P_NOWAIT, "child.exe",
                "child", "parm", NULL );
     cwait( &status, process_id, WAIT_CHILD );
  }
Beispiel #3
0
/* wait waits for a process started by fork_exec.
 * In general, this is called after the complete IO to the called process but
 * it isn't guaranteed. Never call if you don't expect a sudden death of the
 * subprocess.
 * Returns the exit status of the subprocess under normal circumstances. If
 * the subprocess has died by a signal, the return value is -signalnumber.
 */
static int Os2_wait(int process)
{
   int rc, retval, status;

#ifdef __WATCOMC__
   /*
    * Watcom is strange. EINTR isn't an indicator for a retry of the call.
    */
   status = -1;
   rc = cwait(&status, process, WAIT_CHILD);
   if (rc == -1)
   {
      if ((status != -1) && (errno == EINTR))
         retval = -status; /* Exception reason in lower byte */
      else
         retval = -errno;  /* I don't have a better idea */
   }
   else
   {
      if (status & 0xFF)
         retval = -status; /* Exception reason in lower byte */
      else
         retval = status >> 8;
   }
#else
   do {
      rc = waitpid(process, &status, 0);
   } while ((rc == -1) && (errno == EINTR));

   if (WIFEXITED(status))
   {
      retval = (int) WEXITSTATUS(status);
      if ( retval < 0 )
         retval = -retval;
   }
   else if (WIFSIGNALED(status))
   {
      retval = -WTERMSIG(status);
      if ( retval > 0 )
         retval = -retval;
      else if ( retval == 0 )
         retval = -1;
   }
   else
   {
      retval = -WSTOPSIG(status);
      if ( retval > 0 )
         retval = -retval;
      else if ( retval == 0 )
         retval = -1;
   }
#endif

   return(retval);
}
Beispiel #4
0
/* npflush is called for filter ops effected with temp files */
void
npflush(void)
{
    char buf[NFILEN + 128];
    int  rc, term_status;

    /*
     * caller has filled and closed the write pipe data stream.  time to
     * exec a process.
     */

    if ((stdout_fd = open(stdout_name, O_RDONLY|O_BINARY)) == BAD_FD)
    {
        /* oh my, put complaint in user's face. */

        sprintf(buf, "[unable to open temp file \"%s\": %s]",
                stdout_name,
                strerror(errno));
        lastditch_msg(buf);
    }
    else
    {
        /* handles[1-2] were initialized by tmp_npopen_open() */

        handles[0] = (HANDLE) _get_osfhandle(stdout_fd);
        rc = (exec_shell(shcmd,
                         handles,
                         TRUE    /* do hide child window */
                        ) == BAD_PROC_HANDLE) ? FALSE : TRUE;
        if (! rc)
        {
            /* Shell process failed, put complaint in user's face. */

            sprintf(buf, SHELL_ERR_MSG, get_shell());
            lastditch_msg(buf);
        }
        else
        {
            /* now wait for app to exit */

            (void) cwait(&term_status, (CWAIT_PARAM_TYPE) proc_handle, 0);
            TRACE(("...CreateProcess finished waiting in npflush\n"));
            close_proc_handle();
        }

        /*
         * When closing descriptors shared between parent and child, order
         * is quite important when $shell == command.com .  In this
         * situation, the descriptors can't be closed until the exec'd
         * process exits.
         */
        close_fd(stdout_fd);
    }
}
Beispiel #5
0
int Process::join(int pid)
{
	int status, result;

	if(pid == -1)
		return pid;

	result = (int)cwait(&status, pid, WAIT_CHILD);
	if(status & 0x0)
		return -1;
	return result;
}
Beispiel #6
0
static void
native_npclose(FILE *fp)
{
    int term_status;

    (void) fflush(fp);
    (void) fclose(fp);
    if (proc_handle != BAD_PROC_HANDLE)
    {
        (void) cwait(&term_status, (CWAIT_PARAM_TYPE) proc_handle, 0);
        TRACE(("...CreateProcess finished waiting in native_npclose\n"));
        close_proc_handle();
    }
    common_cleanup();
}
Beispiel #7
0
static void
tmp_npclose(FILE *fp)
{
    char buf[NFILEN + 128];
    int  rc, term_status;

    (void) fflush(fp);
    (void) fclose(fp);

    if (stdout_fd != BAD_FD)
    {
        /*
         * write pipe, but not a filter.  Editor has written data to temp
         * file, time now to exec "cmd" and hook its stdin to the file.
         *
         * It should be noted that exec'ing a process in the npclose()
         * phase of a write pipe is not exactly keeping in spirit with
         * the control flow in file.c :-) .  However, the strategy used
         * here ensures that the launched process reads a temp file that
         * is completey flushed to disk.  The only direct drawback with
         * this approach is that when the exec'd process exits, the user
         * does not receive a "[press return to continue]" prompt from
         * file.c .  But, cough, we can work around that problem :-) .
         */

        if ((stdout_fd = open(stdout_name, O_RDONLY|O_BINARY)) == BAD_FD)
        {
            /* oh my, put complaint in user's face. */

            sprintf(buf, "[unable to open temp file \"%s\": %s]",
                    stdout_name,
                    strerror(errno));
            lastditch_msg(buf);
        }
        else
        {
            handles[0] = (HANDLE) _get_osfhandle(stdout_fd);
            handles[1] = handles[2] = GetStdHandle(STD_OUTPUT_HANDLE);
            rc = (exec_shell(shcmd,
                             handles,
                             FALSE    /* don't hide child window */
                            ) == BAD_PROC_HANDLE) ? FALSE : TRUE;
            if (! rc)
            {
                /* Shell process failed, put complaint in user's face. */

                sprintf(buf, SHELL_ERR_MSG, get_shell());
                lastditch_msg(buf);
            }
            else
            {
                /* now wait for app to exit */

                (void) cwait(&term_status, (CWAIT_PARAM_TYPE) proc_handle, 0);
                TRACE(("...CreateProcess finished waiting in tmp_npclose\n"));
                close_proc_handle();
            }

            /*
             * When closing descriptors shared between parent and child,
             * order is quite important when $shell == command.com .  In
             * this situation, the descriptors can't be closed until the
             * exec'd process exits.
             */
            close_fd(stdout_fd);
        }
        pressreturn();  /* cough */
        sgarbf = TRUE;
    }
    tmp_cleanup();
}
Beispiel #8
0
static int
tmp_inout_popen(FILE **fr, FILE **fw, char *cmd)
{
    char  buf[NFILEN + 128];
    DWORD dummy, len;
    int   rc, term_status, tmpin_fd;

    TRACE(("tmp_inout_popen cmd=%s\n", cmd));
    proc_handle = BAD_PROC_HANDLE;
    handles[0]  = handles[1] = handles[2]  = INVALID_HANDLE_VALUE;
    tmpin_fd    = stdin_fd   = stdout_fd   = BAD_FD;
    tmpin_name  = stdin_name = stdout_name = NULL;
    set_console_title(cmd);
    do
    {
        if (fr)
        {
            *fr = NULL;
            if ((stdin_name = _tempnam(getenv("TEMP"), "vile")) == NULL)
                break;
            if ((stdin_fd = open(stdin_name,
                                 O_RDWR|O_CREAT|O_TRUNC|O_TEXT,
                                 _S_IWRITE|_S_IREAD)) == BAD_FD)
            {
                break;
            }
            handles[2] = handles[1] = (HANDLE) _get_osfhandle(stdin_fd);
            if (! fw)
            {
                /*
                 * This is a read pipe (only).  Connect child's stdin to
                 * an empty file.  Under no circumstances should the
                 * child's stdin be connected to a device (else lots of
                 * screwy things will occur).  In particular, connecting
                 * the child's stdin to the parent's stdin will cause
                 * aborts and hangs on the various Win32 hosts.  You've
                 * been warned.
                 */

                if ((tmpin_name = _tempnam(getenv("TEMP"), "vile")) == NULL)
                    break;
                if ((tmpin_fd = open(tmpin_name,
                                     O_RDONLY|O_CREAT|O_TRUNC,
                                     _S_IWRITE|_S_IREAD)) == BAD_FD)
                {
                    break;
                }
                handles[0] = (HANDLE) _get_osfhandle(tmpin_fd);
            }
            else
            {
                /*
                 * Set up descriptor for filter operation.   Note the
                 * sublteties here:  exec'd shell is passed a descriptor
                 * to the temp file that's opened "w".  The editor
                 * receives a descriptor to the file that's opened "r".
                 */

                if ((*fr = fopen(stdin_name, "r")) == NULL)
                    break;
            }
        }
        if (fw)
        {
            *fw = NULL;

            /* create a temp file to receive data from the editor */
            if ((stdout_name = _tempnam(getenv("TEMP"), "vile")) == NULL)
                break;
            if ((stdout_fd = open(stdout_name,
                                  O_RDWR|O_CREAT|O_TRUNC|O_BINARY,
                                  _S_IWRITE|_S_IREAD)) == BAD_FD)
            {
                break;
            }
            if ((*fw = fdopen(stdout_fd, "w")) == 0)
                break;

            /*
             * we're all set up, but can't exec "cmd" until the editor
             * writes data to the temp file connected to stdout.
             */
            shcmd = cmd;   /* remember this */
            return (TRUE);
        }

        /* This must be a read (only) pipe.  Appropriate to exec "cmd". */
        rc = (exec_shell(cmd,
                         handles,
                         TRUE       /* hide child wdw */
                        ) == BAD_PROC_HANDLE) ? FALSE : TRUE;

        if (! rc)
        {
            /*
             * Shell process failed, put complaint in user's buffer, which
             * is currently proxied by a temp file that the editor will
             * suck in shortly.
             */

            len = (DWORD) (lsprintf(buf, SHELL_ERR_MSG, get_shell()) - buf);
            (void) WriteFile(handles[1], buf, len, &dummy, NULL);
            FlushFileBuffers(handles[1]);
        }
        else
        {
            /* wait for exec'd process to exit */

            (void) cwait(&term_status, (CWAIT_PARAM_TYPE) proc_handle, 0);
            TRACE(("...CreateProcess finished waiting in tmp_inout_popen\n"));
            close_proc_handle();
        }

        /*
         * When closing descriptors shared between parent and child, order
         * is quite important when $shell == command.com .  In this
         * situation, the descriptors can't be closed until the exec'd
         * process exits (I kid you not).
         */
        close_fd(stdin_fd);
        (void) close(tmpin_fd);

        /* let the editor consume the output of the read pipe */
        if ((*fr = fopen(stdin_name, "r")) == NULL)
        {
            /*
             * impossible to put error in user's buffer since that file
             * descriptor is closed.
             */

            sprintf(buf,
                    "[error opening temp file \"%s\": %s]",
                    stdin_name,
                    strerror(errno));
            lastditch_msg(buf);
            break;
        }
        return (rc);
    }
    while (FALSE);

    /* If we get here -- some operation has failed.  Clean up. */
    tmp_cleanup();
    return (FALSE);
}
Beispiel #9
0
int hb_fsProcessValue( HB_FHANDLE hProcess, HB_BOOL fWait )
{
   int iRetStatus = -1;

   HB_TRACE( HB_TR_DEBUG, ( "hb_fsProcessValue(%p, %d)", ( void * ) ( HB_PTRDIFF ) hProcess, fWait ) );

#if defined( HB_OS_WIN )
{
   HB_BOOL fError = HB_TRUE;
   DWORD dwResult;
   HANDLE hProc = ( HANDLE ) hb_fsGetOsHandle( hProcess );

   if( hProc )
   {
      hb_vmUnlock();
      dwResult = WaitForSingleObject( hProc, fWait ? INFINITE : 0 );
      if( dwResult == WAIT_OBJECT_0 )
      {
         fError = ! GetExitCodeProcess( hProc, &dwResult );
         iRetStatus = ! fError ? ( int ) dwResult : -2;
      }
      hb_fsSetIOError( ! fError, 0 );
      if( ! fError )
         CloseHandle( hProc );
      hb_vmLock();
   }
   else
      hb_fsSetError( ( HB_ERRCODE ) FS_ERROR );
}
#elif defined( HB_OS_UNIX ) || ( defined( HB_OS_OS2 ) && defined( __GNUC__ ) )
{
   int iStatus;
   pid_t pid = ( pid_t ) hProcess;

   if( pid > 0 )
   {
      hb_vmUnlock();
      iRetStatus = waitpid( pid, &iStatus, fWait ? 0 : WNOHANG );
      hb_fsSetIOError( iRetStatus >= 0, 0 );
#ifdef ERESTARTSYS
      if( iRetStatus < 0 && hb_fsOsError() != ( HB_ERRCODE ) ERESTARTSYS )
#else
      if( iRetStatus < 0 )
#endif
         iRetStatus = -2;
      else if( iRetStatus == 0 )
         iRetStatus = -1;
      else
         iRetStatus = WIFEXITED( iStatus ) ? WEXITSTATUS( iStatus ) : 0;
      hb_vmLock();
   }
   else
      hb_fsSetError( ( HB_ERRCODE ) FS_ERROR );
}
#elif defined( HB_OS_OS2 )
{
   PID pid = ( PID ) hProcess;

   if( pid > 0 )
   {
      RESULTCODES resultCodes = { 0, 0 };
      APIRET ret;

      ret = DosWaitChild( DCWA_PROCESS, fWait ? DCWW_WAIT : DCWW_NOWAIT,
                          &resultCodes, &pid, pid );
      hb_fsSetIOError( ret == NO_ERROR, 0 );
      if( ret == NO_ERROR )
         iRetStatus = resultCodes.codeResult;
      else
         iRetStatus = -2;
   }
   else
      hb_fsSetError( ( HB_ERRCODE ) FS_ERROR );
}
#elif defined( HB_OS_OS2 ) || defined( HB_OS_WIN )
{
   int iPid = ( int ) hProcess;

   HB_SYMBOL_UNUSED( fWait );

   if( iPid > 0 )
   {
      hb_vmUnlock();
#if defined( __BORLANDC__ )
      iPid = cwait( &iRetStatus, iPid, 0 );
#else
      iPid = _cwait( &iRetStatus, iPid, 0 );
#endif
      hb_fsSetIOError( iPid > 0, 0 );
      if( iPid != ( int ) hProcess )
         iRetStatus = -1;
      hb_vmLock();
   }
   else
      hb_fsSetError( ( HB_ERRCODE ) FS_ERROR );
}
#else
{
   int iTODO; /* TODO: for given platform */

   HB_SYMBOL_UNUSED( hProcess );
   HB_SYMBOL_UNUSED( fWait );
   hb_fsSetError( ( HB_ERRCODE ) FS_ERROR );
}
#endif
   return iRetStatus;
}
Beispiel #10
0
_WCRTLINK int wait( int *status )
    {
        return( cwait( status, 0, 0 ) );
    }