Ejemplo n.º 1
0
/*
 * Save standard I/O handles prior to redirection processing.  'select'
 * is a flag mask that specifies which of the standard handles are
 * marked for safekeeping.
 */
static ELVBOOL
SaveStdIOHandles (SAVE_IO save, int select)
{
  /* Establish default values for error recovery. */
  save[0] = save[1] = save[2] = ~0;

    /*
     * Make copies of the selected standard I/O handles and mark the
     * copies so that child processes will not inherit them.
     */
  if (select & SAVE_STDIN)
    {
      if (DosDupHandle (0, &save[0]) != NO_ERROR)
        {
          goto Error;
        }
      if (DosSetFHState (save[0], OPEN_FLAGS_NOINHERIT) != NO_ERROR)
        {
          goto Error;
        }
    }

  if (select & SAVE_STDOUT)
    {
      if (DosDupHandle (1, &save[1]) != NO_ERROR)
        {
          goto Error;
        }
      if (DosSetFHState (save[1], OPEN_FLAGS_NOINHERIT) != NO_ERROR)
        {
          goto Error;
        }
    }

  if (select & SAVE_STDERR)
    {
      if (DosDupHandle (2, &save[2]) != NO_ERROR)
        {
          goto Error;
        }
      if (DosSetFHState (save[2], OPEN_FLAGS_NOINHERIT) != NO_ERROR)
        {
          goto Error;
        }
    }

  /* Success. */
  return ElvTrue;

Error:
  /* Restore any handles we have managed to save. */
  RestoreStdIOHandles (save);
  msg (MSG_ERROR, "can't save stdio handle");
  return ElvFalse;
}
Ejemplo n.º 2
0
void main( int argc, char *argv[] )
{
    APIRET      rc;
    HFILE       h;
    unsigned long       actiontaken;
    unsigned long       sent;
    char        done;

    if( argc > 1 && (argv[1][0] == 'q' || argv[1][0] == 'Q') ) {
        rc = DosOpen( PREFIX DEFAULT_NAME, &h, &actiontaken, 0ul,
                        0, 0x01, 0x41, 0ul );
        if( rc == 0 ) {
            done = LNK_SHUTDOWN;
            DosWrite( h, &done, sizeof( done ), &sent );
            DosClose( h );
        }
        exit( 0 );
    }
    CmdProc = getenv( "COMSPEC" );
    if( CmdProc == NULL ) {
        fprintf( stderr, "Unable to find command processor\n" );
        exit( 1 );
    }
    //NYI: need to accept name for link pipe
    rc = DosCreateNPipe( PREFIX DEFAULT_NAME, &LnkHdl,
        NP_NOINHERIT | NP_NOWRITEBEHIND | NP_ACCESS_DUPLEX,
        NP_WAIT | NP_READMODE_MESSAGE | NP_TYPE_MESSAGE | 1,
        MAX_TRANS, MAX_TRANS, 0 );
    if( rc != 0 ) {
        fprintf( stderr, "Unable to create link pipe\n" );
        exit( 1 );
    }
    sprintf( RedirName, PREFIX "%d", getpid() );
    rc = DosCreateNPipe( RedirName, &RedirHdl,
        NP_NOINHERIT | NP_WRITEBEHIND | NP_ACCESS_INBOUND,
        NP_WAIT | NP_READMODE_BYTE | NP_TYPE_BYTE | 1,
        MAX_TRANS, MAX_TRANS, 0 );
    if( rc != 0 ) {
        fprintf( stderr, "Unable to create redirection pipe\n" );
        exit( 1 );
    }
    DosSetFHState( LnkHdl, OPEN_FLAGS_NOINHERIT );
    DosSetFHState( RedirHdl, OPEN_FLAGS_NOINHERIT );
    for( ;; ) {
        rc = DosConnectNPipe( LnkHdl );
        if( rc == 0 ) {
            ProcessConnection();
            DosDisConnectNPipe( LnkHdl );
        }
    }
}
static void set_inherit(HFILE hFile, int i)
{
	ULONG state = 0;

	DosQueryFHState(hFile, &state);
	DosSetFHState(hFile, (state & ~OPEN_FLAGS_NOINHERIT) | (i ? 0:OPEN_FLAGS_NOINHERIT));
}
Ejemplo n.º 4
0
PRStatus
_PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable)
{
    APIRET rc = 0;
    ULONG flags;
    switch (fd->methods->file_type)
    {
        case PR_DESC_PIPE:
        case PR_DESC_FILE:
            rc = DosQueryFHState((HFILE)fd->secret->md.osfd, &flags);
            if (rc != NO_ERROR) {
                PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
                return PR_FAILURE;
            }

            if (inheritable)
              flags &= ~OPEN_FLAGS_NOINHERIT;
            else
              flags |= OPEN_FLAGS_NOINHERIT;

            /* Mask off flags DosSetFHState don't want. */
            flags &= (OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT);
            rc = DosSetFHState((HFILE)fd->secret->md.osfd, flags);
            if (rc != NO_ERROR) {
                PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
                return PR_FAILURE;
            }
            break;

        case PR_DESC_LAYERED:
            /* what to do here? */
            PR_SetError(PR_UNKNOWN_ERROR, 87 /*ERROR_INVALID_PARAMETER*/);
            return PR_FAILURE;

        case PR_DESC_SOCKET_TCP:
        case PR_DESC_SOCKET_UDP:
            /* These are global on OS/2. */
            break;
    }

    return PR_SUCCESS;
}
/**
 * Implementation of VbglR3Init and VbglR3InitUser
 */
static int vbglR3Init(const char *pszDeviceName)
{
    uint32_t cInits = ASMAtomicIncU32(&g_cInits);
    Assert(cInits > 0);
    if (cInits > 1)
    {
        /*
         * This will fail if two (or more) threads race each other calling VbglR3Init.
         * However it will work fine for single threaded or otherwise serialized
         * processed calling us more than once.
         */
#ifdef RT_OS_WINDOWS
        if (g_hFile == INVALID_HANDLE_VALUE)
#elif !defined (VBOX_VBGLR3_XFREE86)
        if (g_File == NIL_RTFILE)
#else
        if (g_File == -1)
#endif
            return VERR_INTERNAL_ERROR;
        return VINF_SUCCESS;
    }
#if defined(RT_OS_WINDOWS)
    if (g_hFile != INVALID_HANDLE_VALUE)
#elif !defined(VBOX_VBGLR3_XFREE86)
    if (g_File != NIL_RTFILE)
#else
    if (g_File != -1)
#endif
        return VERR_INTERNAL_ERROR;

#if defined(RT_OS_WINDOWS)
    /*
     * Have to use CreateFile here as we want to specify FILE_FLAG_OVERLAPPED
     * and possible some other bits not available thru iprt/file.h.
     */
    HANDLE hFile = CreateFile(pszDeviceName,
                              GENERIC_READ | GENERIC_WRITE,
                              FILE_SHARE_READ | FILE_SHARE_WRITE,
                              NULL,
                              OPEN_EXISTING,
                              FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
                              NULL);

    if (hFile == INVALID_HANDLE_VALUE)
        return VERR_OPEN_FAILED;
    g_hFile = hFile;

#elif defined(RT_OS_OS2)
    /*
     * We might wish to compile this with Watcom, so stick to
     * the OS/2 APIs all the way. And in any case we have to use
     * DosDevIOCtl for the requests, why not use Dos* for everything.
     */
    HFILE hf = NULLHANDLE;
    ULONG ulAction = 0;
    APIRET rc = DosOpen((PCSZ)pszDeviceName, &hf, &ulAction, 0, FILE_NORMAL,
                        OPEN_ACTION_OPEN_IF_EXISTS,
                        OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE,
                        NULL);
    if (rc)
        return RTErrConvertFromOS2(rc);

    if (hf < 16)
    {
        HFILE ahfs[16];
        unsigned i;
        for (i = 0; i < RT_ELEMENTS(ahfs); i++)
        {
            ahfs[i] = 0xffffffff;
            rc = DosDupHandle(hf, &ahfs[i]);
            if (rc)
                break;
        }

        if (i-- > 1)
        {
            ULONG fulState = 0;
            rc = DosQueryFHState(ahfs[i], &fulState);
            if (!rc)
            {
                fulState |= OPEN_FLAGS_NOINHERIT;
                fulState &= OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT; /* Turn off non-participating bits. */
                rc = DosSetFHState(ahfs[i], fulState);
            }
            if (!rc)
            {
                rc = DosClose(hf);
                AssertMsg(!rc, ("%ld\n", rc));
                hf = ahfs[i];
            }
            else
                i++;
            while (i-- > 0)
                DosClose(ahfs[i]);
        }
    }
    g_File = (RTFILE)hf;

#elif defined(VBOX_VBGLR3_XFREE86)
    int File = xf86open(pszDeviceName, XF86_O_RDWR);
    if (File == -1)
        return VERR_OPEN_FAILED;
    g_File = File;

#else

    /* The default implementation. (linux, solaris, freebsd) */
    RTFILE File;
    int rc = RTFileOpen(&File, pszDeviceName, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    if (RT_FAILURE(rc))
        return rc;
    g_File = File;

#endif

#ifndef VBOX_VBGLR3_XFREE86
    /*
     * Create release logger
     */
    PRTLOGGER pReleaseLogger;
    static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
    int rc2 = RTLogCreate(&pReleaseLogger, 0, "all", "VBOX_RELEASE_LOG",
                          RT_ELEMENTS(s_apszGroups), &s_apszGroups[0], RTLOGDEST_USER, NULL);
    /* This may legitimately fail if we are using the mini-runtime. */
    if (RT_SUCCESS(rc2))
        RTLogRelSetDefaultInstance(pReleaseLogger);
#endif

    return VINF_SUCCESS;
}
Ejemplo n.º 6
0
HB_FHANDLE hb_fsProcessOpen( const char * pszFileName,
                             HB_FHANDLE * phStdin, HB_FHANDLE * phStdout,
                             HB_FHANDLE * phStderr,
                             HB_BOOL fDetach, HB_ULONG * pulPID )
{
   HB_FHANDLE hPipeIn [ 2 ] = { FS_ERROR, FS_ERROR },
              hPipeOut[ 2 ] = { FS_ERROR, FS_ERROR },
              hPipeErr[ 2 ] = { FS_ERROR, FS_ERROR };
   HB_FHANDLE hResult = FS_ERROR;
   HB_ERRCODE errCode;
   HB_BOOL fError = HB_FALSE;

   HB_TRACE( HB_TR_DEBUG, ( "hb_fsProcessOpen(%s, %p, %p, %p, %d, %p)", pszFileName, phStdin, phStdout, phStderr, fDetach, pulPID ) );

   if( phStdin != NULL )
      fError = ! hb_fsPipeCreate( hPipeIn );
   if( ! fError && phStdout != NULL )
      fError = ! hb_fsPipeCreate( hPipeOut );
   if( ! fError && phStderr != NULL )
   {
      if( phStdout == phStderr )
      {
         hPipeErr[ 0 ] = hPipeOut[ 0 ];
         hPipeErr[ 1 ] = hPipeOut[ 1 ];
      }
      else
         fError = ! hb_fsPipeCreate( hPipeErr );
   }

   if( ! fError )
   {
#if defined( HB_OS_WIN )

      PROCESS_INFORMATION pi;
      STARTUPINFO si;
      DWORD dwFlags = 0;
      LPTSTR lpCommand = HB_CHARDUP( pszFileName );

#  if ! defined( HB_OS_WIN_CE )
      if( phStdin != NULL )
         SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 1 ] ), HANDLE_FLAG_INHERIT, 0 );
      if( phStdout != NULL )
         SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 0 ] ), HANDLE_FLAG_INHERIT, 0 );
      if( phStderr != NULL && phStdout != phStderr )
         SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 0 ] ), HANDLE_FLAG_INHERIT, 0 );
