redis-server 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (290) hide show
  1. data/LICENSE +38 -0
  2. data/README.md +33 -0
  3. data/bin/redis +114 -0
  4. data/redis/Makefile +5 -0
  5. data/redis/extconf.rb +3 -0
  6. data/redis/redis-2.2.11/00-RELEASENOTES +199 -0
  7. data/redis/redis-2.2.11/BUGS +1 -0
  8. data/redis/redis-2.2.11/CONTRIBUTING +13 -0
  9. data/redis/redis-2.2.11/COPYING +10 -0
  10. data/redis/redis-2.2.11/Changelog +1032 -0
  11. data/redis/redis-2.2.11/INSTALL +30 -0
  12. data/redis/redis-2.2.11/Makefile +22 -0
  13. data/redis/redis-2.2.11/README +83 -0
  14. data/redis/redis-2.2.11/TODO +4 -0
  15. data/redis/redis-2.2.11/client-libraries/README +11 -0
  16. data/redis/redis-2.2.11/deps/hiredis/COPYING +10 -0
  17. data/redis/redis-2.2.11/deps/hiredis/Makefile +115 -0
  18. data/redis/redis-2.2.11/deps/hiredis/README.md +311 -0
  19. data/redis/redis-2.2.11/deps/hiredis/TODO +2 -0
  20. data/redis/redis-2.2.11/deps/hiredis/adapters/ae.h +95 -0
  21. data/redis/redis-2.2.11/deps/hiredis/adapters/libev.h +113 -0
  22. data/redis/redis-2.2.11/deps/hiredis/adapters/libevent.h +76 -0
  23. data/redis/redis-2.2.11/deps/hiredis/async.c +321 -0
  24. data/redis/redis-2.2.11/deps/hiredis/async.h +112 -0
  25. data/redis/redis-2.2.11/deps/hiredis/example-ae.c +53 -0
  26. data/redis/redis-2.2.11/deps/hiredis/example-libev.c +47 -0
  27. data/redis/redis-2.2.11/deps/hiredis/example-libevent.c +48 -0
  28. data/redis/redis-2.2.11/deps/hiredis/example.c +67 -0
  29. data/redis/redis-2.2.11/deps/hiredis/fmacros.h +15 -0
  30. data/redis/redis-2.2.11/deps/hiredis/hiredis.c +1058 -0
  31. data/redis/redis-2.2.11/deps/hiredis/hiredis.h +170 -0
  32. data/redis/redis-2.2.11/deps/hiredis/net.c +170 -0
  33. data/redis/redis-2.2.11/deps/hiredis/net.h +43 -0
  34. data/redis/redis-2.2.11/deps/hiredis/sds.c +479 -0
  35. data/redis/redis-2.2.11/deps/hiredis/sds.h +77 -0
  36. data/redis/redis-2.2.11/deps/hiredis/test.c +479 -0
  37. data/redis/redis-2.2.11/deps/hiredis/util.h +40 -0
  38. data/redis/redis-2.2.11/deps/linenoise/Makefile +10 -0
  39. data/redis/redis-2.2.11/deps/linenoise/README.markdown +45 -0
  40. data/redis/redis-2.2.11/deps/linenoise/example.c +27 -0
  41. data/redis/redis-2.2.11/deps/linenoise/linenoise.c +609 -0
  42. data/redis/redis-2.2.11/deps/linenoise/linenoise.h +55 -0
  43. data/redis/redis-2.2.11/design-documents/REDIS-CLUSTER +214 -0
  44. data/redis/redis-2.2.11/design-documents/REDIS-CLUSTER-2 +343 -0
  45. data/redis/redis-2.2.11/doc/AppendCommand.html +48 -0
  46. data/redis/redis-2.2.11/doc/AppendOnlyFileHowto.html +41 -0
  47. data/redis/redis-2.2.11/doc/AuthCommand.html +39 -0
  48. data/redis/redis-2.2.11/doc/Benchmarks.html +129 -0
  49. data/redis/redis-2.2.11/doc/BgrewriteaofCommand.html +41 -0
  50. data/redis/redis-2.2.11/doc/BgsaveCommand.html +39 -0
  51. data/redis/redis-2.2.11/doc/BlpopCommand.html +51 -0
  52. data/redis/redis-2.2.11/doc/BrpoplpushCommand.html +39 -0
  53. data/redis/redis-2.2.11/doc/CommandReference.html +47 -0
  54. data/redis/redis-2.2.11/doc/Comparisons.html +42 -0
  55. data/redis/redis-2.2.11/doc/ConfigCommand.html +76 -0
  56. data/redis/redis-2.2.11/doc/Configuration.html +38 -0
  57. data/redis/redis-2.2.11/doc/ConnectionHandlingSidebar.html +36 -0
  58. data/redis/redis-2.2.11/doc/ControlCommandsSidebar.html +36 -0
  59. data/redis/redis-2.2.11/doc/Credits.html +38 -0
  60. data/redis/redis-2.2.11/doc/DbsizeCommand.html +38 -0
  61. data/redis/redis-2.2.11/doc/DelCommand.html +41 -0
  62. data/redis/redis-2.2.11/doc/DesignPatterns.html +37 -0
  63. data/redis/redis-2.2.11/doc/EventLibray.html +44 -0
  64. data/redis/redis-2.2.11/doc/ExistsCommand.html +42 -0
  65. data/redis/redis-2.2.11/doc/ExpireCommand.html +96 -0
  66. data/redis/redis-2.2.11/doc/FAQ.html +70 -0
  67. data/redis/redis-2.2.11/doc/Features.html +38 -0
  68. data/redis/redis-2.2.11/doc/FlushallCommand.html +39 -0
  69. data/redis/redis-2.2.11/doc/FlushdbCommand.html +39 -0
  70. data/redis/redis-2.2.11/doc/FromSqlToDataStructures.html +37 -0
  71. data/redis/redis-2.2.11/doc/GenericCommandsSidebar.html +36 -0
  72. data/redis/redis-2.2.11/doc/GetCommand.html +39 -0
  73. data/redis/redis-2.2.11/doc/GetbitCommand.html +39 -0
  74. data/redis/redis-2.2.11/doc/GetsetCommand.html +38 -0
  75. data/redis/redis-2.2.11/doc/HackingStrings.html +83 -0
  76. data/redis/redis-2.2.11/doc/HashCommandsSidebar.html +36 -0
  77. data/redis/redis-2.2.11/doc/Hashes.html +37 -0
  78. data/redis/redis-2.2.11/doc/HdelCommand.html +39 -0
  79. data/redis/redis-2.2.11/doc/HexistsCommand.html +39 -0
  80. data/redis/redis-2.2.11/doc/HgetCommand.html +39 -0
  81. data/redis/redis-2.2.11/doc/HgetallCommand.html +40 -0
  82. data/redis/redis-2.2.11/doc/HincrbyCommand.html +45 -0
  83. data/redis/redis-2.2.11/doc/HlenCommand.html +38 -0
  84. data/redis/redis-2.2.11/doc/HmgetCommand.html +40 -0
  85. data/redis/redis-2.2.11/doc/HmsetCommand.html +40 -0
  86. data/redis/redis-2.2.11/doc/HsetCommand.html +40 -0
  87. data/redis/redis-2.2.11/doc/HsetnxCommand.html +41 -0
  88. data/redis/redis-2.2.11/doc/IncrCommand.html +43 -0
  89. data/redis/redis-2.2.11/doc/InfoCommand.html +48 -0
  90. data/redis/redis-2.2.11/doc/IntroductionToRedisDataTypes.html +152 -0
  91. data/redis/redis-2.2.11/doc/KeysCommand.html +43 -0
  92. data/redis/redis-2.2.11/doc/LastsaveCommand.html +39 -0
  93. data/redis/redis-2.2.11/doc/LindexCommand.html +40 -0
  94. data/redis/redis-2.2.11/doc/ListCommandsSidebar.html +36 -0
  95. data/redis/redis-2.2.11/doc/Lists.html +42 -0
  96. data/redis/redis-2.2.11/doc/LlenCommand.html +41 -0
  97. data/redis/redis-2.2.11/doc/LpopCommand.html +41 -0
  98. data/redis/redis-2.2.11/doc/LrangeCommand.html +47 -0
  99. data/redis/redis-2.2.11/doc/LremCommand.html +41 -0
  100. data/redis/redis-2.2.11/doc/LsetCommand.html +38 -0
  101. data/redis/redis-2.2.11/doc/LtrimCommand.html +47 -0
  102. data/redis/redis-2.2.11/doc/MgetCommand.html +52 -0
  103. data/redis/redis-2.2.11/doc/MonitorCommand.html +63 -0
  104. data/redis/redis-2.2.11/doc/MoveCommand.html +42 -0
  105. data/redis/redis-2.2.11/doc/MsetCommand.html +44 -0
  106. data/redis/redis-2.2.11/doc/MultiExecCommand.html +166 -0
  107. data/redis/redis-2.2.11/doc/NonexistentCommands.html +51 -0
  108. data/redis/redis-2.2.11/doc/ObjectHashMappers.html +39 -0
  109. data/redis/redis-2.2.11/doc/Pipelining.html +36 -0
  110. data/redis/redis-2.2.11/doc/ProgrammingExamples.html +38 -0
  111. data/redis/redis-2.2.11/doc/ProtocolSpecification.html +137 -0
  112. data/redis/redis-2.2.11/doc/PublishSubscribe.html +115 -0
  113. data/redis/redis-2.2.11/doc/QuickStart.html +68 -0
  114. data/redis/redis-2.2.11/doc/QuitCommand.html +38 -0
  115. data/redis/redis-2.2.11/doc/README.html +119 -0
  116. data/redis/redis-2.2.11/doc/RandomkeyCommand.html +39 -0
  117. data/redis/redis-2.2.11/doc/Redis0100ChangeLog.html +67 -0
  118. data/redis/redis-2.2.11/doc/Redis0900ChangeLog.html +56 -0
  119. data/redis/redis-2.2.11/doc/RedisBigData.html +61 -0
  120. data/redis/redis-2.2.11/doc/RedisCLI.html +37 -0
  121. data/redis/redis-2.2.11/doc/RedisEventLibrary.html +70 -0
  122. data/redis/redis-2.2.11/doc/RedisGuides.html +37 -0
  123. data/redis/redis-2.2.11/doc/RedisInternals.html +38 -0
  124. data/redis/redis-2.2.11/doc/RedisPipelining.html +93 -0
  125. data/redis/redis-2.2.11/doc/RedisStatus.html +56 -0
  126. data/redis/redis-2.2.11/doc/Redis_1_2_0_Changelog.html +40 -0
  127. data/redis/redis-2.2.11/doc/Redis_2_0_0_Changelog.html +62 -0
  128. data/redis/redis-2.2.11/doc/Redis_2_0_Whats_new.html +59 -0
  129. data/redis/redis-2.2.11/doc/RenameCommand.html +39 -0
  130. data/redis/redis-2.2.11/doc/RenamenxCommand.html +42 -0
  131. data/redis/redis-2.2.11/doc/ReplicationHowto.html +43 -0
  132. data/redis/redis-2.2.11/doc/ReplyTypes.html +42 -0
  133. data/redis/redis-2.2.11/doc/RoadMap.html +38 -0
  134. data/redis/redis-2.2.11/doc/RpoplpushCommand.html +44 -0
  135. data/redis/redis-2.2.11/doc/RpushCommand.html +40 -0
  136. data/redis/redis-2.2.11/doc/SaddCommand.html +41 -0
  137. data/redis/redis-2.2.11/doc/SaveCommand.html +39 -0
  138. data/redis/redis-2.2.11/doc/ScardCommand.html +41 -0
  139. data/redis/redis-2.2.11/doc/SdiffCommand.html +45 -0
  140. data/redis/redis-2.2.11/doc/SdiffstoreCommand.html +38 -0
  141. data/redis/redis-2.2.11/doc/SelectCommand.html +39 -0
  142. data/redis/redis-2.2.11/doc/SetCommand.html +39 -0
  143. data/redis/redis-2.2.11/doc/SetCommandsSidebar.html +36 -0
  144. data/redis/redis-2.2.11/doc/SetbitCommand.html +45 -0
  145. data/redis/redis-2.2.11/doc/SetexCommand.html +42 -0
  146. data/redis/redis-2.2.11/doc/SetnxCommand.html +51 -0
  147. data/redis/redis-2.2.11/doc/SetrangeCommand.html +58 -0
  148. data/redis/redis-2.2.11/doc/Sets.html +36 -0
  149. data/redis/redis-2.2.11/doc/ShutdownCommand.html +39 -0
  150. data/redis/redis-2.2.11/doc/SideBar.html +36 -0
  151. data/redis/redis-2.2.11/doc/SinterCommand.html +40 -0
  152. data/redis/redis-2.2.11/doc/SinterstoreCommand.html +39 -0
  153. data/redis/redis-2.2.11/doc/SismemberCommand.html +42 -0
  154. data/redis/redis-2.2.11/doc/SlaveofCommand.html +41 -0
  155. data/redis/redis-2.2.11/doc/SmembersCommand.html +38 -0
  156. data/redis/redis-2.2.11/doc/SmoveCommand.html +44 -0
  157. data/redis/redis-2.2.11/doc/SortCommand.html +75 -0
  158. data/redis/redis-2.2.11/doc/SortedSetCommandsSidebar.html +36 -0
  159. data/redis/redis-2.2.11/doc/SortedSets.html +36 -0
  160. data/redis/redis-2.2.11/doc/Speed.html +38 -0
  161. data/redis/redis-2.2.11/doc/SponsorshipHistory.html +38 -0
  162. data/redis/redis-2.2.11/doc/SpopCommand.html +40 -0
  163. data/redis/redis-2.2.11/doc/SrandmemberCommand.html +40 -0
  164. data/redis/redis-2.2.11/doc/SremCommand.html +42 -0
  165. data/redis/redis-2.2.11/doc/StringCommandsSidebar.html +36 -0
  166. data/redis/redis-2.2.11/doc/Strings.html +37 -0
  167. data/redis/redis-2.2.11/doc/StrlenCommand.html +39 -0
  168. data/redis/redis-2.2.11/doc/SubstrCommand.html +52 -0
  169. data/redis/redis-2.2.11/doc/SunionCommand.html +40 -0
  170. data/redis/redis-2.2.11/doc/SunionstoreCommand.html +38 -0
  171. data/redis/redis-2.2.11/doc/SupportedLanguages.html +60 -0
  172. data/redis/redis-2.2.11/doc/SupportedPlatforms.html +37 -0
  173. data/redis/redis-2.2.11/doc/TemplateCommand.html +38 -0
  174. data/redis/redis-2.2.11/doc/TtlCommand.html +38 -0
  175. data/redis/redis-2.2.11/doc/TwitterAlikeExample.html +250 -0
  176. data/redis/redis-2.2.11/doc/TypeCommand.html +46 -0
  177. data/redis/redis-2.2.11/doc/UnstableSource.html +39 -0
  178. data/redis/redis-2.2.11/doc/VirtualMemorySpecification.html +156 -0
  179. data/redis/redis-2.2.11/doc/VirtualMemoryUserGuide.html +66 -0
  180. data/redis/redis-2.2.11/doc/ZaddCommand.html +43 -0
  181. data/redis/redis-2.2.11/doc/ZcardCommand.html +41 -0
  182. data/redis/redis-2.2.11/doc/ZincrbyCommand.html +42 -0
  183. data/redis/redis-2.2.11/doc/ZrangeCommand.html +42 -0
  184. data/redis/redis-2.2.11/doc/ZrangebyscoreCommand.html +77 -0
  185. data/redis/redis-2.2.11/doc/ZrankCommand.html +43 -0
  186. data/redis/redis-2.2.11/doc/ZremCommand.html +42 -0
  187. data/redis/redis-2.2.11/doc/ZremrangebyrankCommand.html +39 -0
  188. data/redis/redis-2.2.11/doc/ZremrangebyscoreCommand.html +39 -0
  189. data/redis/redis-2.2.11/doc/ZscoreCommand.html +41 -0
  190. data/redis/redis-2.2.11/doc/ZunionCommand.html +42 -0
  191. data/redis/redis-2.2.11/doc/ZunionstoreCommand.html +43 -0
  192. data/redis/redis-2.2.11/doc/index.html +43 -0
  193. data/redis/redis-2.2.11/doc/redis.png +0 -0
  194. data/redis/redis-2.2.11/doc/style.css +25 -0
  195. data/redis/redis-2.2.11/redis.conf +417 -0
  196. data/redis/redis-2.2.11/src/Makefile +177 -0
  197. data/redis/redis-2.2.11/src/adlist.c +325 -0
  198. data/redis/redis-2.2.11/src/adlist.h +92 -0
  199. data/redis/redis-2.2.11/src/ae.c +390 -0
  200. data/redis/redis-2.2.11/src/ae.h +117 -0
  201. data/redis/redis-2.2.11/src/ae_epoll.c +91 -0
  202. data/redis/redis-2.2.11/src/ae_kqueue.c +93 -0
  203. data/redis/redis-2.2.11/src/ae_select.c +72 -0
  204. data/redis/redis-2.2.11/src/anet.c +347 -0
  205. data/redis/redis-2.2.11/src/anet.h +57 -0
  206. data/redis/redis-2.2.11/src/aof.c +675 -0
  207. data/redis/redis-2.2.11/src/config.c +627 -0
  208. data/redis/redis-2.2.11/src/config.h +64 -0
  209. data/redis/redis-2.2.11/src/db.c +543 -0
  210. data/redis/redis-2.2.11/src/debug.c +314 -0
  211. data/redis/redis-2.2.11/src/dict.c +721 -0
  212. data/redis/redis-2.2.11/src/dict.h +156 -0
  213. data/redis/redis-2.2.11/src/fmacros.h +15 -0
  214. data/redis/redis-2.2.11/src/help.h +638 -0
  215. data/redis/redis-2.2.11/src/intset.c +422 -0
  216. data/redis/redis-2.2.11/src/intset.h +19 -0
  217. data/redis/redis-2.2.11/src/lzf.h +100 -0
  218. data/redis/redis-2.2.11/src/lzfP.h +159 -0
  219. data/redis/redis-2.2.11/src/lzf_c.c +295 -0
  220. data/redis/redis-2.2.11/src/lzf_d.c +150 -0
  221. data/redis/redis-2.2.11/src/mkreleasehdr.sh +9 -0
  222. data/redis/redis-2.2.11/src/multi.c +268 -0
  223. data/redis/redis-2.2.11/src/networking.c +899 -0
  224. data/redis/redis-2.2.11/src/object.c +484 -0
  225. data/redis/redis-2.2.11/src/pqsort.c +197 -0
  226. data/redis/redis-2.2.11/src/pqsort.h +15 -0
  227. data/redis/redis-2.2.11/src/pubsub.c +267 -0
  228. data/redis/redis-2.2.11/src/rdb.c +1020 -0
  229. data/redis/redis-2.2.11/src/redis-benchmark.c +530 -0
  230. data/redis/redis-2.2.11/src/redis-check-aof.c +185 -0
  231. data/redis/redis-2.2.11/src/redis-check-dump.c +681 -0
  232. data/redis/redis-2.2.11/src/redis-cli.c +773 -0
  233. data/redis/redis-2.2.11/src/redis.c +1677 -0
  234. data/redis/redis-2.2.11/src/redis.h +1022 -0
  235. data/redis/redis-2.2.11/src/release.c +13 -0
  236. data/redis/redis-2.2.11/src/replication.c +557 -0
  237. data/redis/redis-2.2.11/src/sds.c +639 -0
  238. data/redis/redis-2.2.11/src/sds.h +78 -0
  239. data/redis/redis-2.2.11/src/sha1.c +276 -0
  240. data/redis/redis-2.2.11/src/sha1.h +17 -0
  241. data/redis/redis-2.2.11/src/solarisfixes.h +22 -0
  242. data/redis/redis-2.2.11/src/sort.c +389 -0
  243. data/redis/redis-2.2.11/src/syncio.c +154 -0
  244. data/redis/redis-2.2.11/src/t_hash.c +476 -0
  245. data/redis/redis-2.2.11/src/t_list.c +986 -0
  246. data/redis/redis-2.2.11/src/t_set.c +610 -0
  247. data/redis/redis-2.2.11/src/t_string.c +438 -0
  248. data/redis/redis-2.2.11/src/t_zset.c +1084 -0
  249. data/redis/redis-2.2.11/src/testhelp.h +54 -0
  250. data/redis/redis-2.2.11/src/util.c +243 -0
  251. data/redis/redis-2.2.11/src/valgrind.sup +5 -0
  252. data/redis/redis-2.2.11/src/version.h +1 -0
  253. data/redis/redis-2.2.11/src/vm.c +1149 -0
  254. data/redis/redis-2.2.11/src/ziplist.c +1323 -0
  255. data/redis/redis-2.2.11/src/ziplist.h +15 -0
  256. data/redis/redis-2.2.11/src/zipmap.c +455 -0
  257. data/redis/redis-2.2.11/src/zipmap.h +48 -0
  258. data/redis/redis-2.2.11/src/zmalloc.c +278 -0
  259. data/redis/redis-2.2.11/src/zmalloc.h +47 -0
  260. data/redis/redis-2.2.11/tests/assets/default.conf +308 -0
  261. data/redis/redis-2.2.11/tests/integration/aof.tcl +104 -0
  262. data/redis/redis-2.2.11/tests/integration/redis-cli.tcl +208 -0
  263. data/redis/redis-2.2.11/tests/integration/replication.tcl +98 -0
  264. data/redis/redis-2.2.11/tests/support/redis.tcl +241 -0
  265. data/redis/redis-2.2.11/tests/support/server.tcl +294 -0
  266. data/redis/redis-2.2.11/tests/support/test.tcl +190 -0
  267. data/redis/redis-2.2.11/tests/support/tmpfile.tcl +15 -0
  268. data/redis/redis-2.2.11/tests/support/util.tcl +296 -0
  269. data/redis/redis-2.2.11/tests/test_helper.tcl +221 -0
  270. data/redis/redis-2.2.11/tests/unit/auth.tcl +15 -0
  271. data/redis/redis-2.2.11/tests/unit/basic.tcl +616 -0
  272. data/redis/redis-2.2.11/tests/unit/cas.tcl +135 -0
  273. data/redis/redis-2.2.11/tests/unit/expire.tcl +74 -0
  274. data/redis/redis-2.2.11/tests/unit/other.tcl +240 -0
  275. data/redis/redis-2.2.11/tests/unit/printver.tcl +6 -0
  276. data/redis/redis-2.2.11/tests/unit/protocol.tcl +62 -0
  277. data/redis/redis-2.2.11/tests/unit/pubsub.tcl +195 -0
  278. data/redis/redis-2.2.11/tests/unit/quit.tcl +40 -0
  279. data/redis/redis-2.2.11/tests/unit/sort.tcl +189 -0
  280. data/redis/redis-2.2.11/tests/unit/type/hash.tcl +300 -0
  281. data/redis/redis-2.2.11/tests/unit/type/list.tcl +819 -0
  282. data/redis/redis-2.2.11/tests/unit/type/set.tcl +334 -0
  283. data/redis/redis-2.2.11/tests/unit/type/zset.tcl +587 -0
  284. data/redis/redis-2.2.11/utils/build-static-symbols.tcl +22 -0
  285. data/redis/redis-2.2.11/utils/generate-command-help.rb +112 -0
  286. data/redis/redis-2.2.11/utils/mktarball.sh +13 -0
  287. data/redis/redis-2.2.11/utils/redis-copy.rb +78 -0
  288. data/redis/redis-2.2.11/utils/redis-sha1.rb +52 -0
  289. data/redis/redis-2.2.11/utils/redis_init_script +42 -0
  290. metadata +362 -0
@@ -0,0 +1,117 @@
1
+ /* A simple event-driven programming library. Originally I wrote this code
2
+ * for the Jim's event-loop (Jim is a Tcl interpreter) but later translated
3
+ * it in form of a library for easy reuse.
4
+ *
5
+ * Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com>
6
+ * All rights reserved.
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ *
11
+ * * Redistributions of source code must retain the above copyright notice,
12
+ * this list of conditions and the following disclaimer.
13
+ * * Redistributions in binary form must reproduce the above copyright
14
+ * notice, this list of conditions and the following disclaimer in the
15
+ * documentation and/or other materials provided with the distribution.
16
+ * * Neither the name of Redis nor the names of its contributors may be used
17
+ * to endorse or promote products derived from this software without
18
+ * specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ * POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+ #ifndef __AE_H__
34
+ #define __AE_H__
35
+
36
+ #define AE_SETSIZE (1024*10) /* Max number of fd supported */
37
+
38
+ #define AE_OK 0
39
+ #define AE_ERR -1
40
+
41
+ #define AE_NONE 0
42
+ #define AE_READABLE 1
43
+ #define AE_WRITABLE 2
44
+
45
+ #define AE_FILE_EVENTS 1
46
+ #define AE_TIME_EVENTS 2
47
+ #define AE_ALL_EVENTS (AE_FILE_EVENTS|AE_TIME_EVENTS)
48
+ #define AE_DONT_WAIT 4
49
+
50
+ #define AE_NOMORE -1
51
+
52
+ /* Macros */
53
+ #define AE_NOTUSED(V) ((void) V)
54
+
55
+ struct aeEventLoop;
56
+
57
+ /* Types and data structures */
58
+ typedef void aeFileProc(struct aeEventLoop *eventLoop, int fd, void *clientData, int mask);
59
+ typedef int aeTimeProc(struct aeEventLoop *eventLoop, long long id, void *clientData);
60
+ typedef void aeEventFinalizerProc(struct aeEventLoop *eventLoop, void *clientData);
61
+ typedef void aeBeforeSleepProc(struct aeEventLoop *eventLoop);
62
+
63
+ /* File event structure */
64
+ typedef struct aeFileEvent {
65
+ int mask; /* one of AE_(READABLE|WRITABLE) */
66
+ aeFileProc *rfileProc;
67
+ aeFileProc *wfileProc;
68
+ void *clientData;
69
+ } aeFileEvent;
70
+
71
+ /* Time event structure */
72
+ typedef struct aeTimeEvent {
73
+ long long id; /* time event identifier. */
74
+ long when_sec; /* seconds */
75
+ long when_ms; /* milliseconds */
76
+ aeTimeProc *timeProc;
77
+ aeEventFinalizerProc *finalizerProc;
78
+ void *clientData;
79
+ struct aeTimeEvent *next;
80
+ } aeTimeEvent;
81
+
82
+ /* A fired event */
83
+ typedef struct aeFiredEvent {
84
+ int fd;
85
+ int mask;
86
+ } aeFiredEvent;
87
+
88
+ /* State of an event based program */
89
+ typedef struct aeEventLoop {
90
+ int maxfd;
91
+ long long timeEventNextId;
92
+ aeFileEvent events[AE_SETSIZE]; /* Registered events */
93
+ aeFiredEvent fired[AE_SETSIZE]; /* Fired events */
94
+ aeTimeEvent *timeEventHead;
95
+ int stop;
96
+ void *apidata; /* This is used for polling API specific data */
97
+ aeBeforeSleepProc *beforesleep;
98
+ } aeEventLoop;
99
+
100
+ /* Prototypes */
101
+ aeEventLoop *aeCreateEventLoop(void);
102
+ void aeDeleteEventLoop(aeEventLoop *eventLoop);
103
+ void aeStop(aeEventLoop *eventLoop);
104
+ int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,
105
+ aeFileProc *proc, void *clientData);
106
+ void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask);
107
+ long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds,
108
+ aeTimeProc *proc, void *clientData,
109
+ aeEventFinalizerProc *finalizerProc);
110
+ int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id);
111
+ int aeProcessEvents(aeEventLoop *eventLoop, int flags);
112
+ int aeWait(int fd, int mask, long long milliseconds);
113
+ void aeMain(aeEventLoop *eventLoop);
114
+ char *aeGetApiName(void);
115
+ void aeSetBeforeSleepProc(aeEventLoop *eventLoop, aeBeforeSleepProc *beforesleep);
116
+
117
+ #endif
@@ -0,0 +1,91 @@
1
+ /* Linux epoll(2) based ae.c module
2
+ * Copyright (C) 2009-2010 Salvatore Sanfilippo - antirez@gmail.com
3
+ * Released under the BSD license. See the COPYING file for more info. */
4
+
5
+ #include <sys/epoll.h>
6
+
7
+ typedef struct aeApiState {
8
+ int epfd;
9
+ struct epoll_event events[AE_SETSIZE];
10
+ } aeApiState;
11
+
12
+ static int aeApiCreate(aeEventLoop *eventLoop) {
13
+ aeApiState *state = zmalloc(sizeof(aeApiState));
14
+
15
+ if (!state) return -1;
16
+ state->epfd = epoll_create(1024); /* 1024 is just an hint for the kernel */
17
+ if (state->epfd == -1) return -1;
18
+ eventLoop->apidata = state;
19
+ return 0;
20
+ }
21
+
22
+ static void aeApiFree(aeEventLoop *eventLoop) {
23
+ aeApiState *state = eventLoop->apidata;
24
+
25
+ close(state->epfd);
26
+ zfree(state);
27
+ }
28
+
29
+ static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
30
+ aeApiState *state = eventLoop->apidata;
31
+ struct epoll_event ee;
32
+ /* If the fd was already monitored for some event, we need a MOD
33
+ * operation. Otherwise we need an ADD operation. */
34
+ int op = eventLoop->events[fd].mask == AE_NONE ?
35
+ EPOLL_CTL_ADD : EPOLL_CTL_MOD;
36
+
37
+ ee.events = 0;
38
+ mask |= eventLoop->events[fd].mask; /* Merge old events */
39
+ if (mask & AE_READABLE) ee.events |= EPOLLIN;
40
+ if (mask & AE_WRITABLE) ee.events |= EPOLLOUT;
41
+ ee.data.u64 = 0; /* avoid valgrind warning */
42
+ ee.data.fd = fd;
43
+ if (epoll_ctl(state->epfd,op,fd,&ee) == -1) return -1;
44
+ return 0;
45
+ }
46
+
47
+ static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask) {
48
+ aeApiState *state = eventLoop->apidata;
49
+ struct epoll_event ee;
50
+ int mask = eventLoop->events[fd].mask & (~delmask);
51
+
52
+ ee.events = 0;
53
+ if (mask & AE_READABLE) ee.events |= EPOLLIN;
54
+ if (mask & AE_WRITABLE) ee.events |= EPOLLOUT;
55
+ ee.data.u64 = 0; /* avoid valgrind warning */
56
+ ee.data.fd = fd;
57
+ if (mask != AE_NONE) {
58
+ epoll_ctl(state->epfd,EPOLL_CTL_MOD,fd,&ee);
59
+ } else {
60
+ /* Note, Kernel < 2.6.9 requires a non null event pointer even for
61
+ * EPOLL_CTL_DEL. */
62
+ epoll_ctl(state->epfd,EPOLL_CTL_DEL,fd,&ee);
63
+ }
64
+ }
65
+
66
+ static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
67
+ aeApiState *state = eventLoop->apidata;
68
+ int retval, numevents = 0;
69
+
70
+ retval = epoll_wait(state->epfd,state->events,AE_SETSIZE,
71
+ tvp ? (tvp->tv_sec*1000 + tvp->tv_usec/1000) : -1);
72
+ if (retval > 0) {
73
+ int j;
74
+
75
+ numevents = retval;
76
+ for (j = 0; j < numevents; j++) {
77
+ int mask = 0;
78
+ struct epoll_event *e = state->events+j;
79
+
80
+ if (e->events & EPOLLIN) mask |= AE_READABLE;
81
+ if (e->events & EPOLLOUT) mask |= AE_WRITABLE;
82
+ eventLoop->fired[j].fd = e->data.fd;
83
+ eventLoop->fired[j].mask = mask;
84
+ }
85
+ }
86
+ return numevents;
87
+ }
88
+
89
+ static char *aeApiName(void) {
90
+ return "epoll";
91
+ }
@@ -0,0 +1,93 @@
1
+ /* Kqueue(2)-based ae.c module
2
+ * Copyright (C) 2009 Harish Mallipeddi - harish.mallipeddi@gmail.com
3
+ * Released under the BSD license. See the COPYING file for more info. */
4
+
5
+ #include <sys/types.h>
6
+ #include <sys/event.h>
7
+ #include <sys/time.h>
8
+
9
+ typedef struct aeApiState {
10
+ int kqfd;
11
+ struct kevent events[AE_SETSIZE];
12
+ } aeApiState;
13
+
14
+ static int aeApiCreate(aeEventLoop *eventLoop) {
15
+ aeApiState *state = zmalloc(sizeof(aeApiState));
16
+
17
+ if (!state) return -1;
18
+ state->kqfd = kqueue();
19
+ if (state->kqfd == -1) return -1;
20
+ eventLoop->apidata = state;
21
+
22
+ return 0;
23
+ }
24
+
25
+ static void aeApiFree(aeEventLoop *eventLoop) {
26
+ aeApiState *state = eventLoop->apidata;
27
+
28
+ close(state->kqfd);
29
+ zfree(state);
30
+ }
31
+
32
+ static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
33
+ aeApiState *state = eventLoop->apidata;
34
+ struct kevent ke;
35
+
36
+ if (mask & AE_READABLE) {
37
+ EV_SET(&ke, fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
38
+ if (kevent(state->kqfd, &ke, 1, NULL, 0, NULL) == -1) return -1;
39
+ }
40
+ if (mask & AE_WRITABLE) {
41
+ EV_SET(&ke, fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL);
42
+ if (kevent(state->kqfd, &ke, 1, NULL, 0, NULL) == -1) return -1;
43
+ }
44
+ return 0;
45
+ }
46
+
47
+ static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) {
48
+ aeApiState *state = eventLoop->apidata;
49
+ struct kevent ke;
50
+
51
+ if (mask & AE_READABLE) {
52
+ EV_SET(&ke, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
53
+ kevent(state->kqfd, &ke, 1, NULL, 0, NULL);
54
+ }
55
+ if (mask & AE_WRITABLE) {
56
+ EV_SET(&ke, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
57
+ kevent(state->kqfd, &ke, 1, NULL, 0, NULL);
58
+ }
59
+ }
60
+
61
+ static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
62
+ aeApiState *state = eventLoop->apidata;
63
+ int retval, numevents = 0;
64
+
65
+ if (tvp != NULL) {
66
+ struct timespec timeout;
67
+ timeout.tv_sec = tvp->tv_sec;
68
+ timeout.tv_nsec = tvp->tv_usec * 1000;
69
+ retval = kevent(state->kqfd, NULL, 0, state->events, AE_SETSIZE, &timeout);
70
+ } else {
71
+ retval = kevent(state->kqfd, NULL, 0, state->events, AE_SETSIZE, NULL);
72
+ }
73
+
74
+ if (retval > 0) {
75
+ int j;
76
+
77
+ numevents = retval;
78
+ for(j = 0; j < numevents; j++) {
79
+ int mask = 0;
80
+ struct kevent *e = state->events+j;
81
+
82
+ if (e->filter == EVFILT_READ) mask |= AE_READABLE;
83
+ if (e->filter == EVFILT_WRITE) mask |= AE_WRITABLE;
84
+ eventLoop->fired[j].fd = e->ident;
85
+ eventLoop->fired[j].mask = mask;
86
+ }
87
+ }
88
+ return numevents;
89
+ }
90
+
91
+ static char *aeApiName(void) {
92
+ return "kqueue";
93
+ }
@@ -0,0 +1,72 @@
1
+ /* Select()-based ae.c module
2
+ * Copyright (C) 2009-2010 Salvatore Sanfilippo - antirez@gmail.com
3
+ * Released under the BSD license. See the COPYING file for more info. */
4
+
5
+ #include <string.h>
6
+
7
+ typedef struct aeApiState {
8
+ fd_set rfds, wfds;
9
+ /* We need to have a copy of the fd sets as it's not safe to reuse
10
+ * FD sets after select(). */
11
+ fd_set _rfds, _wfds;
12
+ } aeApiState;
13
+
14
+ static int aeApiCreate(aeEventLoop *eventLoop) {
15
+ aeApiState *state = zmalloc(sizeof(aeApiState));
16
+
17
+ if (!state) return -1;
18
+ FD_ZERO(&state->rfds);
19
+ FD_ZERO(&state->wfds);
20
+ eventLoop->apidata = state;
21
+ return 0;
22
+ }
23
+
24
+ static void aeApiFree(aeEventLoop *eventLoop) {
25
+ zfree(eventLoop->apidata);
26
+ }
27
+
28
+ static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
29
+ aeApiState *state = eventLoop->apidata;
30
+
31
+ if (mask & AE_READABLE) FD_SET(fd,&state->rfds);
32
+ if (mask & AE_WRITABLE) FD_SET(fd,&state->wfds);
33
+ return 0;
34
+ }
35
+
36
+ static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) {
37
+ aeApiState *state = eventLoop->apidata;
38
+
39
+ if (mask & AE_READABLE) FD_CLR(fd,&state->rfds);
40
+ if (mask & AE_WRITABLE) FD_CLR(fd,&state->wfds);
41
+ }
42
+
43
+ static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
44
+ aeApiState *state = eventLoop->apidata;
45
+ int retval, j, numevents = 0;
46
+
47
+ memcpy(&state->_rfds,&state->rfds,sizeof(fd_set));
48
+ memcpy(&state->_wfds,&state->wfds,sizeof(fd_set));
49
+
50
+ retval = select(eventLoop->maxfd+1,
51
+ &state->_rfds,&state->_wfds,NULL,tvp);
52
+ if (retval > 0) {
53
+ for (j = 0; j <= eventLoop->maxfd; j++) {
54
+ int mask = 0;
55
+ aeFileEvent *fe = &eventLoop->events[j];
56
+
57
+ if (fe->mask == AE_NONE) continue;
58
+ if (fe->mask & AE_READABLE && FD_ISSET(j,&state->_rfds))
59
+ mask |= AE_READABLE;
60
+ if (fe->mask & AE_WRITABLE && FD_ISSET(j,&state->_wfds))
61
+ mask |= AE_WRITABLE;
62
+ eventLoop->fired[numevents].fd = j;
63
+ eventLoop->fired[numevents].mask = mask;
64
+ numevents++;
65
+ }
66
+ }
67
+ return numevents;
68
+ }
69
+
70
+ static char *aeApiName(void) {
71
+ return "select";
72
+ }
@@ -0,0 +1,347 @@
1
+ /* anet.c -- Basic TCP socket stuff made a bit less boring
2
+ *
3
+ * Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com>
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are met:
8
+ *
9
+ * * Redistributions of source code must retain the above copyright notice,
10
+ * this list of conditions and the following disclaimer.
11
+ * * Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ * * Neither the name of Redis nor the names of its contributors may be used
15
+ * to endorse or promote products derived from this software without
16
+ * specific prior written permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
+ * POSSIBILITY OF SUCH DAMAGE.
29
+ */
30
+
31
+ #include "fmacros.h"
32
+
33
+ #include <sys/types.h>
34
+ #include <sys/socket.h>
35
+ #include <sys/un.h>
36
+ #include <netinet/in.h>
37
+ #include <netinet/tcp.h>
38
+ #include <arpa/inet.h>
39
+ #include <unistd.h>
40
+ #include <fcntl.h>
41
+ #include <string.h>
42
+ #include <netdb.h>
43
+ #include <errno.h>
44
+ #include <stdarg.h>
45
+ #include <stdio.h>
46
+
47
+ #include "anet.h"
48
+
49
+ static void anetSetError(char *err, const char *fmt, ...)
50
+ {
51
+ va_list ap;
52
+
53
+ if (!err) return;
54
+ va_start(ap, fmt);
55
+ vsnprintf(err, ANET_ERR_LEN, fmt, ap);
56
+ va_end(ap);
57
+ }
58
+
59
+ int anetNonBlock(char *err, int fd)
60
+ {
61
+ int flags;
62
+
63
+ /* Set the socket nonblocking.
64
+ * Note that fcntl(2) for F_GETFL and F_SETFL can't be
65
+ * interrupted by a signal. */
66
+ if ((flags = fcntl(fd, F_GETFL)) == -1) {
67
+ anetSetError(err, "fcntl(F_GETFL): %s", strerror(errno));
68
+ return ANET_ERR;
69
+ }
70
+ if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
71
+ anetSetError(err, "fcntl(F_SETFL,O_NONBLOCK): %s", strerror(errno));
72
+ return ANET_ERR;
73
+ }
74
+ return ANET_OK;
75
+ }
76
+
77
+ int anetTcpNoDelay(char *err, int fd)
78
+ {
79
+ int yes = 1;
80
+ if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1)
81
+ {
82
+ anetSetError(err, "setsockopt TCP_NODELAY: %s", strerror(errno));
83
+ return ANET_ERR;
84
+ }
85
+ return ANET_OK;
86
+ }
87
+
88
+ int anetSetSendBuffer(char *err, int fd, int buffsize)
89
+ {
90
+ if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buffsize, sizeof(buffsize)) == -1)
91
+ {
92
+ anetSetError(err, "setsockopt SO_SNDBUF: %s", strerror(errno));
93
+ return ANET_ERR;
94
+ }
95
+ return ANET_OK;
96
+ }
97
+
98
+ int anetTcpKeepAlive(char *err, int fd)
99
+ {
100
+ int yes = 1;
101
+ if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(yes)) == -1) {
102
+ anetSetError(err, "setsockopt SO_KEEPALIVE: %s", strerror(errno));
103
+ return ANET_ERR;
104
+ }
105
+ return ANET_OK;
106
+ }
107
+
108
+ int anetResolve(char *err, char *host, char *ipbuf)
109
+ {
110
+ struct sockaddr_in sa;
111
+
112
+ sa.sin_family = AF_INET;
113
+ if (inet_aton(host, &sa.sin_addr) == 0) {
114
+ struct hostent *he;
115
+
116
+ he = gethostbyname(host);
117
+ if (he == NULL) {
118
+ anetSetError(err, "can't resolve: %s", host);
119
+ return ANET_ERR;
120
+ }
121
+ memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr));
122
+ }
123
+ strcpy(ipbuf,inet_ntoa(sa.sin_addr));
124
+ return ANET_OK;
125
+ }
126
+
127
+ static int anetCreateSocket(char *err, int domain) {
128
+ int s, on = 1;
129
+ if ((s = socket(domain, SOCK_STREAM, 0)) == -1) {
130
+ anetSetError(err, "creating socket: %s", strerror(errno));
131
+ return ANET_ERR;
132
+ }
133
+
134
+ /* Make sure connection-intensive things like the redis benckmark
135
+ * will be able to close/open sockets a zillion of times */
136
+ if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
137
+ anetSetError(err, "setsockopt SO_REUSEADDR: %s", strerror(errno));
138
+ return ANET_ERR;
139
+ }
140
+ return s;
141
+ }
142
+
143
+ #define ANET_CONNECT_NONE 0
144
+ #define ANET_CONNECT_NONBLOCK 1
145
+ static int anetTcpGenericConnect(char *err, char *addr, int port, int flags)
146
+ {
147
+ int s;
148
+ struct sockaddr_in sa;
149
+
150
+ if ((s = anetCreateSocket(err,AF_INET)) == ANET_ERR)
151
+ return ANET_ERR;
152
+
153
+ sa.sin_family = AF_INET;
154
+ sa.sin_port = htons(port);
155
+ if (inet_aton(addr, &sa.sin_addr) == 0) {
156
+ struct hostent *he;
157
+
158
+ he = gethostbyname(addr);
159
+ if (he == NULL) {
160
+ anetSetError(err, "can't resolve: %s", addr);
161
+ close(s);
162
+ return ANET_ERR;
163
+ }
164
+ memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr));
165
+ }
166
+ if (flags & ANET_CONNECT_NONBLOCK) {
167
+ if (anetNonBlock(err,s) != ANET_OK)
168
+ return ANET_ERR;
169
+ }
170
+ if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) == -1) {
171
+ if (errno == EINPROGRESS &&
172
+ flags & ANET_CONNECT_NONBLOCK)
173
+ return s;
174
+
175
+ anetSetError(err, "connect: %s", strerror(errno));
176
+ close(s);
177
+ return ANET_ERR;
178
+ }
179
+ return s;
180
+ }
181
+
182
+ int anetTcpConnect(char *err, char *addr, int port)
183
+ {
184
+ return anetTcpGenericConnect(err,addr,port,ANET_CONNECT_NONE);
185
+ }
186
+
187
+ int anetTcpNonBlockConnect(char *err, char *addr, int port)
188
+ {
189
+ return anetTcpGenericConnect(err,addr,port,ANET_CONNECT_NONBLOCK);
190
+ }
191
+
192
+ int anetUnixGenericConnect(char *err, char *path, int flags)
193
+ {
194
+ int s;
195
+ struct sockaddr_un sa;
196
+
197
+ if ((s = anetCreateSocket(err,AF_LOCAL)) == ANET_ERR)
198
+ return ANET_ERR;
199
+
200
+ sa.sun_family = AF_LOCAL;
201
+ strncpy(sa.sun_path,path,sizeof(sa.sun_path)-1);
202
+ if (flags & ANET_CONNECT_NONBLOCK) {
203
+ if (anetNonBlock(err,s) != ANET_OK)
204
+ return ANET_ERR;
205
+ }
206
+ if (connect(s,(struct sockaddr*)&sa,sizeof(sa)) == -1) {
207
+ if (errno == EINPROGRESS &&
208
+ flags & ANET_CONNECT_NONBLOCK)
209
+ return s;
210
+
211
+ anetSetError(err, "connect: %s", strerror(errno));
212
+ close(s);
213
+ return ANET_ERR;
214
+ }
215
+ return s;
216
+ }
217
+
218
+ int anetUnixConnect(char *err, char *path)
219
+ {
220
+ return anetUnixGenericConnect(err,path,ANET_CONNECT_NONE);
221
+ }
222
+
223
+ int anetUnixNonBlockConnect(char *err, char *path)
224
+ {
225
+ return anetUnixGenericConnect(err,path,ANET_CONNECT_NONBLOCK);
226
+ }
227
+
228
+ /* Like read(2) but make sure 'count' is read before to return
229
+ * (unless error or EOF condition is encountered) */
230
+ int anetRead(int fd, char *buf, int count)
231
+ {
232
+ int nread, totlen = 0;
233
+ while(totlen != count) {
234
+ nread = read(fd,buf,count-totlen);
235
+ if (nread == 0) return totlen;
236
+ if (nread == -1) return -1;
237
+ totlen += nread;
238
+ buf += nread;
239
+ }
240
+ return totlen;
241
+ }
242
+
243
+ /* Like write(2) but make sure 'count' is read before to return
244
+ * (unless error is encountered) */
245
+ int anetWrite(int fd, char *buf, int count)
246
+ {
247
+ int nwritten, totlen = 0;
248
+ while(totlen != count) {
249
+ nwritten = write(fd,buf,count-totlen);
250
+ if (nwritten == 0) return totlen;
251
+ if (nwritten == -1) return -1;
252
+ totlen += nwritten;
253
+ buf += nwritten;
254
+ }
255
+ return totlen;
256
+ }
257
+
258
+ static int anetListen(char *err, int s, struct sockaddr *sa, socklen_t len) {
259
+ if (bind(s,sa,len) == -1) {
260
+ anetSetError(err, "bind: %s", strerror(errno));
261
+ close(s);
262
+ return ANET_ERR;
263
+ }
264
+ if (listen(s, 511) == -1) { /* the magic 511 constant is from nginx */
265
+ anetSetError(err, "listen: %s", strerror(errno));
266
+ close(s);
267
+ return ANET_ERR;
268
+ }
269
+ return ANET_OK;
270
+ }
271
+
272
+ int anetTcpServer(char *err, int port, char *bindaddr)
273
+ {
274
+ int s;
275
+ struct sockaddr_in sa;
276
+
277
+ if ((s = anetCreateSocket(err,AF_INET)) == ANET_ERR)
278
+ return ANET_ERR;
279
+
280
+ memset(&sa,0,sizeof(sa));
281
+ sa.sin_family = AF_INET;
282
+ sa.sin_port = htons(port);
283
+ sa.sin_addr.s_addr = htonl(INADDR_ANY);
284
+ if (bindaddr && inet_aton(bindaddr, &sa.sin_addr) == 0) {
285
+ anetSetError(err, "invalid bind address");
286
+ close(s);
287
+ return ANET_ERR;
288
+ }
289
+ if (anetListen(err,s,(struct sockaddr*)&sa,sizeof(sa)) == ANET_ERR)
290
+ return ANET_ERR;
291
+ return s;
292
+ }
293
+
294
+ int anetUnixServer(char *err, char *path)
295
+ {
296
+ int s;
297
+ struct sockaddr_un sa;
298
+
299
+ if ((s = anetCreateSocket(err,AF_LOCAL)) == ANET_ERR)
300
+ return ANET_ERR;
301
+
302
+ memset(&sa,0,sizeof(sa));
303
+ sa.sun_family = AF_LOCAL;
304
+ strncpy(sa.sun_path,path,sizeof(sa.sun_path)-1);
305
+ if (anetListen(err,s,(struct sockaddr*)&sa,sizeof(sa)) == ANET_ERR)
306
+ return ANET_ERR;
307
+ return s;
308
+ }
309
+
310
+ static int anetGenericAccept(char *err, int s, struct sockaddr *sa, socklen_t *len) {
311
+ int fd;
312
+ while(1) {
313
+ fd = accept(s,sa,len);
314
+ if (fd == -1) {
315
+ if (errno == EINTR)
316
+ continue;
317
+ else {
318
+ anetSetError(err, "accept: %s", strerror(errno));
319
+ return ANET_ERR;
320
+ }
321
+ }
322
+ break;
323
+ }
324
+ return fd;
325
+ }
326
+
327
+ int anetTcpAccept(char *err, int s, char *ip, int *port) {
328
+ int fd;
329
+ struct sockaddr_in sa;
330
+ socklen_t salen = sizeof(sa);
331
+ if ((fd = anetGenericAccept(err,s,(struct sockaddr*)&sa,&salen)) == ANET_ERR)
332
+ return ANET_ERR;
333
+
334
+ if (ip) strcpy(ip,inet_ntoa(sa.sin_addr));
335
+ if (port) *port = ntohs(sa.sin_port);
336
+ return fd;
337
+ }
338
+
339
+ int anetUnixAccept(char *err, int s) {
340
+ int fd;
341
+ struct sockaddr_un sa;
342
+ socklen_t salen = sizeof(sa);
343
+ if ((fd = anetGenericAccept(err,s,(struct sockaddr*)&sa,&salen)) == ANET_ERR)
344
+ return ANET_ERR;
345
+
346
+ return fd;
347
+ }