]> git.saurik.com Git - cycript.git/blob - Connector.cpp
Removed dlclose() as it scares me and would cause everything to crash horribly if...
[cycript.git] / Connector.cpp
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
18 struct CYServer :
19 CYData
20 {
21 int socket_;
22 };
23
24 apr_status_t CYPoolDLClose_(void *data) {
25 // XXX: this is an interesting idea
26 /* void *handle(reinterpret_cast<void *>(data));
27 dlclose(handle); */
28 return APR_SUCCESS;
29 }
30
31 static 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
55 static void Unlink() {
56 pid_t pid(getpid());
57 char path[104];
58 sprintf(path, "/tmp/.s.cy.%u", pid);
59 unlink(path);
60 }
61
62 MSInitialize {
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 }