PageRenderTime 90ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/food/common.c

http://github.com/comex/frash
C | 247 lines | 211 code | 35 blank | 1 comment | 41 complexity | 45ba25e0926091843e0d966730fb4d94 MD5 | raw file
  1. #include <common.h>
  2. #include <pthread.h>
  3. #include <mach/mach.h>
  4. #include <sandbox.h>
  5. #include <string.h>
  6. #include <sys/types.h>
  7. #include <sys/socket.h>
  8. #include <sys/time.h>
  9. #include <netinet/in.h>
  10. #include <fcntl.h>
  11. #include <spawn.h>
  12. int food;
  13. int movie_w = 0, movie_h = -1;
  14. int pending_movie_w = 0, pending_movie_h = -1;
  15. void pattern(void *stuff, uint32_t base, int len) {
  16. uint32_t *p = stuff;
  17. len /= 4;
  18. while(len--) {
  19. *p++ = base;
  20. base += 4;
  21. }
  22. }
  23. static const unsigned int raw_data_isa = 0xdddddddd;
  24. static const unsigned int raw_ptr_isa = 0xbbbbbbbb;
  25. struct raw_data {
  26. unsigned int isa;
  27. int retaincount;
  28. int size;
  29. char data[];
  30. };
  31. struct raw_ptr {
  32. unsigned int isa;
  33. int retaincount;
  34. void *ptr;
  35. };
  36. void *RawDataCreate(int size) {
  37. struct raw_data *ret = malloc(sizeof(struct raw_data) + size);
  38. ret->isa = raw_data_isa;
  39. ret->retaincount = 0; // lol
  40. ret->size = size;
  41. memset(ret->data, 0, size);
  42. return ret;
  43. }
  44. void *RawDataGetPtr(const void *value) {
  45. // Haha I suck :<
  46. struct raw_data *raw = (void *) value;
  47. if(raw->isa != raw_data_isa) return NULL;
  48. return raw->data;
  49. }
  50. int RawDataGetSize(const void *value) {
  51. struct raw_data *raw = (void *) value;
  52. if(raw->isa != raw_data_isa) return 0;
  53. return raw->size;
  54. }
  55. void *RawPtrCreate(void *ptr) {
  56. struct raw_ptr *ret = malloc(sizeof(struct raw_ptr));
  57. ret->isa = raw_ptr_isa;
  58. ret->retaincount = 1;
  59. ret->ptr = ptr;
  60. return ret;
  61. }
  62. void *RawPtrGet(const void *value) {
  63. struct raw_ptr *raw = (void *) value;
  64. if(raw->isa != raw_ptr_isa) return NULL;
  65. return raw->ptr;
  66. }
  67. static const void *myRetain(CFAllocatorRef allocator, const void *value) {
  68. struct raw_data *raw = (void *) value;
  69. if(raw->isa == raw_data_isa || raw->isa == raw_ptr_isa) {
  70. raw->retaincount++;
  71. } else {
  72. CFRetain(value);
  73. }
  74. return value;
  75. }
  76. static void myRelease(CFAllocatorRef allocator, const void *value) {
  77. struct raw_data *raw = (void *) value;
  78. if(raw->isa == raw_data_isa || raw->isa == raw_ptr_isa) {
  79. if(--raw->retaincount == 0) free(raw);
  80. } else {
  81. CFRelease(value);
  82. }
  83. }
  84. CFStringRef myCopyDescription(const void *value) {
  85. const struct raw_data *raw_data = value;
  86. const struct raw_ptr *raw_ptr = value;
  87. if(raw_data->isa == raw_data_isa) {
  88. return CFStringCreateWithFormat(NULL, NULL, CFSTR("<raw data %d>"), raw_data->size);
  89. } else if(raw_data->isa == raw_ptr_isa) {
  90. return CFStringCreateWithFormat(NULL, NULL, CFSTR("<raw ptr %p>"), raw_ptr->ptr);
  91. } else {
  92. return CFCopyDescription(value);
  93. }
  94. }
  95. Boolean myEqual(const void *value1, const void *value2) {
  96. const struct raw_data *raw1 = value1, *raw2 = value2;
  97. if(raw1->isa != raw_data_isa && raw2->isa != raw_data_isa &&
  98. raw1->isa != raw_ptr_isa && raw2->isa != raw_ptr_isa)
  99. return CFEqual(value1, value2);
  100. return value1 == value2;
  101. }
  102. CFDictionaryValueCallBacks myValueCallBacks = {
  103. 0,
  104. myRetain,
  105. myRelease,
  106. myCopyDescription,
  107. myEqual
  108. };
  109. CFMutableDictionaryRef new_dict() {
  110. return CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &myValueCallBacks);
  111. }
  112. void logreal_(CFStringRef string) {
  113. CFIndex len = CFStringGetLength(string) + 1;
  114. char *buf = malloc(len);
  115. CFStringGetCString(string, buf, len, kCFStringEncodingASCII);
  116. CFRelease(string);
  117. write(STDERR_FILENO, buf, len);
  118. write(STDERR_FILENO, "\n", 1);
  119. free(buf);
  120. }
  121. void do_later(void (*func)(CFRunLoopTimerRef, void *), void *info) {
  122. CFRunLoopTimerContext ctx;
  123. memset(&ctx, 0, sizeof(ctx));
  124. ctx.info = info;
  125. CFRunLoopTimerRef ref = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent(), 0.0, 0, 0, func, &ctx);
  126. CFRunLoopAddTimer(CFRunLoopGetMain(), ref, kCFRunLoopCommonModes);
  127. }
  128. static void error(int food_, int err) {
  129. if(err < 0) {
  130. fprintf(stderr, "Socket error: %s\n", strerror(-err));
  131. } else {
  132. fprintf(stderr, "Internal error: %d\n", err);
  133. }
  134. _abort();
  135. }
  136. void rpc_init(const char *rpcname) {
  137. if(!strcmp(rpcname, "inetd")) {
  138. food = 3;
  139. } else {
  140. int serv = socket(AF_INET, SOCK_STREAM, 0);
  141. _assert(serv > 0);
  142. struct sockaddr_in addr;
  143. memset(&addr, 0, sizeof(addr));
  144. addr.sin_family = AF_INET;
  145. addr.sin_addr.s_addr = htonl(0x7f000001);
  146. addr.sin_port = htons(atoi(rpcname));
  147. int tru = 1;
  148. setsockopt(serv, SOL_SOCKET, SO_REUSEADDR, &tru, sizeof(tru));
  149. setsockopt(serv, SOL_SOCKET, SO_REUSEPORT, &tru, sizeof(tru));
  150. _assertZero(bind(serv, (struct sockaddr *) &addr, sizeof(addr)));
  151. _assertZero(listen(serv, 10));
  152. char buf[200];
  153. socklen_t buflen = 200;
  154. food = accept(serv, (struct sockaddr *) buf, &buflen);
  155. _assert(food > 0);
  156. }
  157. rpcserve(food, error);
  158. log("RPC hi.");
  159. }
  160. void sandbox_me() {
  161. char *err;
  162. int fd = open("food.sb", O_RDONLY);
  163. _assert(fd > 0);
  164. size_t len = lseek(fd, 0, SEEK_END);
  165. char *sandbox = malloc(len + 1);
  166. pread(fd, sandbox, len, 0);
  167. sandbox[len] = 0;
  168. close(fd);
  169. if(0 != sandbox_init(sandbox, 0, &err)) {
  170. fprintf(stderr, "Couldn't sandbox: %s\n", err);
  171. _abort();
  172. }
  173. free(sandbox);
  174. }
  175. __attribute__((noreturn))
  176. static void do_abort(char *message) {
  177. err("%s", message);
  178. abort_msg(food, message, strlen(message)); // may or may not succeed
  179. exit(1);
  180. }
  181. void _assert_(bool test, const char *label, const char *file, int line, const char *func) {
  182. if(!test) {
  183. char *x;
  184. asprintf(&x, "Assertion failed: (%s), function %s, file %s, line %d.", label, func, file, line);
  185. do_abort(x);
  186. }
  187. }
  188. void _assertZero_(int test, const char *label, const char *file, int line, const char *func) {
  189. if(test != 0) {
  190. char *x;
  191. asprintf(&x, "Assertion failed: !(%s) [it was %d / 0x%x], function %s, file %s, line %d.", label, test, test, func, file, line);
  192. do_abort(x);
  193. }
  194. }
  195. void _abort_(const char *file, int line) {
  196. char *x;
  197. asprintf(&x, "_abort() %s:%d", file, line);
  198. do_abort(x);
  199. }
  200. void _abortWithError_(const char *file, int line, const char *error) {
  201. char *x;
  202. asprintf(&x, "%s %s:%d", error, file, line);
  203. do_abort(x);
  204. }
  205. #if TIMING
  206. uint64_t getus() {
  207. struct timeval tp;
  208. gettimeofday(&tp, NULL);
  209. return ((uint64_t) tp.tv_sec) * 1000000 + (uint64_t) tp.tv_usec;
  210. }
  211. #endif
  212. bool locked, sfc_dirty;