This is the new state of the function, I'm not expecting there to be issues but posting it on the off chance I overlooked something.
Code:
PAW_SHARED struct paw_app* paw_boot_app( void *ud, char const * const path, char *argv[], char *envp[] )
{
#ifdef PAW_WIN32
struct paw_app *app;
char *cmd, *dir, *tok = NULL;
PROCESS_INFORMATION pi = {NULL};
int created = 0;
size_t size = strlen( path ) + 1, want = size * 2, done = 0;
for ( int i = 0; argv[i]; ++i )
want += strlen(argv[i]) + 2;
dir = paw.alloc( ud, NULL, 0, want );
if ( !dir )
return NULL;
cmd = dir + size;
memset( dir, 0, want );
for ( int i = 0; argv[i]; ++i )
{
char *arg = cmd + done;
size_t len = strlen(argv[i]);
memcpy( arg, argv[i], len );
arg[len] = ' ';
done += len + 1;
}
cmd[done-1] = 0;
created = CreateProcess(
path, cmd, NULL, NULL, FALSE, 0, (void*)envp, dir, NULL, &pi );
paw.alloc( ud, dir, want, 0 );
app = created ? paw_load_app( ud, pi.dwProcessId ) : NULL;
if ( app )
{
app->hook = pi.hProcess;
app->tracing = true;
}
return app;
#else
int pid = fork();
if ( pid == 0 )
(void)execve( path, argv, envp );
/* According to docs the new app will take over the pid and replace
* our address space with it's own as it initiates, we therefore
* should assume that if execve returned we failed to launch the app,
* either way we do not want the child to return a valid object for
* itself or the root system process which is probably the kernel and
* not what any normal user will want to use, anyone that does want to
* use it will not use such a convoluded method as going through this
* function unless they just want to see what happens, in which case
* they will have downloaded the project, modified it and compiled that
* copy instead */
else if ( pid > 0 )
/* Instead of duplicating code let's just pass the pid to one that
* assumes it already exists */
return paw_load_app( ud, pid );
return NULL;
#endif
}
Edit: Minor modification to the win32 code:
Code:
...
dir = paw.alloc( ud, NULL, 0, want );
if ( !dir )
return NULL;
memset( dir, 0, want );
memcpy( dir, path, size - 1 );
PathRemoveFileSpecA( dir );
cmd = dir + size;
...