Skip to content

Instantly share code, notes, and snippets.

@numinit
Created October 14, 2012 03:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save numinit/3887202 to your computer and use it in GitHub Desktop.
Save numinit/3887202 to your computer and use it in GitHub Desktop.
#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