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, **argv, *p;
8  int i, argc = 0, res = 0;
9  ssize_t len_program, len_arguments;
10 
11  if( (program == NULL) || (program->data == NULL) )
12  {
13  fb_hStrDelTemp( args );
14  fb_hStrDelTemp( program );
15  return -1;
16  }
17 
18  application = fb_hGetShortPath( program->data, buffer, MAX_PATH );
19  DBG_ASSERT( application!=NULL );
20  if( application==program->data )
21  {
22  len_program = FB_STRSIZE( program );
23  application = buffer;
24  FB_MEMCPY(application, program->data, len_program );
25  application[len_program] = 0;
26  }
27 
28  if( args==NULL ) {
29  arguments = "";
30  } else {
31  len_arguments = FB_STRSIZE( args );
32  arguments = alloca( len_arguments + 1 );
33  DBG_ASSERT( arguments!=NULL );
34  arguments[len_arguments] = 0;
35  if( len_arguments )
36  argc = fb_hParseArgs( arguments, args->data, len_arguments );
37  }
38 
39  FB_STRLOCK();
40 
41  fb_hStrDelTemp_NoLock( args );
42  fb_hStrDelTemp_NoLock( program );
43 
44  FB_STRUNLOCK();
45 
46  if( argc == -1 )
47  return -1;
48 
49  argc++; /* add 1 for program name */
50 
51  argv = alloca( sizeof(char*) * (argc + 1 ));
52  DBG_ASSERT( argv!=NULL );
53 
54  argv[0] = buffer;
55 
56  /* scan the processed args and set pointers */
57  p = arguments;
58  for( i=1 ; i<argc; i++)
59  {
60  argv[i] = p; /* set pointer to current argument */
61  while( *p++ ); /* skip to 1 char past next null char */
62  }
63  argv[argc] = NULL;
64 
65  /* NOTE: DJGPP info on 3rd arg of spawnv* functions is inconsistent;
66  in docs, defined as const char **;
67  in process.h, defined as char *const _argv[]
68  */
69 
70  if( do_fork )
71  res = spawnv( P_WAIT, (const char*)application, (char * const *)argv );
72  else
73  res = execv( (const char*)application, (char * const *)argv );
74 
75  return res;
76 }