#  endif

      memset( &pi, 0, sizeof( pi ) );
      memset( &si, 0, sizeof( si ) );
      si.cb = sizeof( si );
#  ifdef STARTF_USESTDHANDLES
      si.dwFlags = STARTF_USESTDHANDLES;
#  endif
      if( fDetach )
      {
#  ifdef STARTF_USESHOWWINDOW
         si.dwFlags |= STARTF_USESHOWWINDOW;
#  endif
         si.wShowWindow = SW_HIDE;
         si.hStdInput  = ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] );
         si.hStdOutput = ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] );
         si.hStdError  = ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] );
#  ifdef DETACHED_PROCESS
         dwFlags |= DETACHED_PROCESS;
#  endif
      }
      else
      {
         si.hStdInput  = phStdin  ? ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] ) : GetStdHandle( STD_INPUT_HANDLE );
         si.hStdOutput = phStdout ? ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] ) : GetStdHandle( STD_OUTPUT_HANDLE );
         si.hStdError  = phStderr ? ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] ) : GetStdHandle( STD_ERROR_HANDLE );
      }
      fError = ! CreateProcess( NULL,           /* lpAppName */
                                lpCommand,
                                NULL,           /* lpProcessAttr */
                                NULL,           /* lpThreadAttr */
                                TRUE,           /* bInheritHandles */
                                dwFlags,        /* dwCreationFlags */
                                NULL,           /* lpEnvironment */
                                NULL,           /* lpCurrentDirectory */
                                &si,
                                &pi );
      hb_fsSetIOError( ! fError, 0 );
      hb_xfree( lpCommand );
      if( ! fError )
      {
         if( phStdin != NULL )
         {
            *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ];
            hPipeIn[ 1 ] = FS_ERROR;
         }
         if( phStdout != NULL )
         {
            *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ];
            hPipeOut[ 0 ] = FS_ERROR;
         }
         if( phStderr != NULL )
         {
            *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ];
            hPipeErr[ 0 ] = FS_ERROR;
         }
         if( pulPID )
            *pulPID = pi.dwProcessId;
         CloseHandle( pi.hThread );
         hResult = ( HB_FHANDLE ) pi.hProcess;
      }

