Created
October 14, 2012 03:52
-
-
Save numinit/3887202 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if defined(MACOS) | |
#define HAVE_STRUCT_TIMESPEC 1 | |
#include <mach-o/dyld.h> | |
#include <libgen.h> | |
#elif defined(LINUX) | |
#elif defined(WINDOWS) | |
#endif | |
#include <stdio.h> | |
#include <locale.h> | |
#include <pthread.h> | |
#include <unistd.h> | |
#include <ruby.h> | |
#if defined(MACOS) || defined(LINUX) | |
#define SEPARATOR "/" | |
#elif defined(WINDOWS) | |
#define SEPARATOR "\\" | |
#endif | |
struct args_t { | |
int argc; | |
char **argv; | |
}; | |
struct ret_t { | |
int value; | |
}; | |
struct ret_t *rl_start_interpreter(struct args_t *args) { | |
struct ret_t *ret = (struct ret_t *)malloc(sizeof(struct ret_t)); | |
static const char bootstrap[] = "boot.rb"; | |
// This is the interpreter thread. | |
pthread_setname_np("ruby_loader.interpreter"); | |
// Find the relative path of the script - should be in the same folder as the executable | |
char path[1024]; | |
#if defined(MACOS) | |
_NSGetExecutablePath((char *)&path, &(uint32_t[]){sizeof(path)}[0]); | |
#elif defined(LINUX) | |
#elif defined(WIN32) | |
#endif | |
// Grab the directory name | |
char *boot = dirname((char *)&path); | |
// Reallocate memory to hold the bootstrap path | |
boot = realloc(boot, strlen(boot) + sizeof(bootstrap) + 2); | |
strcat(boot, SEPARATOR); | |
strcat(boot, (const char *)&bootstrap); | |
/** Start the Ruby interpreter **/ | |
ruby_init(); | |
/** AT THIS POINT, THE RUBY INTERPRETER IS RUNNING! **/ | |
ruby_init_loadpath(); | |
ruby_set_argv(args->argc, args->argv); | |
ruby_script((const char *)bootstrap); | |
/** We're ready. Call the bootstrap code. **/ | |
rb_load_protect(rb_str_new_cstr((const char *)boot), Qfalse, &ret->value); | |
/** Cave Johnson. We're done here. **/ | |
ruby_finalize(); | |
/** Free memory **/ | |
free(boot); | |
return ret; | |
} | |
int main(int argc, char **argv) { | |
/** Allocate memory to hold command-line argument pointer **/ | |
struct args_t *args = (struct args_t *)malloc(sizeof(struct args_t)); | |
/** Values that will be returned back to us **/ | |
struct ret_t *ret = NULL; | |
int r; | |
/** Thread attributes **/ | |
pthread_attr_t attr; | |
pthread_t interpreter; | |
args->argc = argc; | |
args->argv = argv; | |
// This is the main thread. | |
pthread_setname_np("ruby_loader.main"); | |
// Spawn the interpreter thread | |
pthread_attr_init(&attr); | |
pthread_create(&interpreter, &attr, (void *(*)(void *))rl_start_interpreter, args); | |
pthread_attr_destroy(&attr); | |
// Join the interpreter thread. Wait for it to exit. | |
pthread_join(interpreter, (void **)&ret); | |
r = ret->value; | |
free(args); | |
free(ret); | |
return r; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment