示例#1
0
/*:::::*/
FBCALL void *fb_DylibLoad( FBSTRING *library )
{
	void *res = NULL;
	int i;
	char libname[MAX_PATH];
	char *libnameformat[] = { "%s",
							  "lib%s",
							  "lib%s.so",
							  "./%s",
							  "./lib%s",
							  "./lib%s.so",
							  NULL };

	// Just in case the shared lib is an FB one, temporarily reset the
	// terminal, to let the 2nd rtlib capture the original terminal state.
	// That way both rtlibs can restore the terminal properly on exit.
	// Note: The shared lib rtlib exits *after* the program rtlib, in case
	// the user forgot to dylibfree().
	fb_hExitConsole();

	libname[MAX_PATH-1] = '\0';
	if( (library) && (library->data) ) {
		for( i = 0; libnameformat[i]; i++ ) {
			snprintf( libname, MAX_PATH-1, libnameformat[i], library->data );
			fb_hConvertPath( libname );
			res = dlopen( libname, RTLD_LAZY );
			if( res )
				break;
		}
	}

	/* del if temp */
	fb_hStrDelTemp( library );

	fb_hInitConsole();

	return res;
}
示例#2
0
/*:::::*/
FBCALL int fb_ExecEx ( FBSTRING *program, FBSTRING *args, int do_fork )
{
	char buffer[MAX_PATH+1], *application, *arguments, **argv, *p;
	int i, argc = 0, res = -1, status, len_program, len_arguments;
	pid_t pid;

	if( (program == NULL) || (program->data == NULL) ) 
	{
		fb_hStrDelTemp( args );
		fb_hStrDelTemp( program );
		return -1;
	}

	application = fb_hGetShortPath( program->data, buffer, MAX_PATH );
	DBG_ASSERT( application!=NULL );
	if( application==program->data ) 
	{
		len_program = FB_STRSIZE( program );
		application = buffer;
		FB_MEMCPY(application, program->data, len_program );
		application[len_program] = 0;
	}

	fb_hConvertPath( application );

	if( args==NULL ) 
	{
		arguments = "";
	} 
	else 
	{
		len_arguments = FB_STRSIZE( args );
		arguments = alloca( len_arguments + 1 );
		DBG_ASSERT( arguments!=NULL );
		arguments[len_arguments] = 0;
		if( len_arguments )
			argc = fb_hParseArgs( arguments, args->data, len_arguments );

	}

	FB_STRLOCK();

	fb_hStrDelTemp_NoLock( args );
	fb_hStrDelTemp_NoLock( program );

	FB_STRUNLOCK();

	if( argc == -1 )
		return -1;

	argc++; 			/* add 1 for program name */

	argv = alloca( sizeof(char*) * (argc + 1 ));
	DBG_ASSERT( argv!=NULL );

	argv[0] = application;

	/* scan the processed args and set pointers */
	p = arguments;
	for( i=1 ; i<argc; i++) {
		argv[i] = p;	/* set pointer to current argument */
		while( *p++ );	/* skip to 1 char past next null char */
	}
	argv[argc] = NULL;


	/* Launch */
	fb_hExitConsole();

	if( do_fork ) {
		pid = fork();
		if( pid != -1 ) {
			if (pid == 0) {
				/* execvp() only returns if it failed */
				execvp( application, argv );
				/* HACK: execvp() failed, this must be communiated to the parent process *somehow*,
				   so fb_ExecEx() can return -1 there */
				exit( 255 );
				/* FIXME: won't be able to tell the difference if the exec'ed program returned 255.
				   Maybe a pipe could be used instead of the 255 exit code? Unless that's too slow/has side-effects */
			} else if( (waitpid(pid, &status, 0) > 0) && WIFEXITED(status) ) {
				res = WEXITSTATUS(status);
				if( res == 255 ) {
					/* See the HACK above */
					res = -1;
				}
			}
		}
	} else {
		res = execvp( application, argv );
	}

	fb_hInitConsole();

	return res;
}
示例#3
0
int fb_DevFileOpenEncod
	(
		FB_FILE *handle,
		const char *filename,
		size_t fname_len
	)
{
    FILE *fp = NULL;
    char *openmask;
    char *fname;

    FB_LOCK();

    fname = (char*) alloca(fname_len + 1);
    memcpy(fname, filename, fname_len);
    fname[fname_len] = 0;

    /* Convert directory separators to whatever the current platform supports */
    fb_hConvertPath( fname );

    handle->hooks = &hooks_dev_file;

    openmask = NULL;
    switch( handle->mode )
    {
    case FB_FILE_MODE_APPEND:
        /* will create the file if it doesn't exist */
        openmask = "ab";
        break;

    case FB_FILE_MODE_INPUT:
        /* will fail if file doesn't exist */
        openmask = "rb";
        break;

    case FB_FILE_MODE_OUTPUT:
        /* will create the file if it doesn't exist */
        openmask = "wb";
        break;

    default:
        FB_UNLOCK();
        return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL );
    }

    /* try opening */
    if( (fp = fopen( fname, openmask )) == NULL )
    {
    	FB_UNLOCK();
        return fb_ErrorSetNum( FB_RTERROR_FILENOTFOUND );
    }

    fb_hSetFileBufSize( fp );

    handle->opaque = fp;

    if ( handle->access == FB_FILE_ACCESS_ANY)
        handle->access = FB_FILE_ACCESS_READWRITE;

    /* handle BOM */
    switch( handle->mode )
    {
    case FB_FILE_MODE_APPEND:
    case FB_FILE_MODE_INPUT:
        if( !hCheckBOM( handle ) )
        {
    		fclose( fp );
    		FB_UNLOCK();
        	return fb_ErrorSetNum( FB_RTERROR_FILENOTFOUND );
        }

        break;

    case FB_FILE_MODE_OUTPUT:
        if( !hWriteBOM( handle ) )
        {
    		fclose( fp );
    		FB_UNLOCK();
        	return fb_ErrorSetNum( FB_RTERROR_FILENOTFOUND );
        }
	}

	/* calc file size */
    handle->size = fb_DevFileGetSize( fp, handle->mode, handle->encod, TRUE );
    if( handle->size == -1 )
    {
    	fclose( fp );
        FB_UNLOCK();
        return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL );
	}

    FB_UNLOCK();

	return fb_ErrorSetNum( FB_RTERROR_OK );
}