#elif defined( HB_OS_OS2 )

      HFILE hNull = ( HFILE ) FS_ERROR;
      ULONG ulState = 0;
      APIRET ret = NO_ERROR;
      PID pid = ( PID ) -1;
      PHB_GT pGT;

      if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) )
      {
         HB_FHANDLE hFile;

         ret = hb_fsOS2DosOpen( "NUL:", &hFile, &ulState, 0,
                                FILE_NORMAL, OPEN_ACCESS_READWRITE,
                                OPEN_ACTION_OPEN_IF_EXISTS );
         if( ret == NO_ERROR )
            hNull = ( HFILE ) hFile;
      }

      if( ret == NO_ERROR && phStdin != NULL )
      {
         ret = DosQueryFHState( hPipeIn[ 1 ], &ulState );
         if( ret == NO_ERROR && ( ulState & OPEN_FLAGS_NOINHERIT ) == 0 )
            ret = DosSetFHState( hPipeIn[ 1 ], ( ulState & 0xFF00 ) | OPEN_FLAGS_NOINHERIT );
      }
      if( ret == NO_ERROR && phStdout != NULL )
      {
         ret = DosQueryFHState( hPipeOut[ 0 ], &ulState );
         if( ret == NO_ERROR && ( ulState & OPEN_FLAGS_NOINHERIT ) == 0 )
            ret = DosSetFHState( hPipeOut[ 0 ], ( ulState & 0xFF00 ) | OPEN_FLAGS_NOINHERIT );
      }
      if( ret == NO_ERROR && phStderr != NULL && phStdout != phStderr )
      {
         ret = DosQueryFHState( hPipeErr[ 0 ], &ulState );
         if( ret == NO_ERROR && ( ulState & OPEN_FLAGS_NOINHERIT ) == 0 )
            ret = DosSetFHState( hPipeErr[ 0 ], ( ulState & 0xFF00 ) | OPEN_FLAGS_NOINHERIT );
      }

      if( ret == NO_ERROR && ( pGT = hb_gt_Base() ) != NULL )
      {
         ULONG ulStateIn, ulStateOut, ulStateErr;
         HFILE hStdIn, hStdErr, hStdOut, hDup;

         ulStateIn = ulStateOut = ulStateErr = OPEN_FLAGS_NOINHERIT;
         hStdIn  = hStdErr = hStdOut = ( HFILE ) FS_ERROR;

         if( ret == NO_ERROR && ( phStdin != NULL || fDetach ) )
         {
            hDup = 0;
            ret = DosDupHandle( hDup, &hStdIn );
            if( ret == NO_ERROR )
            {
               ret = DosQueryFHState( hStdIn, &ulStateIn );
               if( ret == NO_ERROR && ( ulStateIn & OPEN_FLAGS_NOINHERIT ) == 0 )
                  ret = DosSetFHState( hStdIn, ( ulStateIn & 0xFF00 ) | OPEN_FLAGS_NOINHERIT );
               if( ret == NO_ERROR )
                  ret = DosDupHandle( phStdin != NULL ? ( HFILE ) hPipeIn[ 0 ] : hNull, &hDup );
            }
         }

         if( ret == NO_ERROR && ( phStdout != NULL || fDetach ) )
         {
            hDup = 1;
            ret = DosDupHandle( hDup, &hStdOut );
            if( ret == NO_ERROR )
            {
               ret = DosQueryFHState( hStdOut, &ulStateOut );
               if( ret == NO_ERROR && ( ulStateOut & OPEN_FLAGS_NOINHERIT ) == 0 )
                  ret = DosSetFHState( hStdOut, ( ulStateOut & 0xFF00 ) | OPEN_FLAGS_NOINHERIT );
               if( ret == NO_ERROR )
                  ret = DosDupHandle( phStdout != NULL ? ( HFILE ) hPipeOut[ 1 ] : hNull, &hDup );
            }
         }

         if( ret == NO_ERROR && ( phStderr != NULL || fDetach ) )
         {
            hDup = 2;
            ret = DosDupHandle( hDup, &hStdErr );
            if( ret == NO_ERROR )
            {
               ret = DosQueryFHState( hStdErr, &ulStateErr );
               if( ret == NO_ERROR && ( ulStateErr & OPEN_FLAGS_NOINHERIT ) == 0 )
                  ret = DosSetFHState( hStdErr, ( ulStateErr & 0xFF00 ) | OPEN_FLAGS_NOINHERIT );
               if( ret == NO_ERROR )
                  ret = DosDupHandle( phStderr != NULL ? ( HFILE ) hPipeErr[ 1 ] : hNull, &hDup );
            }
         }

         if( ret == NO_ERROR )
         {
            char * pArgs = hb_buildArgsOS2( pszFileName, &ret );
            char uchLoadError[ CCHMAXPATH ] = { 0 };
            RESULTCODES ChildRC = { 0, 0 };

            if( pArgs )
            {
               ret = DosExecPgm( uchLoadError, sizeof( uchLoadError ),
                                 fDetach ? EXEC_BACKGROUND : EXEC_ASYNCRESULT,
                                 ( PCSZ ) pArgs, NULL /* env */,
                                 &ChildRC,
                                 ( PCSZ ) pArgs );
               if( ret == NO_ERROR )
                  pid = ChildRC.codeTerminate;
               hb_freeArgsOS2( pArgs );
            }
         }

         if( hNull != ( HFILE ) FS_ERROR )
            DosClose( hNull );

         if( hStdIn != ( HFILE ) FS_ERROR )
         {
            hDup = 0;
            DosDupHandle( hStdIn, &hDup );
            DosClose( hStdIn );
            if( ( ulStateIn & OPEN_FLAGS_NOINHERIT ) == 0 )
               DosSetFHState( hDup, ulStateIn & 0xFF00 );
         }
         if( hStdOut != ( HFILE ) FS_ERROR )
         {
            hDup = 1;
            DosDupHandle( hStdOut, &hDup );
            DosClose( hStdOut );
            if( ( ulStateOut & OPEN_FLAGS_NOINHERIT ) == 0 )
               DosSetFHState( hDup, ulStateOut & 0xFF00 );
         }
         if( hStdErr != ( HFILE ) FS_ERROR )
         {
            hDup = 2;
            DosDupHandle( hStdErr, &hDup );
            DosClose( hStdErr );
            if( ( ulStateErr & OPEN_FLAGS_NOINHERIT ) == 0 )
               DosSetFHState( hDup, ulStateErr & 0xFF00 );
         }

         hb_gt_BaseFree( pGT );
      }
      else
      {
         if( hNull != ( HFILE ) FS_ERROR )
            DosClose( hNull );
         if( ret == NO_ERROR )
            ret = ( APIRET ) FS_ERROR;
      }

      fError = ret != NO_ERROR;
      if( ! fError )
      {
         if( phStdin != NULL )
         {
            *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ];
            hPipeIn[ 1 ] = FS_ERROR;
         }
         if( phStdout != NULL )
         {
            *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ];
            hPipeOut[ 0 ] = FS_ERROR;
         }
         if( phStderr != NULL )
         {
            *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ];
            hPipeErr[ 0 ] = FS_ERROR;
         }
         if( pulPID )
            *pulPID = pid;
         hResult = ( HB_FHANDLE ) pid;
      }

      hb_fsSetError( ( HB_ERRCODE ) ret );

#elif defined( HB_OS_UNIX ) && \
      ! defined( HB_OS_VXWORKS ) && ! defined( HB_OS_SYMBIAN )

      char ** argv = hb_buildArgs( pszFileName );
      pid_t pid = fork();

      if( pid == -1 )
         fError = HB_TRUE;
      else if( pid != 0 )    /* parent process */
      {
         if( phStdin != NULL )
         {
            *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ];
            hPipeIn[ 1 ] = FS_ERROR;
         }
         if( phStdout != NULL )
         {
            *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ];
            hPipeOut[ 0 ] = FS_ERROR;
         }
         if( phStderr != NULL )
         {
            *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ];
            hPipeErr[ 0 ] = FS_ERROR;
         }
         if( pulPID )
            *pulPID = pid;
         hResult = ( HB_FHANDLE ) pid;
      }
      else                    /* child process */
      {
         if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) )
         {
            HB_FHANDLE hNull = open( "/dev/null", O_RDWR );

            if( ! phStdin )
               dup2( hNull, 0 );
            if( ! phStdout )
               dup2( hNull, 1 );
            if( ! phStderr )
               dup2( hNull, 2 );

            if( hNull != FS_ERROR )
               hb_fsClose( hNull );
         }

         if( phStdin != NULL )
         {
            dup2( hPipeIn[ 0 ], 0 );
            hb_fsClose( hPipeIn[ 1 ] );
         }
         if( phStdout != NULL )
         {
            dup2( hPipeOut[ 1 ], 1 );
            hb_fsClose( hPipeOut[ 0 ] );
         }
         if( phStderr != NULL )
         {
            dup2( hPipeErr[ 1 ], 2 );
            if( phStdout != phStderr )
               hb_fsClose( hPipeErr[ 0 ] );
         }

         /* close all non std* handles */
         {
            int iMaxFD, i;
            iMaxFD = sysconf( _SC_OPEN_MAX );
            if( iMaxFD < 3 )
               iMaxFD = 1024;
            for( i = 3; i < iMaxFD; ++i )
               hb_fsClose( i );
         }

         /* reset extended process attributes */
         if( setuid( getuid() ) == -1 ) {}
         if( setgid( getgid() ) == -1 ) {}

         /* execute command */
         {
#  if defined( __WATCOMC__ )
            execvp( argv[ 0 ], ( const char ** ) argv );
#  else
            execvp( argv[ 0 ], argv );
#  endif
            exit( -1 );
         }
      }
      hb_fsSetIOError( ! fError, 0 );

      hb_freeArgs( argv );

#elif defined( HB_OS_OS2 ) || defined( HB_OS_WIN )

      int hStdIn, hStdOut, hStdErr;
      char ** argv;
      int pid;

      hStdIn  = dup( 0 );
      hStdOut = dup( 1 );
      hStdErr = dup( 2 );

      if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) )
      {
         HB_FHANDLE hNull = open( "NUL:", O_RDWR );

         if( ! phStdin )
            dup2( hNull, 0 );
         if( ! phStdout )
            dup2( hNull, 1 );
         if( ! phStderr )
            dup2( hNull, 2 );

         if( hNull != FS_ERROR )
            close( hNull );
      }

      if( phStdin != NULL )
         dup2( hPipeIn[ 0 ], 0 );
      if( phStdout != NULL )
         dup2( hPipeOut[ 1 ], 1 );
      if( phStderr != NULL )
         dup2( hPipeErr[ 1 ], 2 );

      argv = hb_buildArgs( pszFileName );

#if defined( _MSC_VER ) || defined( __LCC__ ) || \
    defined( __XCC__ ) || defined( __POCC__ )
      pid = _spawnvp( _P_NOWAIT, argv[ 0 ], argv );
#elif defined( __MINGW32__ ) || defined( __WATCOMC__ )
      pid = spawnvp( P_NOWAIT, argv[ 0 ], ( const char * const * ) argv );
#else
      pid = spawnvp( P_NOWAIT, argv[ 0 ], ( char * const * ) argv );
