Skip to content

Instantly share code, notes, and snippets.

@patrickt
Created May 27, 2009 15:30
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 patrickt/118697 to your computer and use it in GitHub Desktop.
Save patrickt/118697 to your computer and use it in GitHub Desktop.
VALUE
io_from_spawning_new_process(VALUE prog, VALUE mode)
{
// Allocate space for a new IO struct.
VALUE io = io_alloc(rb_cIO, 0);
rb_io_t *io_struct = ExtractIOStruct(io);
io_struct->readStream = NULL;
io_struct->writeStream = NULL;
posix_spawn_file_actions_t actions;
// Streams for reading and writing.
CFReadStreamRef r;
CFWriteStreamRef w;
// Required variables for pipe() and posix_spawn().
pid_t pid;
int comms[2] = {};
socketpair(PF_LOCAL, SOCK_STREAM, 0, comms);
posix_spawn_file_actions_init(&actions);
posix_spawn_file_actions_adddup2(&actions, comms[1], STDOUT_FILENO);
posix_spawn_file_actions_adddup2(&actions, STDOUT_FILENO, STDERR_FILENO);
posix_spawn_file_actions_addclose(&actions, comms[0]);
posix_spawn_file_actions_addclose(&actions, comms[1]);
char *spawnedArgs[] = {(char*)_PATH_BSHELL, "-c", (char*)RSTRING_PTR(prog), NULL};
int error = posix_spawn(&pid, spawnedArgs[0], &actions, NULL, spawnedArgs, *(_NSGetEnviron()));
if (error != 0) {
close(comms[0]);
close(comms[1]);
rb_bug("posix_spawn failed.");
}
else {
if (convert_mode_string_to_fmode(mode) != FMODE_WRITABLE) {
r = _CFReadStreamCreateFromFileDescriptor(NULL, comms[0]);
if (r != NULL) {
CFReadStreamOpen(r);
CFMakeCollectable(r);
GC_WB(&io_struct->readStream, r);
}
}
if (convert_mode_string_to_fmode(mode) != FMODE_READABLE) {
w = _CFWriteStreamCreateFromFileDescriptor(NULL, comms[1]);
if (w != NULL) {
CFWriteStreamOpen(w);
CFMakeCollectable(w);
GC_WB(&io_struct->writeStream, w);
}
}
io_struct->fd = comms[0];
io_struct->pid = pid;
io_struct->ungetc_buf = NULL;
io_struct->ungetc_buf_len = 0;
io_struct->ungetc_buf_pos = 0;
posix_spawn_file_actions_destroy(&actions);
}
return io;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment