X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/69caa5be0e7aa4b274a98640d7b5f3334ec4894d..be36c292cf875904599e45d49e4f8b2f8b4e9ca6:/Console.cpp diff --git a/Console.cpp b/Console.cpp index ef3de63..b6bcedf 100644 --- a/Console.cpp +++ b/Console.cpp @@ -1,4 +1,4 @@ -/* Cycript - Remove Execution Server and Disassembler +/* Cycript - Inlining/Optimizing JavaScript Compiler * Copyright (C) 2009 Jay Freeman (saurik) */ @@ -39,6 +39,10 @@ #include "cycript.hpp" +#ifdef CY_EXECUTE +#include "JavaScript.hpp" +#endif + #include #include @@ -66,6 +70,8 @@ #include +#include + static volatile enum { Working, Parsing, @@ -106,18 +112,17 @@ void Setup(CYDriver &driver, cy::parser &parser) { driver.strict_ = true; } -void Setup(CYOutput &out, CYDriver &driver) { +void Setup(CYOutput &out, CYDriver &driver, CYOptions &options) { out.pretty_ = pretty_; - - CYContext context(driver.pool_); + CYContext context(driver.pool_, options); driver.program_->Replace(context); } -void Run(int socket, const char *data, size_t size, FILE *fout = NULL, bool expand = false) { +void Run(int client, const char *data, size_t size, FILE *fout = NULL, bool expand = false) { CYPool pool; const char *json; - if (socket == -1) { + if (client == -1) { mode_ = Running; #ifdef CY_EXECUTE json = CYExecute(pool, data); @@ -129,15 +134,15 @@ void Run(int socket, const char *data, size_t size, FILE *fout = NULL, bool expa size = strlen(json); } else { mode_ = Sending; - CYSendAll(socket, &size, sizeof(size)); - CYSendAll(socket, data, size); + CYSendAll(client, &size, sizeof(size)); + CYSendAll(client, data, size); mode_ = Waiting; - CYRecvAll(socket, &size, sizeof(size)); + CYRecvAll(client, &size, sizeof(size)); if (size == _not(size_t)) json = NULL; else { char *temp(new(pool) char[size + 1]); - CYRecvAll(socket, temp, size); + CYRecvAll(client, temp, size); temp[size] = '\0'; json = temp; } @@ -170,11 +175,13 @@ void Run(int socket, const char *data, size_t size, FILE *fout = NULL, bool expa } } -void Run(int socket, std::string &code, FILE *fout = NULL, bool expand = false) { - Run(socket, code.c_str(), code.size(), fout, expand); +void Run(int client, std::string &code, FILE *fout = NULL, bool expand = false) { + Run(client, code.c_str(), code.size(), fout, expand); } -static void Console(apr_pool_t *pool, int socket) { +int (*append_history$)(int, const char *); + +static void Console(apr_pool_t *pool, int client, CYOptions &options) { passwd *passwd; if (const char *username = getenv("LOGNAME")) passwd = getpwnam(username); @@ -222,6 +229,8 @@ static void Console(apr_pool_t *pool, int socket) { mode_ = Working; if (line == NULL) break; + if (line[0] == '\0') + goto read; if (!extra) { extra = true; @@ -310,12 +319,12 @@ static void Console(apr_pool_t *pool, int socket) { if (driver.program_ == NULL) goto restart; - if (socket != -1) + if (client != -1) code = command; else { std::ostringstream str; - CYOutput out(str); - Setup(out, driver); + CYOutput out(str, options); + Setup(out, driver, options); out << *driver.program_; code = str.str(); } @@ -327,11 +336,15 @@ static void Console(apr_pool_t *pool, int socket) { if (debug) std::cout << code << std::endl; - Run(socket, code, fout, expand); + Run(client, code, fout, expand); } - _syscall(close(_syscall(open(histfile, O_CREAT | O_WRONLY, 0600)))); - append_history(histlines, histfile); + if (append_history$ != NULL) { + _syscall(close(_syscall(open(histfile, O_CREAT | O_WRONLY, 0600)))); + (*append_history$)(histlines, histfile); + } else { + write_history(histfile); + } fputs("\n", fout); fflush(fout); @@ -354,11 +367,14 @@ static void *Map(const char *path, size_t *psize) { return base; } -int main(int argc, char const * const argv[], char const * const envp[]) { - _aprcall(apr_app_initialize(&argc, &argv, &envp)); +void InjectLibrary(pid_t pid); +int Main(int argc, char const * const argv[], char const * const envp[]) { bool tty(isatty(STDIN_FILENO)); bool compile(false); + CYOptions options; + + append_history$ = reinterpret_cast(dlsym(RTLD_DEFAULT, "append_history")); #ifdef CY_ATTACH pid_t pid(_not(pid_t)); @@ -404,6 +420,8 @@ int main(int argc, char const * const argv[], char const * const envp[]) { case 'g': if (false); + else if (strcmp(arg, "rename") == 0) + options.verbose_ = true; #if YYDEBUG else if (strcmp(arg, "bison") == 0) bison_ = true; @@ -446,14 +464,14 @@ int main(int argc, char const * const argv[], char const * const envp[]) { size += read; if (size == sizeof(value)) { pid = _not(pid_t); - goto pclose; + goto fail; } } } size: if (size == 0) - goto pclose; + goto fail; if (value[size - 1] == '\n') { --size; goto size; @@ -462,10 +480,8 @@ int main(int argc, char const * const argv[], char const * const envp[]) { value[size] = '\0'; size = strlen(value); pid = strtoul(value, &end, 0); - if (value + size != end) + if (value + size != end) fail: pid = _not(pid_t); - - pclose: _syscall(pclose(pids)); } @@ -517,27 +533,42 @@ int main(int argc, char const * const argv[], char const * const envp[]) { } #endif - int socket; + int client; #ifdef CY_ATTACH if (pid == _not(pid_t)) - socket = -1; + client = -1; else { - socket = _syscall(::socket(PF_UNIX, SOCK_STREAM, 0)); - - 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))); + int server(_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", getpid()); + + _syscall(bind(server, reinterpret_cast(&address), SUN_LEN(&address))); + _syscall(chmod(address.sun_path, 0777)); + + try { + _syscall(listen(server, 1)); + InjectLibrary(pid); + client = _syscall(accept(server, NULL, NULL)); + } catch (...) { + // XXX: exception? + unlink(address.sun_path); + throw; + } + } catch (...) { + _syscall(close(server)); + throw; + } } #else - socket = -1; + client = -1; #endif if (script == NULL && tty) - Console(pool, socket); + Console(pool, client, options); else { CYDriver driver(script ?: ""); cy::parser parser(driver); @@ -572,20 +603,36 @@ int main(int argc, char const * const argv[], char const * const envp[]) { for (CYDriver::Errors::const_iterator i(driver.errors_.begin()); i != driver.errors_.end(); ++i) std::cerr << i->location_.begin << ": " << i->message_ << std::endl; } else if (driver.program_ != NULL) - if (socket != -1) - Run(socket, start, end - start, stdout); - else { + if (client != -1) { + std::string code(start, end-start); + Run(client, code, stdout); + } else { std::ostringstream str; - CYOutput out(str); - Setup(out, driver); + CYOutput out(str, options); + Setup(out, driver, options); out << *driver.program_; std::string code(str.str()); if (compile) std::cout << code; else - Run(socket, code, stdout); + Run(client, code, stdout); } } return 0; } + +int main(int argc, char const * const argv[], char const * const envp[]) { + apr_status_t status(apr_app_initialize(&argc, &argv, &envp)); + + if (status != APR_SUCCESS) { + fprintf(stderr, "apr_app_initialize() != APR_SUCCESS\n"); + return 1; + } else try { + return Main(argc, argv, envp); + } catch (const CYException &error) { + CYPool pool; + fprintf(stderr, "%s\n", error.PoolCString(pool)); + return 1; + } +}