#endif
      hb_freeArgs( argv );

      dup2( hStdIn,  0 );
      close( hStdIn );

      dup2( hStdOut, 1 );
      close( hStdOut );

      dup2( hStdErr, 2 );
      close( hStdErr );

      if( pid < 0 )
         fError = HB_TRUE;
      else if( pid != 0 )    /* parent process */
      {
         if( phStdin != NULL )
         {
            *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ];
            hPipeIn[ 1 ] = FS_ERROR;
         }
         if( phStdout != NULL )
         {
            *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ];
            hPipeOut[ 0 ] = FS_ERROR;
         }
         if( phStderr != NULL )
         {
            *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ];
            hPipeErr[ 0 ] = FS_ERROR;
         }
         if( pulPID )
            *pulPID = pid;
         hResult = ( HB_FHANDLE ) pid;
      }

      hb_fsSetIOError( ! fError, 0 );

#else
      int iTODO; /* TODO: for given platform */

      HB_SYMBOL_UNUSED( pszFileName );
      HB_SYMBOL_UNUSED( fDetach );
      HB_SYMBOL_UNUSED( pulPID );

      hb_fsSetError( ( HB_ERRCODE ) FS_ERROR );
#endif
   }

   errCode = hb_fsError();

   if( hPipeIn[ 0 ] != FS_ERROR )
      hb_fsClose( hPipeIn[ 0 ] );
   if( hPipeIn[ 1 ] != FS_ERROR )
      hb_fsClose( hPipeIn[ 1 ] );
   if( hPipeOut[ 0 ] != FS_ERROR )
      hb_fsClose( hPipeOut[ 0 ] );
   if( hPipeOut[ 1 ] != FS_ERROR )
      hb_fsClose( hPipeOut[ 1 ] );
   if( phStdout != phStderr )
   {
      if( hPipeErr[ 0 ] != FS_ERROR )
         hb_fsClose( hPipeErr[ 0 ] );
      if( hPipeErr[ 1 ] != FS_ERROR )
         hb_fsClose( hPipeErr[ 1 ] );
   }

   hb_fsSetError( errCode );

   return hResult;
}
Ejemplo n.º 7
0
/*
 * Marks the end of writing.  Returns ElvTrue if all is okay, or ElvFalse if
 * error.
 *
 * For UNIX, the temp file is closed, and the program is forked.
 * (Since this function is only called when willwrite, the program
 * wasn't forked when prgopen() was called.)  Returns ElvTrue if the
 * fork was successful, or ElvFalse if it failed.
 */
ELVBOOL 
prggo (void)
{
  HFILE r_pipe, w_pipe;  /* two ends of a pipe */
  SAVE_IO save_io;
  HFILE fd, tmp_fd;
  APIRET rc;

  /* If we weren't writing, then there's nothing to be done here */
  if (writefd < 0)
    {
      return ElvTrue;
    }

  /*
   * If we're using a temp file, close it for writing, then spawn
   * the program with its stdin redirected to come from the file.
   */
  if (command)
    {
      /* Close the temp file for writing. */
      close (writefd);
      writefd = -1;

      /* Make a pipe to use for reading stdout/stderr. */
      rc = DosCreatePipe (&r_pipe, &w_pipe, 4096);
      if (rc != NO_ERROR)
        {
          msg (MSG_ERROR, "can't create pipe");
          goto Error;
        }

      /* Save all of the standard I/O handles. */
      if (!SaveStdIOHandles (save_io, 
                             SAVE_STDIN | SAVE_STDOUT | SAVE_STDERR))
        {
          goto Error;
        }

      /*
       * Redirect standard file handles for the CHILD PROCESS.
       */

      /* Get stdin from the temporary file. */
      tmp_fd = open (tempfname, O_RDONLY);
      fd = 0;
      if (DosDupHandle (tmp_fd, &fd) != NO_ERROR)
        {
          goto DupError;
        }
      close(tmp_fd);

      /* Connect the write end of the pipe to stdout/stderr. */
      fd = 1;
      if (DosDupHandle (w_pipe, &fd) != NO_ERROR)
        {
          goto DupError;
        }
      fd = 2;
      if (DosDupHandle (w_pipe, &fd) != NO_ERROR)
        {
          goto DupError;
        }

      /*
       * Prevent the child process from inheriting the read end
       * of the pipe.  This will ensure that the pipe closes
       * cleanly when the parent process (elvis) is done with it.
       */
      if (DosSetFHState (r_pipe, OPEN_FLAGS_NOINHERIT) != NO_ERROR)
        {
          msg (MSG_ERROR, "can't set file inheritance");
          goto Error;
        }

      /* Launch the command. */
      if ((pid = RunCommand (command)) < 0)
        {
          msg (MSG_ERROR, "can't spawn");
          goto Error;
        }

      /* Restore standard file handles for the PARENT PROCESS. */
      RestoreStdIOHandles (save_io);

      /*
       * Close the write end of the pipe; the read end becomes 
       * 'readfd'.
       */
      DosClose (w_pipe);
      w_pipe = NULLHANDLE;
      readfd = r_pipe;

      /* We don't need the command string any more. */
      free (command);
    }
  else /* writing but not reading */
    {
      /* close the writefd */
      close (writefd);
      writefd = -1;
    }

  return ElvTrue;

DupError:
  msg (MSG_ERROR, "can't dup file handle");

Error:
  /* Restore standard I/O handles if necessary. */
  RestoreStdIOHandles (save_io);
  return ElvFalse;
}
Ejemplo n.º 8
0
/*
 * Declares which program we'll run, and what we'll be doing with it.
 * This function should return ElvTrue if successful.  If there is an error,
 * it should issue an error message via msg(), and return ElvFalse.
 *
 * For UNIX, the behavior of this function depends on willwrite.
 * If willwrite, then the command is saved and a temporary file is
 * is created to store the data that will become the program's stdin,
 * and the function succeeds if the temp file was created successfully.
 * Else the program is forked (with stdout/stderr redirected to a pipe
 * if willread) and the function succedes if pipe() and fork()
 * succeed.
 */
