]> git.saurik.com Git - cycript.git/blame - Connector.cpp
Re-added final output to script execution, implemented unary affirmation operator...
[cycript.git] / Connector.cpp
CommitLineData
1ef7d061
JF
1#include <substrate.h>
2
3#include "cycript.hpp"
4#include "Pooling.hpp"
5
6#include <sys/types.h>
7#include <sys/socket.h>
8#include <netinet/in.h>
9#include <sys/un.h>
10
11#include <apr-1/apr_thread_proc.h>
12
13#include <fcntl.h>
14#include <unistd.h>
15
16#import <CoreFoundation/CFLogUtilities.h>
17
18struct CYServer :
19 CYData
20{
21 int socket_;
22};
23
24apr_status_t CYPoolDLClose_(void *data) {
92841c2c
JF
25 // XXX: this is an interesting idea
26 /* void *handle(reinterpret_cast<void *>(data));
27 dlclose(handle); */
1ef7d061
JF
28 return APR_SUCCESS;
29}
30
31static void * APR_THREAD_FUNC Cyrver(apr_thread_t *thread, void *data) {
32 CYServer *server(reinterpret_cast<CYServer *>(data));
33
34 for (;;) {
35 int socket(_syscall(accept(server->socket_, NULL, NULL)));
36
37 if (void *handle = dlopen("/usr/lib/libcycript.dylib", RTLD_LAZY | RTLD_LOCAL)) {
38 apr_pool_t *pool;
39 _aprcall(apr_pool_create(&pool, NULL));
40
41 apr_pool_cleanup_register(pool, handle, &CYPoolDLClose_, &apr_pool_cleanup_null);
42
43 if (void (*CYHandleClient_)(apr_pool_t *, int) = reinterpret_cast<void (*)(apr_pool_t *, int)>(dlsym(handle, "CYHandleClient")))
44 (*CYHandleClient_)(pool, socket);
45 else
46 apr_pool_destroy(pool);
47 } else
48 CFLog(kCFLogLevelError, CFSTR("CY:Error: cannot load: %s"), dlerror());
49 }
50
51 delete server;
52 return NULL;
53}
54
55static void Unlink() {
56 pid_t pid(getpid());
57 char path[104];
58 sprintf(path, "/tmp/.s.cy.%u", pid);
59 unlink(path);
60}
61
62MSInitialize {
63 _aprcall(apr_initialize());
64
65 CYServer *server(new CYServer());
66 server->socket_ = _syscall(socket(PF_UNIX, SOCK_STREAM, 0));
67
68 struct sockaddr_un address;
69 memset(&address, 0, sizeof(address));
70 address.sun_family = AF_UNIX;
71
72 pid_t pid(getpid());
73 sprintf(address.sun_path, "/tmp/.s.cy.%u", pid);
74
75 try {
76 _syscall(bind(server->socket_, reinterpret_cast<sockaddr *>(&address), SUN_LEN(&address)));
77 atexit(&Unlink);
78 _syscall(listen(server->socket_, 0));
79
80 apr_threadattr_t *attr;
81 _aprcall(apr_threadattr_create(&attr, server->pool_));
82
83 apr_thread_t *thread;
84 _aprcall(apr_thread_create(&thread, attr, &Cyrver, server, server->pool_));
85 } catch (...) {
86 CFLog(kCFLogLevelError, CFSTR("CY:Error: cannot bind unix domain socket"));
87 }
88}