예제 #1
0
// We extract the list of open modules for a process by parsing out the
//   /proc/<pid>/maps
// File. This lists all the files mapped into the processes memory space.
bool MCSystemListProcessModules(uint32_t p_process_id, MCSystemListProcessModulesCallback p_callback, void *p_context)
{
	char t_maps_file[6 + I4L + 5 + 1];
	sprintf(t_maps_file, "/proc/%u/maps", p_process_id);

	FILE *t_stream;
	t_stream = fopen(t_maps_file, "r");
	if (t_stream == nil)
		return false;

	bool t_success;
	t_success = true;

	// Each line is of a fixed format, with any module path appearing at '/'.
	// Modules are repeated in the map for each segment that is mapped in. Thus
	// we only report the first appearance, and assume that they are always
	// consecutive.
	char t_last_module[4096];
	t_last_module[0] = '\0';
	while(t_success)
	{
		char t_line[4096];
		if (fgets(t_line, 4096, t_stream) == nil)
			break;

		// See if there is a module path
		char *t_path;
		t_path = strchr(t_line, '/');
		if (t_path == nil)
			continue;

		// See if it is a shared library (terminated by .so, or containing .so.)
		if (!MCCStringEndsWith(t_path, ".so") ||
			!MCCStringContains(t_path, ".so.") ||
			MCCStringEqual(t_path, t_last_module))
			continue;

		MCAutoStringRef t_path_str;
        /* UNCHECKED */ MCStringCreateWithSysString(t_path, &t_path_str);

		t_success = p_callback(p_context, *t_path_str);
	}

	fclose(t_stream);

	return t_success;
}
예제 #2
0
int platform_main(int argc, char *argv[], char *envp[])
{
	// On Linux, the argv and envp could be in pretty much any format. The
	// safest thing to do is let the C library's iconv convert to a known
	// format. To do this, the system locale needs to be retrieved.
	setlocale(LC_ALL, "");
	MCsysencoding = strclone(nl_langinfo(CODESET));
		
	if (!MCInitialize())
	{
		fprintf(stderr, "Fatal: initialization failed\n");
		exit(-1);
	}
	
	if (!MCSInitialize())
	{
		fprintf(stderr, "Fatal: platform initialization failed\n");
		exit(-1);
	}
	
	if (!MCScriptInitialize())
	{
		fprintf(stderr, "Fatal: script initialization failed\n");
		exit(-1);
	}
	
	// Linux needs the platform layer to be initialised early so that it can
	// use it to load the weakly-linked dynamic libraries that the engine
	// depends on.
	MCS_preinit();
		
	// Core initialisation complete; 
	// This depends on libFoundation and MCsystem being initialised first
	initialise_required_weak_link_glib();
	
	// Convert the argv array to StringRefs
    MCAutoStringRefArray t_argv;
    /* UNCHECKED */ t_argv.New(argc);
	for (int i = 0; i < argc; i++)
	{
        /* UNCHECKED */ MCStringCreateWithSysString(argv[i], t_argv[i]);
	}
	
	// Convert the envp array to StringRefs
    int envc = 0;
    while (envp[envc] != nullptr)
        ++envc;
    MCAutoStringRefArray t_envp;
    /* UNCHECKED */ t_envp.New(envc + 1);
    for (int i = 0; envp[i] != nullptr; ++i)
    {
        /* UNCHECKED */ MCStringCreateWithSysString(envp[i], t_envp[i]);
    }

	// Terminate the envp array
	t_envp[envc] = nil;
	
	extern int MCSystemElevatedMain(int, char* argv[]);
	if (argc == 3&& strcmp(argv[1], "-elevated-slave") == 0)
		return MCSystemElevatedMain(argc, argv);
	
    struct X_init_options t_options;
    t_options.argc = argc;
    t_options.argv = *t_argv;
    t_options.envp = *t_envp;
    t_options.app_code_path = nullptr;
	if (!X_init(t_options))
    {
		// Try to print an informative error message or, failing that, just
		// report that an error occurred.
		if (MCresult != nil)
        {
            MCExecContext ctxt(nil, nil, nil);
            MCAutoValueRef t_result;
            MCAutoStringRef t_string;
            MCresult -> eval(ctxt, &t_result);
            ctxt . ConvertToString(*t_result, &t_string);
            MCAutoStringRefAsSysString t_autostring;
            /* UNCHECKED */ t_autostring . Lock(*t_string);
            fprintf(stderr, "Startup error - %s\n", *t_autostring);
		}
		else
		{
			fprintf(stderr, "Fatal: unknown startup error\n");
		}
		
		exit(-1);
	}
	
	X_main_loop();
	
	int t_exit_code = X_close();

	MCScriptFinalize();
	MCFinalize();

	exit(t_exit_code);
}
예제 #3
0
// This call is primarily designed to be used by the plugin installer. As this
// is generally installed 'per-user', we simply scan '/proc' for processes owned
// by the calling user.
bool MCSystemListProcesses(MCSystemListProcessesCallback p_callback, void* p_context)
{
	bool t_success;
	t_success = true;

	DIR *t_dir;
	t_dir = nil;
	if (t_success)
	{
		t_dir = opendir("/proc");
		if (t_dir == nil)
			t_success = false;
	}

	if (t_success)
	{
		dirent *t_entry;
		while(t_success)
		{
			// Fetch the next entry
			t_entry = readdir(t_dir);
			if (t_entry == nil)
				break;

			// Work out if the entry is a process id
			int32_t t_pid;
            MCAutoStringRef t_dname;
            /* UNCHECKED */ MCStringCreateWithCString(t_entry -> d_name, &t_dname);
			if (!MCU_strtol(*t_dname, t_pid))
				continue;

			// Work out the full path ("/proc/<int>") and stat so we can
			// check ownership.
			char t_path[6 + I4L + 1];
			struct stat64 t_stat;
			sprintf(t_path, "/proc/%u", t_pid);
			stat64(t_path, &t_stat);
			if (t_stat . st_uid != getuid())
				continue;

			// We have a viable process to report. First fetch its path
            MCAutoStringRef t_exe_link, t_exe_path;
            /* UNCHECKED */ MCStringFormat(&t_exe_link, "/proc/%u/exe", t_pid);
			if (!MCS_resolvepath(*t_exe_link, &t_exe_path))
			{
				t_success = false;
				break;
			}

			// Next fetch its 'description' from the first line of the status
			// file.
			char t_status_file[6 + I4L + 7 + 1];
			char t_status[256];
			FILE *t_stream;
			sprintf(t_status_file, "/proc/%u/status", t_pid);
			t_stream = fopen(t_status_file, "r");
			if (t_stream != nil)
			{
				if (fgets(t_status, 256, t_stream) != nil)
				{
					char *t_tab;
					t_tab = strchr(t_status, '\t');
					if (t_tab != nil)
						MCMemoryMove(t_status, t_tab + 1, MCCStringLength(t_tab + 1));
				}
				else
					t_status[0] = '\0';
				fclose(t_stream);
			}
			else
				t_status[0] = '\0';

            MCAutoStringRef t_status_str;
            /* UNCHECKED */ MCStringCreateWithSysString(t_status, &t_status_str);
			t_success = p_callback(p_context, t_pid, *t_exe_path, *t_status_str);
		}
	}

	if (t_dir != nil)
		closedir(t_dir);

	return t_success;
}