FreeBASIC  0.91.0
sys_execex.c
Go to the documentation of this file.
1 #include "../fb.h"
2 #include "fb_private_console.h"
3 #include <process.h>
4 
5 FBCALL int fb_ExecEx( FBSTRING *program, FBSTRING *args, int do_fork )
6 {
7  char buffer[MAX_PATH+1], *application, *arguments;
8  int res = 0, got_program;
9  size_t len_arguments;
10 #ifndef HOST_MINGW
11  size_t len_program;
12 #endif
13 
14  got_program = (program != NULL) && (program->data != NULL);
15 
16  if( !got_program ) {
17  fb_hStrDelTemp( args );
18  fb_hStrDelTemp( program );
19  return -1;
20  }
21 
22  application = fb_hGetShortPath( program->data, buffer, MAX_PATH );
23  DBG_ASSERT( application!=NULL );
24  if( application==program->data ) {
25  application = buffer;
26  FB_MEMCPY(application, program->data, FB_STRSIZE( program ) );
27  }
28 
29 #ifdef HOST_MINGW
30  if( args==NULL ) {
31  arguments = "";
32  } else {
33  len_arguments = FB_STRSIZE( args );
34  arguments = alloca( len_arguments + 1 );
35  DBG_ASSERT( arguments!=NULL );
36  if( len_arguments )
37  FB_MEMCPY( arguments, args->data, len_arguments );
38  arguments[len_arguments] = 0;
39  }
40 #else
41  len_program = strlen( buffer );
42  len_arguments = ( ( args==NULL ) ? 0 : FB_STRSIZE( args ) );
43 
44  arguments = alloca( len_program + len_arguments + 2 );
45  DBG_ASSERT( arguments!=NULL );
46 
47  FB_MEMCPY( arguments, buffer, len_program );
48  arguments[len_program] = ' ';
49  if( len_arguments!=0 )
50  FB_MEMCPY( arguments + len_program + 1, args->data, len_arguments );
51  arguments[len_program + len_arguments + 1] = 0;
52 #endif
53 
54  FB_STRLOCK();
55 
56  fb_hStrDelTemp_NoLock( args );
57  fb_hStrDelTemp_NoLock( program );
58 
59  FB_STRUNLOCK();
60 
62 
63  {
64 #ifdef HOST_MINGW
65  if( do_fork )
66  res = _spawnl( _P_WAIT, buffer, buffer, arguments, NULL );
67  else
68  res = _execl( buffer, buffer, arguments, NULL );
69 #else
70  STARTUPINFO StartupInfo;
71  PROCESS_INFORMATION ProcessInfo;
72  memset( &StartupInfo, 0, sizeof(StartupInfo) );
73  StartupInfo.cb = sizeof(StartupInfo);
74 
75  if( !CreateProcess( NULL, /* application name - correct! */
76  arguments, /* command line */
77  NULL, NULL, /* default security descriptors */
78  FALSE, /* don't inherit handles */
79  CREATE_DEFAULT_ERROR_MODE, /* do we really need this? */
80  NULL, /* default environment */
81  NULL, /* current directory */
82  &StartupInfo,
83  &ProcessInfo ) )
84  {
85  res = -1;
86  } else {
87  /* Release main thread handle - we're not interested in it */
88  CloseHandle( ProcessInfo.hThread );
89  if( do_fork ) {
90  DWORD dwExitCode;
91  WaitForSingleObject( ProcessInfo.hProcess,
92  INFINITE );
93  if( !GetExitCodeProcess( ProcessInfo.hProcess, &dwExitCode ) ) {
94  res = -1;
95  } else {
96  res = (int) dwExitCode;
97  }
98  CloseHandle( ProcessInfo.hProcess );
99  } else {
100  res = (int) ProcessInfo.hProcess;
101  }
102  }
103 #endif
104  }
105 
106  return res;
107 }