Thread: Launching programmes in Win32 & Linux/Unix/Posix

  1. #1
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733

    Launching programmes in Win32 & Linux/Unix/Posix

    I've got this:
    Code:
    PAW_SHARED struct paw_app* paw_boot_app( void *ud, char const * const path, char *argv[], char *envp[] )
    {
    #ifdef PAW_WIN32
    	/* Not supported yet */
    	return NULL;
    #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
    }
    But I'm struggling to find the right way to do it on Win32, also is this the correct way for linux etc?

  2. #2
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Windows has CreateProcess() function on Win32 API.

  3. #3
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by flp1969 View Post
    Windows has CreateProcess() function on Win32 API.
    ty

  4. #4
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    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;
    	...

  5. #5
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Sooner or later I'm gonna have to get round to checking for the death of traced & potentially hooked processes, what would be the suggestions for when I get to that point for both systems

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. creating POSIX threads in UNIX
    By v3dant in forum C++ Programming
    Replies: 7
    Last Post: 09-22-2004, 05:07 PM
  2. UNIX (Linux, BSD, etc) Programming :: UNIX
    By kuphryn in forum Linux Programming
    Replies: 6
    Last Post: 04-01-2004, 08:44 PM
  3. pthreads-win32 POSIX threads
    By c99 in forum C Programming
    Replies: 4
    Last Post: 02-24-2004, 06:59 PM
  4. compile prob: sched.h (win32 POSIX threads) - pid_t
    By BrianK in forum Windows Programming
    Replies: 6
    Last Post: 04-11-2003, 05:52 PM
  5. Linux and POSIX.
    By adrianxw in forum Linux Programming
    Replies: 2
    Last Post: 02-25-2002, 10:34 AM

Tags for this Thread