X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/d15b59f5d4f43d12719c5ce37518246058b405c6..1504c9b837a7561d8ae2c81f1c4d57fe0f138781:/Handler.mm?ds=sidebyside diff --git a/Handler.mm b/Handler.mm index 39825fa..01c3cbc 100644 --- a/Handler.mm +++ b/Handler.mm @@ -38,6 +38,7 @@ /* }}} */ #include "cycript.hpp" +#include "JavaScript.hpp" #include "Pooling.hpp" #include "Parser.hpp" @@ -49,6 +50,11 @@ #include #include +#include +#include +#include +#include + struct CYExecute_ { apr_pool_t *pool_; const char * volatile data_; @@ -68,7 +74,7 @@ struct CYExecute_ { CYExecute_ *execute(reinterpret_cast([value pointerValue])); const char *data(execute->data_); execute->data_ = NULL; - execute->data_ = CYExecute(execute->pool_, data); + execute->data_ = CYExecute(execute->pool_, CYUTF8String(data)); } @end @@ -89,8 +95,16 @@ struct CYClient : } void Handle() { - CYClient_ *client = [[CYClient_ alloc] init]; - @try { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + CYClient_ *client = [[[CYClient_ alloc] init] autorelease]; + + bool dispatch; + if (CFStringRef mode = CFRunLoopCopyCurrentMode(CFRunLoopGetMain())) { + dispatch = true; + CFRelease(mode); + } else + dispatch = false; for (;;) { size_t size; @@ -103,7 +117,7 @@ struct CYClient : return; data[size] = '\0'; - CYDriver driver(""); + CYDriver driver; cy::parser parser(driver); driver.data_ = data; @@ -114,16 +128,25 @@ struct CYClient : json = NULL; size = _not(size_t); } else { - CYContext context(driver.pool_); + NSAutoreleasePool *ar = [[NSAutoreleasePool alloc] init]; + + CYOptions options; + CYContext context(driver.pool_, options); driver.program_->Replace(context); std::ostringstream str; - CYOutput out(str); + CYOutput out(str, options); out << *driver.program_; std::string code(str.str()); CYExecute_ execute = {pool, code.c_str()}; - [client performSelectorOnMainThread:@selector(execute:) withObject:[NSValue valueWithPointer:&execute] waitUntilDone:YES]; + NSValue *value([NSValue valueWithPointer:&execute]); + if (dispatch) + [client performSelectorOnMainThread:@selector(execute:) withObject:value waitUntilDone:YES]; + else + [client execute:value]; json = execute.data_; size = json == NULL ? _not(size_t) : strlen(json); + + [ar release]; } if (!CYSendAll(socket_, &size, sizeof(size))) @@ -133,9 +156,7 @@ struct CYClient : return; } - } @finally { - [client release]; - } + [pool release]; } }; @@ -152,3 +173,24 @@ extern "C" void CYHandleClient(apr_pool_t *pool, int socket) { _aprcall(apr_threadattr_create(&attr, client->pool_)); _aprcall(apr_thread_create(&client->thread_, attr, &OnClient, client, client->pool_)); } + +extern "C" void CYHandleServer(pid_t pid) { + CYInitializeDynamic(); + + int socket(_syscall(::socket(PF_UNIX, SOCK_STREAM, 0))); try { + struct sockaddr_un address; + memset(&address, 0, sizeof(address)); + address.sun_family = AF_UNIX; + sprintf(address.sun_path, "/tmp/.s.cy.%u", pid); + + _syscall(connect(socket, reinterpret_cast(&address), SUN_LEN(&address))); + + apr_pool_t *pool; + apr_pool_create(&pool, NULL); + + CYHandleClient(pool, socket); + } catch (const CYException &error) { + CYPool pool; + fprintf(stderr, "%s\n", error.PoolCString(pool)); + } +}