ELVBOOL 
prgopen (char  *cmd,    /* command string */
         ELVBOOL  willwrite,  /* if ElvTrue, redirect command's stdin */
         ELVBOOL  willread)  /* if ElvTrue, redirect command's stdout */
{
  HFILE r_pipe, w_pipe;  /* two ends of a pipe */
  SAVE_IO save_io;
  HFILE fd;
  APIRET rc;

  /* Mark both fd's as being unused */
  writefd = readfd = -1;

  /* Next step depends on what I/O we expect to do with this program */
  if (willwrite && willread)
    {
      /* save the command */
      command = strdup (cmd);

      /* create a temporary file for feeding the program's stdin */
      sprintf (tempfname, "%s/elvis%d.tmp", TMPDIR, (int)getpid ());
      writefd = open (tempfname, O_WRONLY|O_CREAT|O_EXCL, S_IREAD|S_IWRITE);
      if (writefd < 0)
        {
          msg (MSG_ERROR, "can't make temporary file");
          free (command);
          return ElvFalse;
        }
    }
  else if (willwrite || willread) /* but not both */
    {
      /* Create a pipe. */
      rc = DosCreatePipe (&r_pipe, &w_pipe, 4096);
      if (rc != NO_ERROR)
        {
          msg(MSG_ERROR, "can't create pipe");
          goto Error;
        }

      /*
       * Redirect standard file handles for the CHILD PROCESS.
       */

      if (willwrite)
        {
          /* Save the standard input handle. */
          if (!SaveStdIOHandles (save_io, SAVE_STDIN))
            goto Error;

          /* Get standard input from the read end of the pipe. */
          fd = 0;
          if (DosDupHandle (r_pipe, &fd) != NO_ERROR)
            goto DupError;

          /*
           * Prevent the child process from inheriting the write end
           * of the pipe.  This will ensure that the pipe closes
           * cleanly when the parent process (elvis) is done with it.
           */
          if (DosSetFHState (w_pipe, OPEN_FLAGS_NOINHERIT) != NO_ERROR)
            {
              msg (MSG_ERROR, "can't set file inheritance");
              goto Error;
            }
        }
      else
        {
          /* Save the standard output and error handles. */
          if (!SaveStdIOHandles (save_io, SAVE_STDOUT | SAVE_STDERR))
            {
              goto Error;
            }

          /* Send standard output to the write end of the pipe. */
          fd = 1;
          if (DosDupHandle (w_pipe, &fd) != NO_ERROR)
            {
              goto DupError;
            }

          /* Send error output to the write end of the pipe. */
          fd = 2;
          if (DosDupHandle (w_pipe, &fd) != NO_ERROR)
            {
              goto DupError;
            }
        }

      /* Launch the command. */
      if ((pid = RunCommand (cmd)) < 0)
        {
          msg (MSG_ERROR, "can't spawn");
          goto Error;
        }

      if (willwrite)
        {
          /*
           * Close the read end of the pipe and remember the fd 
           * of the write end.
           */
          DosClose (r_pipe);
          r_pipe = NULLHANDLE;
          writefd = w_pipe;
        }
      else
        {
          /*
           * Close the write end of the pipe and remember the fd 
           * of the read end.
           */
          DosClose (w_pipe);
          w_pipe = NULLHANDLE;
          readfd = r_pipe;
        }

      /* Restore standard file handles for the PARENT PROCESS. */
      RestoreStdIOHandles (save_io);
    }
  else /* no redirection */
    {
      /* Launch the command. */
      if ((pid = RunCommand (cmd)) < 0)
        {
          msg(MSG_ERROR, "can't spawn");
          goto Error;
        }
    }

  /* if we get here, we must have succeeded */
  return ElvTrue;

DupError:
  msg(MSG_ERROR, "can't dup file handle");

Error:
  /* Restore standard I/O handles if necessary. */
  RestoreStdIOHandles (save_io);
  return ElvFalse;
}
Ejemplo n.º 9
0
/**
 * Implementation of VbglR3Init and VbglR3InitUser
 */
static int vbglR3Init(const char *pszDeviceName)
{
    uint32_t cInits = ASMAtomicIncU32(&g_cInits);
    Assert(cInits > 0);
    if (cInits > 1)
    {
        /*
         * This will fail if two (or more) threads race each other calling VbglR3Init.
         * However it will work fine for single threaded or otherwise serialized
         * processed calling us more than once.
         */
#ifdef RT_OS_WINDOWS
        if (g_hFile == INVALID_HANDLE_VALUE)
#elif !defined (VBOX_VBGLR3_XSERVER)
        if (g_File == NIL_RTFILE)
#else
        if (g_File == -1)
#endif
            return VERR_INTERNAL_ERROR;
        return VINF_SUCCESS;
    }
#if defined(RT_OS_WINDOWS)
    if (g_hFile != INVALID_HANDLE_VALUE)
#elif !defined(VBOX_VBGLR3_XSERVER)
    if (g_File != NIL_RTFILE)
#else
    if (g_File != -1)
#endif
        return VERR_INTERNAL_ERROR;

#if defined(RT_OS_WINDOWS)
    /*
     * Have to use CreateFile here as we want to specify FILE_FLAG_OVERLAPPED
     * and possible some other bits not available thru iprt/file.h.
     */
    HANDLE hFile = CreateFile(pszDeviceName,
                              GENERIC_READ | GENERIC_WRITE,
                              FILE_SHARE_READ | FILE_SHARE_WRITE,
                              NULL,
                              OPEN_EXISTING,
                              FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
                              NULL);

    if (hFile == INVALID_HANDLE_VALUE)
        return VERR_OPEN_FAILED;
    g_hFile = hFile;

#elif defined(RT_OS_OS2)
    /*
     * We might wish to compile this with Watcom, so stick to
     * the OS/2 APIs all the way. And in any case we have to use
     * DosDevIOCtl for the requests, why not use Dos* for everything.
     */
    HFILE hf = NULLHANDLE;
    ULONG ulAction = 0;
    APIRET rc = DosOpen((PCSZ)pszDeviceName, &hf, &ulAction, 0, FILE_NORMAL,
                        OPEN_ACTION_OPEN_IF_EXISTS,
                        OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE,
                        NULL);
    if (rc)
        return RTErrConvertFromOS2(rc);

    if (hf < 16)
    {
        HFILE ahfs[16];
        unsigned i;
        for (i = 0; i < RT_ELEMENTS(ahfs); i++)
        {
            ahfs[i] = 0xffffffff;
            rc = DosDupHandle(hf, &ahfs[i]);
            if (rc)
                break;
        }

        if (i-- > 1)
        {
            ULONG fulState = 0;
            rc = DosQueryFHState(ahfs[i], &fulState);
            if (!rc)
            {
                fulState |= OPEN_FLAGS_NOINHERIT;
                fulState &= OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT; /* Turn off non-participating bits. */
                rc = DosSetFHState(ahfs[i], fulState);
            }
            if (!rc)
            {
                rc = DosClose(hf);
                AssertMsg(!rc, ("%ld\n", rc));
                hf = ahfs[i];
            }
            else
                i++;
            while (i-- > 0)
                DosClose(ahfs[i]);
        }
    }
    g_File = (RTFILE)hf;

#elif defined(RT_OS_DARWIN)
    /*
     * Darwin is kind of special we need to engage the device via I/O first
     * before we open it via the BSD device node.
     */
    mach_port_t MasterPort;
    kern_return_t kr = IOMasterPort(MACH_PORT_NULL, &MasterPort);
    if (kr != kIOReturnSuccess)
        return VERR_GENERAL_FAILURE;

    CFDictionaryRef ClassToMatch = IOServiceMatching("org_virtualbox_VBoxGuest");
    if (!ClassToMatch)
        return VERR_GENERAL_FAILURE;

    io_service_t ServiceObject = IOServiceGetMatchingService(kIOMasterPortDefault, ClassToMatch);
    if (!ServiceObject)
        return VERR_NOT_FOUND;

    io_connect_t uConnection;
    kr = IOServiceOpen(ServiceObject, mach_task_self(), VBOXGUEST_DARWIN_IOSERVICE_COOKIE, &uConnection);
    IOObjectRelease(ServiceObject);
    if (kr != kIOReturnSuccess)
        return VERR_OPEN_FAILED;

    RTFILE hFile;
    int rc = RTFileOpen(&hFile, pszDeviceName, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    if (RT_FAILURE(rc))
    {
        IOServiceClose(uConnection);
        return rc;
    }
    g_File = hFile;
    g_uConnection = uConnection;

#elif defined(VBOX_VBGLR3_XSERVER)
    int File = xf86open(pszDeviceName, XF86_O_RDWR);
    if (File == -1)
        return VERR_OPEN_FAILED;
    g_File = File;

#else

    /* The default implementation. (linux, solaris, freebsd, haiku) */
    RTFILE File;
    int rc = RTFileOpen(&File, pszDeviceName, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    if (RT_FAILURE(rc))
        return rc;
    g_File = File;

#endif

#ifndef VBOX_VBGLR3_XSERVER
    /*
     * Create release logger
     */
    PRTLOGGER pReleaseLogger;
    static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
    int rc2 = RTLogCreate(&pReleaseLogger, 0, "all", "VBOX_RELEASE_LOG",
                          RT_ELEMENTS(s_apszGroups), &s_apszGroups[0], RTLOGDEST_USER, NULL);
    /* This may legitimately fail if we are using the mini-runtime. */
    if (RT_SUCCESS(rc2))
        RTLogRelSetDefaultInstance(pReleaseLogger);
#endif

    return VINF_SUCCESS;
}