rbczmq 1.7.1 → 1.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (437) hide show
  1. checksums.yaml +8 -8
  2. data/.gitmodules +1 -1
  3. data/CHANGELOG.rdoc +4 -0
  4. data/Gemfile.lock +1 -1
  5. data/README.rdoc +5 -4
  6. data/ext/czmq/.gitignore +5 -0
  7. data/ext/czmq/.travis.yml +10 -1
  8. data/ext/czmq/AUTHORS +2 -0
  9. data/ext/czmq/COPYING.LESSER +3 -0
  10. data/ext/czmq/Makefile.am +13 -3
  11. data/ext/czmq/NEWS +132 -0
  12. data/ext/czmq/README.md +1553 -615
  13. data/ext/czmq/README.txt +188 -72
  14. data/ext/czmq/addons/Makefile.am +9 -0
  15. data/ext/czmq/addons/makecert.c +72 -0
  16. data/ext/czmq/builds/mingw32/Makefile.mingw32 +11 -3
  17. data/ext/czmq/builds/msvc/.gitignore +4 -1
  18. data/ext/czmq/builds/msvc/czmq.vcproj +4 -0
  19. data/ext/czmq/builds/msvc/czmq.vcxproj +6 -1
  20. data/ext/czmq/builds/msvc/czmq.vcxproj.filters +4 -1
  21. data/ext/{zeromq/cmake/Modules/zmq_version.cpp → czmq/builds/msvc/platform.h} +10 -9
  22. data/ext/czmq/configure.ac +64 -5
  23. data/ext/czmq/doc/Makefile.am +8 -1
  24. data/ext/czmq/doc/mkmans +17 -0
  25. data/ext/czmq/doc/zauth.txt +191 -0
  26. data/ext/czmq/doc/zbeacon.txt +13 -22
  27. data/ext/czmq/doc/zcert.txt +122 -0
  28. data/ext/czmq/doc/zcertstore.txt +107 -0
  29. data/ext/czmq/doc/zchunk.txt +77 -0
  30. data/ext/czmq/doc/zclock.txt +8 -0
  31. data/ext/czmq/doc/zconfig.txt +9 -63
  32. data/ext/czmq/doc/zctx.txt +26 -7
  33. data/ext/czmq/doc/zdir.txt +83 -0
  34. data/ext/czmq/doc/zfile.txt +130 -35
  35. data/ext/czmq/doc/zframe.txt +6 -39
  36. data/ext/czmq/doc/zhash.txt +55 -10
  37. data/ext/czmq/doc/zlist.txt +2 -4
  38. data/ext/czmq/doc/zloop.txt +7 -1
  39. data/ext/czmq/doc/zmsg.txt +75 -32
  40. data/ext/czmq/doc/zpoller.txt +88 -0
  41. data/ext/czmq/doc/zsocket.txt +50 -1
  42. data/ext/czmq/doc/zsockopt.txt +185 -251
  43. data/ext/czmq/doc/zstr.txt +14 -3
  44. data/ext/czmq/doc/zsys.txt +89 -1
  45. data/ext/czmq/doc/ztree.txt +21 -11
  46. data/ext/czmq/examples/security/LICENSE +18 -0
  47. data/ext/czmq/examples/security/README.txt +9 -0
  48. data/ext/czmq/examples/security/grasslands.c +29 -0
  49. data/ext/czmq/examples/security/hello.c +10 -0
  50. data/ext/czmq/examples/security/ironhouse.c +55 -0
  51. data/ext/czmq/examples/security/ironhouse2.c +103 -0
  52. data/ext/czmq/examples/security/stonehouse.c +51 -0
  53. data/ext/czmq/examples/security/strawhouse.c +44 -0
  54. data/ext/czmq/examples/security/woodhouse.c +40 -0
  55. data/ext/czmq/images/README_1.png +0 -0
  56. data/ext/czmq/images/README_2.png +0 -0
  57. data/ext/czmq/include/czmq.h +10 -4
  58. data/ext/czmq/include/czmq_prelude.h +42 -42
  59. data/ext/czmq/include/zauth.h +97 -0
  60. data/ext/czmq/include/zbeacon.h +0 -5
  61. data/ext/czmq/include/zcert.h +118 -0
  62. data/ext/czmq/include/zcertstore.h +78 -0
  63. data/ext/czmq/include/zchunk.h +87 -0
  64. data/ext/czmq/include/zclock.h +4 -0
  65. data/ext/czmq/include/zconfig.h +21 -12
  66. data/ext/czmq/include/zctx.h +34 -11
  67. data/ext/czmq/include/zdir.h +90 -0
  68. data/ext/czmq/include/zfile.h +104 -25
  69. data/ext/czmq/include/zframe.h +7 -20
  70. data/ext/czmq/include/zhash.h +13 -0
  71. data/ext/czmq/include/zlist.h +0 -4
  72. data/ext/czmq/include/zloop.h +5 -5
  73. data/ext/czmq/include/zmsg.h +59 -29
  74. data/ext/czmq/include/zmutex.h +5 -0
  75. data/ext/czmq/include/zpoller.h +72 -0
  76. data/ext/czmq/include/zsocket.h +12 -15
  77. data/ext/czmq/include/zsockopt.h +124 -121
  78. data/ext/czmq/include/zstr.h +12 -9
  79. data/ext/czmq/include/zsys.h +50 -2
  80. data/ext/czmq/mkdoc +1 -1
  81. data/ext/czmq/model/sockopts.xml +101 -21
  82. data/ext/czmq/scripts/sockopts.gsl +95 -41
  83. data/ext/czmq/src/Makefile.am +13 -0
  84. data/ext/czmq/src/czmq_selftest.c +16 -10
  85. data/ext/czmq/src/selftest +2 -2
  86. data/ext/czmq/src/zauth.c +714 -0
  87. data/ext/czmq/src/zbeacon.c +27 -35
  88. data/ext/czmq/src/zcert.c +463 -0
  89. data/ext/czmq/src/zcertstore.c +265 -0
  90. data/ext/czmq/src/zchunk.c +207 -0
  91. data/ext/czmq/src/zclock.c +18 -0
  92. data/ext/czmq/src/zconfig.c +116 -99
  93. data/ext/czmq/src/zctx.c +103 -18
  94. data/ext/czmq/src/zdir.c +409 -0
  95. data/ext/czmq/src/zfile.c +421 -130
  96. data/ext/czmq/src/zframe.c +28 -127
  97. data/ext/czmq/src/zhash.c +255 -139
  98. data/ext/czmq/src/zlist.c +2 -8
  99. data/ext/czmq/src/zloop.c +40 -13
  100. data/ext/czmq/src/zmsg.c +109 -141
  101. data/ext/czmq/src/zmutex.c +27 -1
  102. data/ext/czmq/src/zpoller.c +218 -0
  103. data/ext/czmq/src/zsocket.c +53 -66
  104. data/ext/czmq/src/zsockopt.c +2337 -682
  105. data/ext/czmq/src/zstr.c +48 -118
  106. data/ext/czmq/src/zsys.c +270 -3
  107. data/ext/czmq/src/zthread.c +2 -2
  108. data/ext/czmq/src/ztree.c +179 -180
  109. data/ext/rbczmq/beacon.c +1 -1
  110. data/ext/rbczmq/context.c +12 -3
  111. data/ext/rbczmq/context.h +7 -0
  112. data/ext/rbczmq/extconf.rb +13 -4
  113. data/ext/rbczmq/pollitem.c +1 -1
  114. data/ext/rbczmq/socket.c +34 -24
  115. data/ext/rbczmq/socket.h +3 -2
  116. data/ext/zeromq/AUTHORS +17 -3
  117. data/ext/zeromq/CMakeLists.txt +742 -339
  118. data/ext/zeromq/COPYING.LESSER +2 -0
  119. data/ext/zeromq/Makefile.am +3 -3
  120. data/ext/zeromq/NEWS +130 -1
  121. data/ext/zeromq/{README → README.md} +8 -9
  122. data/ext/zeromq/builds/cmake/Modules/FindAsciiDoc.cmake +24 -0
  123. data/ext/zeromq/builds/cmake/Modules/TestZMQVersion.cmake +18 -0
  124. data/ext/zeromq/builds/cmake/Modules/ZMQSourceRunChecks.cmake +129 -0
  125. data/ext/zeromq/{cmake → builds/cmake}/NSIS.template32.in +1 -1
  126. data/ext/zeromq/{cmake → builds/cmake}/NSIS.template64.in +1 -1
  127. data/ext/zeromq/builds/cmake/platform.hpp.in +88 -0
  128. data/ext/zeromq/builds/mingw32/Makefile.mingw32 +47 -0
  129. data/ext/zeromq/{src/i_msg_sink.hpp → builds/mingw32/platform.hpp} +10 -21
  130. data/ext/zeromq/builds/msvc/Makefile.am +5 -2
  131. data/ext/zeromq/builds/msvc/c_local_lat/c_local_lat.vcxproj +1 -1
  132. data/ext/zeromq/builds/msvc/c_local_lat/c_local_lat11.vcxproj +91 -0
  133. data/ext/zeromq/builds/msvc/c_local_thr/c_local_thr.vcproj +2 -0
  134. data/ext/zeromq/builds/msvc/c_local_thr/c_local_thr.vcxproj +21 -1
  135. data/ext/zeromq/builds/msvc/c_local_thr/c_local_thr11.vcxproj +111 -0
  136. data/ext/zeromq/builds/msvc/c_remote_lat/c_remote_lat.vcxproj +1 -1
  137. data/ext/zeromq/builds/msvc/c_remote_lat/c_remote_lat11.vcxproj +91 -0
  138. data/ext/zeromq/builds/msvc/c_remote_thr/c_remote_thr.vcproj +2 -0
  139. data/ext/zeromq/builds/msvc/c_remote_thr/c_remote_thr.vcxproj +21 -1
  140. data/ext/zeromq/builds/msvc/c_remote_thr/c_remote_thr11.vcxproj +111 -0
  141. data/ext/zeromq/builds/msvc/errno.cpp +1 -1
  142. data/ext/zeromq/builds/msvc/errno.hpp +1 -1
  143. data/ext/zeromq/builds/msvc/inproc_lat/inproc_lat.vcproj +176 -174
  144. data/ext/zeromq/builds/msvc/inproc_lat/inproc_lat.vcxproj +21 -1
  145. data/ext/zeromq/builds/msvc/inproc_lat/inproc_lat11.vcxproj +110 -0
  146. data/ext/zeromq/builds/msvc/inproc_thr/inproc_thr.vcproj +176 -174
  147. data/ext/zeromq/builds/msvc/inproc_thr/inproc_thr.vcxproj +21 -1
  148. data/ext/zeromq/builds/msvc/inproc_thr/inproc_thr11.vcxproj +110 -0
  149. data/ext/zeromq/builds/msvc/libzmq/libzmq.vcproj +997 -804
  150. data/ext/zeromq/builds/msvc/libzmq/libzmq.vcxproj +78 -2
  151. data/ext/zeromq/builds/msvc/libzmq/libzmq.vcxproj.filters +42 -6
  152. data/ext/zeromq/builds/msvc/libzmq/libzmq11.vcxproj +362 -0
  153. data/ext/zeromq/builds/msvc/msvc.sln +6 -0
  154. data/ext/zeromq/builds/msvc/msvc10.sln +36 -2
  155. data/ext/zeromq/builds/msvc/msvc11.sln +150 -0
  156. data/ext/zeromq/builds/msvc/properties/Static.props +15 -0
  157. data/ext/zeromq/builds/msvc/properties/ZeroMQ.props +0 -1
  158. data/ext/zeromq/builds/msvc/properties/ZeroMQ_Static.props +23 -0
  159. data/ext/zeromq/builds/redhat/zeromq.spec.in +2 -1
  160. data/ext/zeromq/{configure.in → configure.ac} +74 -15
  161. data/ext/zeromq/doc/Makefile.am +6 -4
  162. data/ext/zeromq/doc/zmq.txt +30 -3
  163. data/ext/zeromq/doc/zmq_bind.txt +2 -2
  164. data/ext/zeromq/doc/zmq_close.txt +2 -2
  165. data/ext/zeromq/doc/zmq_connect.txt +9 -7
  166. data/ext/zeromq/doc/zmq_ctx_destroy.txt +4 -3
  167. data/ext/zeromq/doc/zmq_ctx_get.txt +8 -3
  168. data/ext/zeromq/doc/zmq_ctx_new.txt +3 -2
  169. data/ext/zeromq/doc/zmq_ctx_set.txt +13 -1
  170. data/ext/zeromq/doc/zmq_ctx_shutdown.txt +52 -0
  171. data/ext/zeromq/doc/zmq_ctx_term.txt +67 -0
  172. data/ext/zeromq/doc/zmq_curve.txt +92 -0
  173. data/ext/zeromq/doc/zmq_curve_keypair.txt +56 -0
  174. data/ext/zeromq/doc/zmq_disconnect.txt +2 -2
  175. data/ext/zeromq/doc/zmq_epgm.txt +5 -4
  176. data/ext/zeromq/doc/zmq_errno.txt +2 -2
  177. data/ext/zeromq/doc/zmq_getsockopt.txt +149 -24
  178. data/ext/zeromq/doc/zmq_init.txt +2 -2
  179. data/ext/zeromq/doc/zmq_inproc.txt +2 -2
  180. data/ext/zeromq/doc/zmq_ipc.txt +10 -5
  181. data/ext/zeromq/doc/zmq_msg_close.txt +4 -3
  182. data/ext/zeromq/doc/zmq_msg_copy.txt +2 -2
  183. data/ext/zeromq/doc/zmq_msg_data.txt +2 -2
  184. data/ext/zeromq/doc/zmq_msg_get.txt +3 -3
  185. data/ext/zeromq/doc/zmq_msg_init.txt +2 -2
  186. data/ext/zeromq/doc/zmq_msg_init_data.txt +2 -2
  187. data/ext/zeromq/doc/zmq_msg_init_size.txt +2 -2
  188. data/ext/zeromq/doc/zmq_msg_more.txt +6 -4
  189. data/ext/zeromq/doc/zmq_msg_move.txt +2 -2
  190. data/ext/zeromq/doc/zmq_msg_recv.txt +3 -4
  191. data/ext/zeromq/doc/zmq_msg_send.txt +10 -7
  192. data/ext/zeromq/doc/zmq_msg_set.txt +2 -1
  193. data/ext/zeromq/doc/zmq_msg_size.txt +2 -2
  194. data/ext/zeromq/doc/zmq_null.txt +27 -0
  195. data/ext/zeromq/doc/zmq_pgm.txt +5 -4
  196. data/ext/zeromq/doc/zmq_plain.txt +37 -0
  197. data/ext/zeromq/doc/zmq_poll.txt +2 -6
  198. data/ext/zeromq/doc/zmq_proxy.txt +2 -1
  199. data/ext/zeromq/doc/zmq_recv.txt +2 -5
  200. data/ext/zeromq/doc/zmq_recvmsg.txt +3 -5
  201. data/ext/zeromq/doc/zmq_send.txt +9 -7
  202. data/ext/zeromq/doc/zmq_send_const.txt +103 -0
  203. data/ext/zeromq/doc/zmq_sendmsg.txt +8 -8
  204. data/ext/zeromq/doc/zmq_setsockopt.txt +291 -37
  205. data/ext/zeromq/doc/zmq_socket.txt +92 -21
  206. data/ext/zeromq/doc/zmq_socket_monitor.txt +102 -131
  207. data/ext/zeromq/doc/zmq_strerror.txt +3 -2
  208. data/ext/zeromq/doc/zmq_tcp.txt +4 -2
  209. data/ext/zeromq/doc/zmq_term.txt +3 -3
  210. data/ext/zeromq/doc/zmq_unbind.txt +2 -2
  211. data/ext/zeromq/doc/zmq_version.txt +3 -2
  212. data/ext/zeromq/doc/zmq_z85_decode.txt +50 -0
  213. data/ext/zeromq/doc/zmq_z85_encode.txt +57 -0
  214. data/ext/zeromq/foreign/openpgm/libpgm-5.2.122~dfsg.tar.gz +0 -0
  215. data/ext/zeromq/include/zmq.h +179 -136
  216. data/ext/zeromq/include/zmq_utils.h +44 -3
  217. data/ext/zeromq/perf/inproc_lat.cpp +2 -4
  218. data/ext/zeromq/perf/inproc_thr.cpp +1 -1
  219. data/ext/zeromq/perf/local_lat.cpp +1 -3
  220. data/ext/zeromq/perf/local_thr.cpp +1 -3
  221. data/ext/zeromq/perf/remote_lat.cpp +1 -3
  222. data/ext/zeromq/perf/remote_thr.cpp +1 -8
  223. data/ext/zeromq/src/Makefile.am +26 -7
  224. data/ext/zeromq/src/address.cpp +7 -8
  225. data/ext/zeromq/src/address.hpp +1 -2
  226. data/ext/zeromq/src/array.hpp +1 -3
  227. data/ext/zeromq/src/atomic_counter.hpp +11 -3
  228. data/ext/zeromq/src/atomic_ptr.hpp +9 -3
  229. data/ext/zeromq/src/blob.hpp +2 -2
  230. data/ext/zeromq/src/clock.cpp +3 -4
  231. data/ext/zeromq/src/clock.hpp +1 -2
  232. data/ext/zeromq/src/command.hpp +2 -3
  233. data/ext/zeromq/src/config.hpp +1 -3
  234. data/ext/zeromq/src/ctx.cpp +154 -15
  235. data/ext/zeromq/src/ctx.hpp +34 -3
  236. data/ext/zeromq/src/curve_client.cpp +410 -0
  237. data/ext/zeromq/src/curve_client.hpp +109 -0
  238. data/ext/zeromq/src/curve_server.cpp +629 -0
  239. data/ext/zeromq/src/curve_server.hpp +120 -0
  240. data/ext/zeromq/src/dbuffer.hpp +134 -0
  241. data/ext/zeromq/src/dealer.cpp +52 -60
  242. data/ext/zeromq/src/dealer.hpp +12 -26
  243. data/ext/zeromq/src/decoder.hpp +27 -102
  244. data/ext/zeromq/src/devpoll.cpp +1 -3
  245. data/ext/zeromq/src/devpoll.hpp +1 -3
  246. data/ext/zeromq/src/dist.cpp +17 -15
  247. data/ext/zeromq/src/dist.hpp +5 -6
  248. data/ext/zeromq/src/encoder.hpp +32 -52
  249. data/ext/zeromq/src/epoll.cpp +1 -3
  250. data/ext/zeromq/src/epoll.hpp +1 -3
  251. data/ext/zeromq/src/err.cpp +2 -4
  252. data/ext/zeromq/src/err.hpp +7 -4
  253. data/ext/zeromq/src/fd.hpp +1 -2
  254. data/ext/zeromq/src/fq.cpp +2 -5
  255. data/ext/zeromq/src/fq.hpp +2 -4
  256. data/ext/zeromq/src/i_decoder.hpp +11 -9
  257. data/ext/zeromq/src/i_encoder.hpp +7 -11
  258. data/ext/zeromq/src/i_engine.hpp +3 -3
  259. data/ext/zeromq/src/i_poll_events.hpp +1 -3
  260. data/ext/zeromq/src/io_object.cpp +1 -3
  261. data/ext/zeromq/src/io_object.hpp +1 -3
  262. data/ext/zeromq/src/io_thread.cpp +1 -3
  263. data/ext/zeromq/src/io_thread.hpp +1 -3
  264. data/ext/zeromq/src/ip.cpp +46 -5
  265. data/ext/zeromq/src/ip.hpp +7 -4
  266. data/ext/zeromq/src/ipc_address.cpp +13 -2
  267. data/ext/zeromq/src/ipc_address.hpp +1 -2
  268. data/ext/zeromq/src/ipc_connecter.cpp +3 -3
  269. data/ext/zeromq/src/ipc_connecter.hpp +1 -2
  270. data/ext/zeromq/src/ipc_listener.cpp +15 -10
  271. data/ext/zeromq/src/ipc_listener.hpp +1 -2
  272. data/ext/zeromq/src/kqueue.cpp +11 -3
  273. data/ext/zeromq/src/kqueue.hpp +7 -3
  274. data/ext/zeromq/src/lb.cpp +13 -11
  275. data/ext/zeromq/src/lb.hpp +10 -5
  276. data/ext/zeromq/src/libzmq.pc.cmake.in +10 -0
  277. data/ext/zeromq/src/likely.hpp +1 -2
  278. data/ext/zeromq/src/mailbox.cpp +1 -4
  279. data/ext/zeromq/src/mailbox.hpp +8 -3
  280. data/ext/zeromq/src/mechanism.cpp +163 -0
  281. data/ext/zeromq/src/mechanism.hpp +101 -0
  282. data/ext/zeromq/src/msg.cpp +38 -18
  283. data/ext/zeromq/src/msg.hpp +19 -7
  284. data/ext/zeromq/src/mtrie.cpp +16 -14
  285. data/ext/zeromq/src/mtrie.hpp +1 -3
  286. data/ext/zeromq/src/mutex.hpp +42 -3
  287. data/ext/zeromq/src/null_mechanism.cpp +282 -0
  288. data/ext/zeromq/src/null_mechanism.hpp +65 -0
  289. data/ext/zeromq/src/object.cpp +29 -3
  290. data/ext/zeromq/src/object.hpp +8 -5
  291. data/ext/zeromq/src/options.cpp +557 -485
  292. data/ext/zeromq/src/options.hpp +38 -24
  293. data/ext/zeromq/src/own.cpp +1 -2
  294. data/ext/zeromq/src/own.hpp +1 -2
  295. data/ext/zeromq/src/pair.cpp +8 -25
  296. data/ext/zeromq/src/pair.hpp +5 -22
  297. data/ext/zeromq/src/pgm_receiver.cpp +80 -67
  298. data/ext/zeromq/src/pgm_receiver.hpp +11 -10
  299. data/ext/zeromq/src/pgm_sender.cpp +37 -16
  300. data/ext/zeromq/src/pgm_sender.hpp +12 -6
  301. data/ext/zeromq/src/pgm_socket.cpp +8 -8
  302. data/ext/zeromq/src/pgm_socket.hpp +1 -4
  303. data/ext/zeromq/src/pipe.cpp +110 -72
  304. data/ext/zeromq/src/pipe.hpp +36 -27
  305. data/ext/zeromq/src/plain_mechanism.cpp +482 -0
  306. data/ext/zeromq/src/plain_mechanism.hpp +88 -0
  307. data/ext/zeromq/src/poll.cpp +1 -3
  308. data/ext/zeromq/src/poll.hpp +1 -3
  309. data/ext/zeromq/src/poller.hpp +1 -3
  310. data/ext/zeromq/src/poller_base.cpp +3 -3
  311. data/ext/zeromq/src/poller_base.hpp +1 -2
  312. data/ext/zeromq/src/precompiled.cpp +1 -2
  313. data/ext/zeromq/src/precompiled.hpp +1 -2
  314. data/ext/zeromq/src/proxy.cpp +1 -2
  315. data/ext/zeromq/src/proxy.hpp +1 -2
  316. data/ext/zeromq/src/pub.cpp +2 -16
  317. data/ext/zeromq/src/pub.hpp +2 -19
  318. data/ext/zeromq/src/pull.cpp +7 -24
  319. data/ext/zeromq/src/pull.hpp +4 -21
  320. data/ext/zeromq/src/push.cpp +8 -22
  321. data/ext/zeromq/src/push.hpp +4 -21
  322. data/ext/zeromq/src/random.cpp +1 -2
  323. data/ext/zeromq/src/random.hpp +1 -2
  324. data/ext/zeromq/src/raw_decoder.cpp +63 -0
  325. data/ext/zeromq/src/raw_decoder.hpp +66 -0
  326. data/ext/zeromq/src/raw_encoder.cpp +40 -0
  327. data/ext/zeromq/src/raw_encoder.hpp +60 -0
  328. data/ext/zeromq/src/reaper.cpp +12 -2
  329. data/ext/zeromq/src/reaper.hpp +6 -2
  330. data/ext/zeromq/src/rep.cpp +7 -21
  331. data/ext/zeromq/src/rep.hpp +3 -20
  332. data/ext/zeromq/src/req.cpp +132 -38
  333. data/ext/zeromq/src/req.hpp +27 -8
  334. data/ext/zeromq/src/router.cpp +109 -65
  335. data/ext/zeromq/src/router.hpp +9 -23
  336. data/ext/zeromq/src/select.cpp +1 -3
  337. data/ext/zeromq/src/select.hpp +1 -3
  338. data/ext/zeromq/src/session_base.cpp +164 -118
  339. data/ext/zeromq/src/session_base.hpp +29 -22
  340. data/ext/zeromq/src/signaler.cpp +127 -19
  341. data/ext/zeromq/src/signaler.hpp +20 -3
  342. data/ext/zeromq/src/socket_base.cpp +167 -134
  343. data/ext/zeromq/src/socket_base.hpp +18 -20
  344. data/ext/zeromq/src/stdint.hpp +1 -2
  345. data/ext/zeromq/src/stream.cpp +257 -0
  346. data/ext/zeromq/src/stream.hpp +97 -0
  347. data/ext/zeromq/src/stream_engine.cpp +405 -157
  348. data/ext/zeromq/src/stream_engine.hpp +72 -23
  349. data/ext/zeromq/src/sub.cpp +5 -18
  350. data/ext/zeromq/src/sub.hpp +2 -19
  351. data/ext/zeromq/src/tcp.cpp +23 -3
  352. data/ext/zeromq/src/tcp.hpp +7 -3
  353. data/ext/zeromq/src/tcp_address.cpp +35 -46
  354. data/ext/zeromq/src/tcp_address.hpp +7 -12
  355. data/ext/zeromq/src/tcp_connecter.cpp +10 -5
  356. data/ext/zeromq/src/tcp_connecter.hpp +1 -3
  357. data/ext/zeromq/src/tcp_listener.cpp +19 -8
  358. data/ext/zeromq/src/tcp_listener.hpp +1 -3
  359. data/ext/zeromq/src/thread.cpp +2 -4
  360. data/ext/zeromq/src/thread.hpp +1 -3
  361. data/ext/zeromq/src/trie.cpp +122 -125
  362. data/ext/zeromq/src/trie.hpp +1 -4
  363. data/ext/zeromq/src/v1_decoder.cpp +77 -91
  364. data/ext/zeromq/src/v1_decoder.hpp +10 -21
  365. data/ext/zeromq/src/v1_encoder.cpp +24 -62
  366. data/ext/zeromq/src/v1_encoder.hpp +7 -18
  367. data/ext/zeromq/src/v2_decoder.cpp +142 -0
  368. data/ext/zeromq/src/v2_decoder.hpp +57 -0
  369. data/ext/zeromq/src/v2_encoder.cpp +67 -0
  370. data/ext/zeromq/src/{i_msg_source.hpp → v2_encoder.hpp} +20 -15
  371. data/ext/zeromq/src/{v1_protocol.hpp → v2_protocol.hpp} +7 -11
  372. data/ext/zeromq/src/windows.hpp +2 -4
  373. data/ext/zeromq/src/wire.hpp +5 -6
  374. data/ext/zeromq/src/xpub.cpp +37 -46
  375. data/ext/zeromq/src/xpub.hpp +7 -23
  376. data/ext/zeromq/src/xsub.cpp +26 -40
  377. data/ext/zeromq/src/xsub.hpp +5 -21
  378. data/ext/zeromq/src/ypipe.hpp +3 -4
  379. data/ext/zeromq/src/ypipe_base.hpp +44 -0
  380. data/ext/zeromq/src/ypipe_conflate.hpp +127 -0
  381. data/ext/zeromq/src/yqueue.hpp +3 -7
  382. data/ext/zeromq/src/zmq.cpp +76 -96
  383. data/ext/zeromq/src/zmq_utils.cpp +146 -8
  384. data/ext/zeromq/tests/Makefile.am +56 -8
  385. data/ext/zeromq/tests/test_abstract_ipc.cpp +57 -0
  386. data/ext/zeromq/tests/test_conflate.cpp +75 -0
  387. data/ext/zeromq/tests/test_connect_resolve.cpp +14 -15
  388. data/ext/zeromq/tests/test_ctx_destroy.cpp +90 -0
  389. data/ext/zeromq/tests/test_ctx_options.cpp +52 -0
  390. data/ext/zeromq/tests/test_disconnect_inproc.cpp +35 -30
  391. data/ext/zeromq/tests/test_fork.cpp +81 -0
  392. data/ext/zeromq/tests/test_hwm.cpp +251 -35
  393. data/ext/zeromq/tests/test_immediate.cpp +229 -0
  394. data/ext/zeromq/tests/test_inproc_connect.cpp +339 -0
  395. data/ext/zeromq/tests/test_invalid_rep.cpp +9 -13
  396. data/ext/zeromq/tests/test_iov.cpp +106 -0
  397. data/ext/zeromq/tests/test_issue_566.cpp +85 -0
  398. data/ext/zeromq/tests/test_last_endpoint.cpp +14 -18
  399. data/ext/zeromq/tests/test_linger.cpp +93 -0
  400. data/ext/zeromq/tests/test_monitor.cpp +112 -129
  401. data/ext/zeromq/tests/test_msg_flags.cpp +17 -16
  402. data/ext/zeromq/tests/test_pair_inproc.cpp +25 -7
  403. data/ext/zeromq/tests/test_pair_ipc.cpp +4 -7
  404. data/ext/zeromq/tests/test_pair_tcp.cpp +4 -8
  405. data/ext/zeromq/tests/test_probe_router.cpp +72 -0
  406. data/ext/zeromq/tests/test_req_correlate.cpp +177 -0
  407. data/ext/zeromq/tests/test_req_relaxed.cpp +116 -0
  408. data/ext/zeromq/tests/test_reqrep_device.cpp +9 -17
  409. data/ext/zeromq/tests/test_reqrep_inproc.cpp +4 -7
  410. data/ext/zeromq/tests/test_reqrep_ipc.cpp +4 -7
  411. data/ext/zeromq/tests/test_reqrep_tcp.cpp +4 -8
  412. data/ext/zeromq/tests/test_router_mandatory.cpp +41 -22
  413. data/ext/zeromq/tests/test_security_curve.cpp +212 -0
  414. data/ext/zeromq/tests/test_security_null.cpp +148 -0
  415. data/ext/zeromq/tests/test_security_plain.cpp +150 -0
  416. data/ext/zeromq/tests/test_shutdown_stress.cpp +10 -23
  417. data/ext/zeromq/tests/test_spec_dealer.cpp +254 -0
  418. data/ext/zeromq/tests/test_spec_pushpull.cpp +293 -0
  419. data/ext/zeromq/tests/test_spec_rep.cpp +155 -0
  420. data/ext/zeromq/tests/test_spec_req.cpp +253 -0
  421. data/ext/zeromq/tests/test_spec_router.cpp +204 -0
  422. data/ext/zeromq/tests/test_stream.cpp +228 -0
  423. data/ext/zeromq/tests/test_sub_forward.cpp +14 -22
  424. data/ext/zeromq/tests/test_system.cpp +82 -0
  425. data/ext/zeromq/tests/test_term_endpoint.cpp +17 -31
  426. data/ext/zeromq/tests/test_timeo.cpp +34 -78
  427. data/ext/zeromq/tests/testutil.hpp +211 -26
  428. data/ext/zeromq/tools/Makefile.am +9 -0
  429. data/ext/zeromq/tools/curve_keygen.c +58 -0
  430. data/lib/zmq/version.rb +1 -1
  431. data/test/test_socket.rb +4 -3
  432. metadata +114 -15
  433. data/ext/zeromq/cmake/Modules/TestZMQVersion.cmake +0 -35
  434. data/ext/zeromq/foreign/openpgm/libpgm-5.1.118~dfsg.tar.gz +0 -0
  435. data/ext/zeromq/src/decoder.cpp +0 -166
  436. data/ext/zeromq/src/encoder.cpp +0 -102
  437. data/ext/zeromq/tests/test_connect_delay.cpp +0 -260
@@ -0,0 +1,409 @@
1
+ /* =========================================================================
2
+ zdir - work with file-system directories
3
+
4
+ -------------------------------------------------------------------------
5
+ Copyright (c) 1991-2013 iMatix Corporation <www.imatix.com>
6
+ Copyright other contributors as noted in the AUTHORS file.
7
+
8
+ This file is part of CZMQ, the high-level C binding for 0MQ:
9
+ http://czmq.zeromq.org.
10
+
11
+ This is free software; you can redistribute it and/or modify it under
12
+ the terms of the GNU Lesser General Public License as published by the
13
+ Free Software Foundation; either version 3 of the License, or (at your
14
+ option) any later version.
15
+
16
+ This software is distributed in the hope that it will be useful, but
17
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTA-
18
+ BILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
19
+ Public License for more details.
20
+
21
+ You should have received a copy of the GNU Lesser General Public License
22
+ along with this program. If not, see http://www.gnu.org/licenses/.
23
+ =========================================================================*/
24
+
25
+ /*
26
+ @header
27
+ The zdir class gives access to the file system index. It will load
28
+ a directory tree (a directory plus all child directories) into a
29
+ zdir structure and then let you navigate that structure. It exists
30
+ mainly to wrap non-portable OS functions to do this.
31
+ @discuss
32
+ @end
33
+ */
34
+
35
+ #include "../include/czmq.h"
36
+
37
+ // Structure of our class
38
+
39
+ struct _zdir_t {
40
+ char *path; // Directory name + separator
41
+ zlist_t *files; // List of files in directory
42
+ zlist_t *subdirs; // List of subdirectories
43
+ time_t modified; // Most recent file including subdirs
44
+ off_t cursize; // Total file size including subdirs
45
+ size_t count; // Total file count including subdirs
46
+ };
47
+
48
+ #if (defined (WIN32))
49
+ static void
50
+ s_win32_populate_entry (zdir_t *self, WIN32_FIND_DATA *entry)
51
+ {
52
+ if (entry->cFileName [0] == '.')
53
+ ; // Skip hidden files
54
+ else
55
+ // If we have a subdirectory, go load that
56
+ if (entry->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
57
+ zdir_t *subdir = zdir_new (entry->cFileName, self->path);
58
+ zlist_append (self->subdirs, subdir);
59
+ }
60
+ else {
61
+ // Add file entry to directory list
62
+ zfile_t *file = zfile_new (self->path, entry->cFileName);
63
+ zlist_append (self->files, file);
64
+ }
65
+ }
66
+
67
+ #else
68
+ static void
69
+ s_posix_populate_entry (zdir_t *self, struct dirent *entry)
70
+ {
71
+ // Skip . and ..
72
+ if (streq (entry->d_name, ".")
73
+ || streq (entry->d_name, ".."))
74
+ return;
75
+
76
+ char fullpath [1024 + 1];
77
+ snprintf (fullpath, 1024, "%s/%s", self->path, entry->d_name);
78
+ struct stat stat_buf;
79
+ if (stat (fullpath, &stat_buf))
80
+ return;
81
+
82
+ if (entry->d_name [0] == '.')
83
+ ; // Skip hidden files
84
+ else
85
+ // If we have a subdirectory, go load that
86
+ if (stat_buf.st_mode & S_IFDIR) {
87
+ zdir_t *subdir = zdir_new (entry->d_name, self->path);
88
+ zlist_append (self->subdirs, subdir);
89
+ }
90
+ else {
91
+ // Add file entry to directory list
92
+ zfile_t *file = zfile_new (self->path, entry->d_name);
93
+ zlist_append (self->files, file);
94
+ }
95
+ }
96
+ #endif
97
+
98
+
99
+ // --------------------------------------------------------------------------
100
+ // Constructor
101
+ // Create a new directory item that loads in the full tree of the
102
+ // specified path, optionally located under some parent path.
103
+
104
+ zdir_t *
105
+ zdir_new (const char *path, const char *parent)
106
+ {
107
+ zdir_t *self = (zdir_t *) zmalloc (sizeof (zdir_t));
108
+ if (parent) {
109
+ self->path = (char *) malloc (strlen (path) + strlen (parent) + 2);
110
+ sprintf (self->path, "%s/%s", parent, path);
111
+ }
112
+ else
113
+ self->path = strdup (path);
114
+ self->files = zlist_new ();
115
+ self->subdirs = zlist_new ();
116
+
117
+ #if (defined (WIN32))
118
+ // On Windows, replace backslashes by normal slashes
119
+ char *path_clean_ptr = self->path;
120
+ while (*path_clean_ptr) {
121
+ if (*path_clean_ptr == '\\')
122
+ *path_clean_ptr = '/';
123
+ path_clean_ptr++;
124
+ }
125
+ // Remove any trailing slash
126
+ if (self->path [strlen (self->path) - 1] == '/')
127
+ self->path [strlen (self->path) - 1] = 0;
128
+
129
+ // Win32 wants a wildcard at the end of the path
130
+ char *wildcard = (char *) malloc (strlen (self->path) + 3);
131
+ sprintf (wildcard, "%s/*", self->path);
132
+ WIN32_FIND_DATA entry;
133
+ HANDLE handle = FindFirstFile (wildcard, &entry);
134
+ free (wildcard);
135
+
136
+ if (handle != INVALID_HANDLE_VALUE) {
137
+ // We have read an entry, so return those values
138
+ s_win32_populate_entry (self, &entry);
139
+ while (FindNextFile (handle, &entry))
140
+ s_win32_populate_entry (self, &entry);
141
+ FindClose (handle);
142
+ }
143
+ #else
144
+ // Remove any trailing slash
145
+ if (self->path [strlen (self->path) - 1] == '/')
146
+ self->path [strlen (self->path) - 1] = 0;
147
+
148
+ DIR *handle = opendir (self->path);
149
+ if (handle) {
150
+ // Calculate system-specific size of dirent block
151
+ int dirent_size = offsetof (struct dirent, d_name)
152
+ + pathconf (self->path, _PC_NAME_MAX) + 1;
153
+ struct dirent *entry = (struct dirent *) malloc (dirent_size);
154
+ struct dirent *result;
155
+
156
+ int rc = readdir_r (handle, entry, &result);
157
+ while (rc == 0 && result != NULL) {
158
+ s_posix_populate_entry (self, entry);
159
+ rc = readdir_r (handle, entry, &result);
160
+ }
161
+ free (entry);
162
+ closedir (handle);
163
+ }
164
+ #endif
165
+ else {
166
+ zdir_destroy (&self);
167
+ return NULL;
168
+ }
169
+ // Update directory signatures
170
+ zdir_t *subdir = (zdir_t *) zlist_first (self->subdirs);
171
+ while (subdir) {
172
+ if (self->modified < subdir->modified)
173
+ self->modified = subdir->modified;
174
+ self->cursize += subdir->cursize;
175
+ self->count += subdir->count;
176
+ subdir = (zdir_t *) zlist_next (self->subdirs);
177
+ }
178
+ zfile_t *file = (zfile_t *) zlist_first (self->files);
179
+ while (file) {
180
+ if (self->modified < zfile_modified (file))
181
+ self->modified = zfile_modified (file);
182
+ self->cursize += zfile_cursize (file);
183
+ self->count += 1;
184
+ file = (zfile_t *) zlist_next (self->files);
185
+ }
186
+ return self;
187
+ }
188
+
189
+
190
+ // --------------------------------------------------------------------------
191
+ // Destroy a directory item
192
+
193
+ void
194
+ zdir_destroy (zdir_t **self_p)
195
+ {
196
+ assert (self_p);
197
+ if (*self_p) {
198
+ zdir_t *self = *self_p;
199
+ while (zlist_size (self->subdirs)) {
200
+ zdir_t *subdir = (zdir_t *) zlist_pop (self->subdirs);
201
+ zdir_destroy (&subdir);
202
+ }
203
+ while (zlist_size (self->files)) {
204
+ zfile_t *file = (zfile_t *) zlist_pop (self->files);
205
+ zfile_destroy (&file);
206
+ }
207
+ zlist_destroy (&self->subdirs);
208
+ zlist_destroy (&self->files);
209
+ free (self->path);
210
+ free (self);
211
+ *self_p = NULL;
212
+ }
213
+ }
214
+
215
+
216
+ // --------------------------------------------------------------------------
217
+ // Return directory path
218
+
219
+ char *
220
+ zdir_path (zdir_t *self)
221
+ {
222
+ return self->path;
223
+ }
224
+
225
+
226
+ // --------------------------------------------------------------------------
227
+ // Return last modification time for directory.
228
+
229
+ time_t
230
+ zdir_modified (zdir_t *self)
231
+ {
232
+ assert (self);
233
+ return self->modified;
234
+ }
235
+
236
+
237
+ // --------------------------------------------------------------------------
238
+ // Return total hierarchy size, in bytes of data contained in all files
239
+ // in the directory tree.
240
+
241
+ off_t
242
+ zdir_cursize (zdir_t *self)
243
+ {
244
+ assert (self);
245
+ return self->cursize;
246
+ }
247
+
248
+
249
+ // --------------------------------------------------------------------------
250
+ // Return directory count
251
+
252
+ size_t
253
+ zdir_count (zdir_t *self)
254
+ {
255
+ assert (self);
256
+ return self->count;
257
+ }
258
+
259
+
260
+ // --------------------------------------------------------------------------
261
+ // Returns a sorted array of zfile objects; returns a single block of memory,
262
+ // that you destroy by calling free(). Each entry in the array is a pointer
263
+ // to a zfile_t item already allocated in the zdir tree. The array ends with
264
+ // a null pointer. Do not destroy the original zdir tree until you are done
265
+ // with this array.
266
+
267
+ static int s_dir_flatten (zdir_t *self, zfile_t **files, int index);
268
+ static bool s_dir_compare (void *item1, void *item2);
269
+ static bool s_file_compare (void *item1, void *item2);
270
+
271
+ zfile_t **
272
+ zdir_flatten (zdir_t *self)
273
+ {
274
+ int flat_size;
275
+ if (self)
276
+ flat_size = self->count + 1;
277
+ else
278
+ flat_size = 1; // Just null terminator
279
+
280
+ zfile_t **files = (zfile_t **) zmalloc (sizeof (zfile_t *) * flat_size);
281
+ uint index = 0;
282
+ if (self)
283
+ index = s_dir_flatten (self, files, index);
284
+ return files;
285
+ }
286
+
287
+
288
+ // Flatten one directory, calls itself recursively
289
+
290
+ static int
291
+ s_dir_flatten (zdir_t *self, zfile_t **files, int index)
292
+ {
293
+ // First flatten the normal files
294
+ zlist_sort (self->files, s_file_compare);
295
+ zfile_t *file = (zfile_t *) zlist_first (self->files);
296
+ while (file) {
297
+ files [index++] = file;
298
+ file = (zfile_t *) zlist_next (self->files);
299
+ }
300
+ // Now flatten subdirectories, recursively
301
+ zlist_sort (self->subdirs, s_dir_compare);
302
+ zdir_t *subdir = (zdir_t *) zlist_first (self->subdirs);
303
+ while (subdir) {
304
+ index = s_dir_flatten (subdir, files, index);
305
+ subdir = (zdir_t *) zlist_next (self->subdirs);
306
+ }
307
+ return index;
308
+ }
309
+
310
+ // Compare two subdirs, true if they need swapping
311
+ static bool
312
+ s_dir_compare (void *item1, void *item2)
313
+ {
314
+ if (strcmp (zdir_path ((zdir_t *) item1),
315
+ zdir_path ((zdir_t *) item2)) > 0)
316
+ return true;
317
+ else
318
+ return false;
319
+ }
320
+
321
+ // Compare two files, true if they need swapping
322
+ // We sort by ascending name
323
+
324
+ static bool
325
+ s_file_compare (void *item1, void *item2)
326
+ {
327
+ if (strcmp (zfile_filename ((zfile_t *) item1, NULL),
328
+ zfile_filename ((zfile_t *) item2, NULL)) > 0)
329
+ return true;
330
+ else
331
+ return false;
332
+ }
333
+
334
+
335
+ // --------------------------------------------------------------------------
336
+ // Print contents of directory
337
+
338
+ void
339
+ zdir_dump (zdir_t *self, int indent)
340
+ {
341
+ assert (self);
342
+
343
+ zfile_t **files = zdir_flatten (self);
344
+ uint index;
345
+ for (index = 0;; index++) {
346
+ zfile_t *file = files [index];
347
+ if (!file)
348
+ break;
349
+ puts (zfile_filename (file, NULL));
350
+ }
351
+ free (files);
352
+ }
353
+
354
+
355
+ // --------------------------------------------------------------------------
356
+ // Remove directory, optionally including all files that it contains, at
357
+ // all levels. If force is false, will only remove the directory if empty.
358
+ // If force is true, will remove all files and all subdirectories.
359
+
360
+ void
361
+ zdir_remove (zdir_t *self, bool force)
362
+ {
363
+ // If forced, remove all subdirectories and files
364
+ if (force) {
365
+ zfile_t *file = (zfile_t *) zlist_pop (self->files);
366
+ while (file) {
367
+ zfile_remove (file);
368
+ zfile_destroy (&file);
369
+ file = (zfile_t *) zlist_pop (self->files);
370
+ }
371
+ zdir_t *subdir = (zdir_t *) zlist_pop (self->subdirs);
372
+ while (subdir) {
373
+ zdir_remove (subdir, force);
374
+ zdir_destroy (&subdir);
375
+ subdir = (zdir_t *) zlist_pop (self->subdirs);
376
+ }
377
+ self->cursize = 0;
378
+ self->count = 0;
379
+ }
380
+ // Remove if empty
381
+ if (zlist_size (self->files) == 0
382
+ && zlist_size (self->subdirs) == 0)
383
+ zsys_dir_delete (self->path);
384
+ }
385
+
386
+
387
+ // --------------------------------------------------------------------------
388
+ // Self test of this class
389
+ int
390
+ zdir_test (bool verbose)
391
+ {
392
+ printf (" * zdir: ");
393
+
394
+ // @selftest
395
+ zdir_t *older = zdir_new (".", NULL);
396
+ assert (older);
397
+ if (verbose) {
398
+ printf ("\n");
399
+ zdir_dump (older, 0);
400
+ }
401
+ zdir_destroy (&older);
402
+
403
+ zdir_t *nosuch = zdir_new ("does-not-exist", NULL);
404
+ assert (nosuch == NULL);
405
+ // @end
406
+
407
+ printf ("OK\n");
408
+ return 0;
409
+ }
data/ext/czmq/src/zfile.c CHANGED
@@ -1,5 +1,5 @@
1
1
  /* =========================================================================
2
- zfile - helper functions for working with files.
2
+ zfile - provides methods to work with files in a portable fashion.
3
3
 
4
4
  -------------------------------------------------------------------------
5
5
  Copyright (c) 1991-2013 iMatix Corporation <www.imatix.com>
@@ -25,196 +25,430 @@
25
25
 
26
26
  /*
27
27
  @header
28
- The zfile class provides methods to work with files and directories.
28
+ The zfile class provides methods to work with disk files. A file object
29
+ provides the modified date, current size, and type of the file. You can
30
+ create a file object for a filename that does not yet exist. To read or
31
+ write data from the file, use the input and output methods, and then
32
+ read and write chunks. The output method lets you both read and write
33
+ chunks, at any offset. Finally, this class provides portable symbolic
34
+ links. If a filename ends in ".ln", the first line of text in the file
35
+ is read, and used as the underlying file for read/write operations.
36
+ This lets you manipulate (e.g.) copy symbolic links without copying
37
+ the perhaps very large files they point to.
29
38
  @discuss
39
+ This class is a new API, deprecating the old zfile class (which still
40
+ exists but is implemented in zsys now).
30
41
  @end
31
42
  */
32
43
 
33
44
  #include "../include/czmq.h"
34
45
 
46
+ // Structure of our class
47
+
48
+ struct _zfile_t {
49
+ // Properties for all file objects
50
+ char *fullname; // File name with path
51
+ char *link; // Optional linked file
52
+ bool exists; // true if file exists
53
+ bool stable; // true if file is stable
54
+ bool eof; // true if at end of file
55
+ FILE *handle; // Read/write handle
56
+
57
+ // Properties from files that exist on file system
58
+ time_t modified; // Modification time
59
+ off_t cursize; // Size of the file
60
+ mode_t mode; // POSIX permission bits
61
+ };
62
+
35
63
 
36
64
  // --------------------------------------------------------------------------
37
- // Return true if file exists, else zero
65
+ // Constructor
66
+ // If file exists, populates properties. CZMQ supports portable symbolic
67
+ // links, which are files with the extension ".ln". A symbolic link is a
68
+ // text file containing one line, the filename of a target file. Reading
69
+ // data from the symbolic link actually reads from the target file.
70
+
71
+ zfile_t *
72
+ zfile_new (const char *path, const char *name)
73
+ {
74
+ zfile_t *self = (zfile_t *) zmalloc (sizeof (zfile_t));
75
+
76
+ // Format full path to file
77
+ self->fullname = (char *) zmalloc (strlen (path) + strlen (name) + 2);
78
+ sprintf (self->fullname, "%s/%s", path, name);
79
+
80
+ // Resolve symbolic link if possible
81
+ if (strlen (self->fullname) > 3
82
+ && streq (self->fullname + strlen (self->fullname) - 3, ".ln")) {
83
+ FILE *handle = fopen (self->fullname, "r");
84
+ if (handle) {
85
+ char buffer [256];
86
+ if (fgets (buffer, 256, handle)) {
87
+ // We have the contents of the symbolic link
88
+ if (buffer [strlen (buffer) - 1] == '\n')
89
+ buffer [strlen (buffer) - 1] = 0;
90
+ self->link = strdup (buffer);
91
+ // Chop ".ln" off name for external use
92
+ self->fullname [strlen (self->fullname) - 3] = 0;
93
+ }
94
+ fclose (handle);
95
+ }
96
+ }
97
+ zfile_restat (self);
98
+ return self;
99
+ }
38
100
 
39
- bool
40
- zfile_exists (const char *filename)
101
+ // --------------------------------------------------------------------------
102
+ // Destroy a file item
103
+
104
+ void
105
+ zfile_destroy (zfile_t **self_p)
41
106
  {
42
- assert (filename);
43
- return zfile_mode (filename) != (mode_t)-1;
107
+ assert (self_p);
108
+ if (*self_p) {
109
+ zfile_t *self = *self_p;
110
+ if (self->handle)
111
+ fclose (self->handle);
112
+ free (self->fullname);
113
+ free (self->link);
114
+ free (self);
115
+ *self_p = NULL;
116
+ }
44
117
  }
45
118
 
46
119
 
47
120
  // --------------------------------------------------------------------------
48
- // Return size of file, or -1 if not found
121
+ // Duplicate a file item
49
122
 
50
- ssize_t
51
- zfile_size (const char *filename)
123
+ zfile_t *
124
+ zfile_dup (zfile_t *self)
52
125
  {
53
- struct stat
54
- stat_buf;
55
-
56
- assert (filename);
57
- if (stat ((char *) filename, &stat_buf) == 0)
58
- return stat_buf.st_size;
59
- else
60
- return -1;
126
+ zfile_t
127
+ *copy;
128
+
129
+ copy = (zfile_t *) zmalloc (sizeof (zfile_t));
130
+ copy->fullname = strdup (self->fullname);
131
+ copy->modified = self->modified;
132
+ copy->cursize = self->cursize;
133
+ copy->link = self->link? strdup (self->link): NULL;
134
+ copy->mode = self->mode;
135
+ return copy;
61
136
  }
62
137
 
63
138
 
64
139
  // --------------------------------------------------------------------------
65
- // Return file mode
140
+ // Return file name, remove path if provided
66
141
 
67
- mode_t
68
- zfile_mode (const char *filename)
142
+ char *
143
+ zfile_filename (zfile_t *self, char *path)
69
144
  {
70
- #if (defined (__WINDOWS__))
71
- DWORD dwfa = GetFileAttributes (filename);
72
- if (dwfa == 0xffffffff)
73
- return -1;
145
+ assert (self);
146
+ char *name = self->fullname;
147
+ if (path
148
+ && strlen (self->fullname) >= strlen (path)
149
+ && memcmp (self->fullname, path, strlen (path)) == 0) {
150
+ name += strlen (path);
151
+ if (*name == '/')
152
+ name++;
153
+ }
154
+ return name;
155
+ }
74
156
 
75
- dbyte mode = 0;
76
- if (dwfa & FILE_ATTRIBUTE_DIRECTORY)
77
- mode |= S_IFDIR;
78
- else
79
- mode |= S_IFREG;
80
- if (!(dwfa & FILE_ATTRIBUTE_HIDDEN))
81
- mode |= S_IREAD;
82
- if (!(dwfa & FILE_ATTRIBUTE_READONLY))
83
- mode |= S_IWRITE;
84
-
85
- return mode;
86
- #else
157
+
158
+ // --------------------------------------------------------------------------
159
+ // Refresh file properties from disk; this is not done automatically
160
+ // on access methods, otherwise it is not possible to compare directory
161
+ // snapshots.
162
+
163
+ void
164
+ zfile_restat (zfile_t *self)
165
+ {
166
+ assert (self);
87
167
  struct stat stat_buf;
88
- if (stat ((char *) filename, &stat_buf) == 0)
89
- return stat_buf.st_mode;
90
- else
91
- return -1;
92
- #endif
168
+ char *real_name = self->link? self->link: self->fullname;
169
+ if (stat (real_name, &stat_buf) == 0) {
170
+ self->cursize = stat_buf.st_size;
171
+ self->modified = stat_buf.st_mtime;
172
+ self->mode = zsys_file_mode (real_name);
173
+ self->stable = zsys_file_stable (real_name);
174
+ }
175
+ else {
176
+ self->cursize = 0;
177
+ self->modified = 0;
178
+ self->mode = 0;
179
+ self->stable = false;
180
+ }
93
181
  }
94
182
 
95
183
 
96
184
  // --------------------------------------------------------------------------
97
- // Delete file, return 0 if OK, -1 if not possible.
185
+ // Return when the file was last modified. If you want this to reflect the
186
+ // current situation, call zfile_restat before checking this property.
98
187
 
99
- int
100
- zfile_delete (const char *filename)
188
+ time_t
189
+ zfile_modified (zfile_t *self)
101
190
  {
102
- assert (filename);
103
- #if (defined (__WINDOWS__))
104
- return DeleteFile (filename) ? 0: -1;
105
- #else
106
- return unlink (filename);
107
- #endif
191
+ assert (self);
192
+ return self->modified;
108
193
  }
109
194
 
110
195
 
111
196
  // --------------------------------------------------------------------------
112
- // Check if file is 'stable'
197
+ // Return the last-known size of the file. If you want this to reflect the
198
+ // current situation, call zfile_restat before checking this property.
199
+
200
+ off_t
201
+ zfile_cursize (zfile_t *self)
202
+ {
203
+ assert (self);
204
+ return self->cursize;
205
+ }
206
+
207
+
208
+ // --------------------------------------------------------------------------
209
+ // Return true if the file is a directory. If you want this to reflect
210
+ // any external changes, call zfile_restat before checking this property.
113
211
 
114
212
  bool
115
- zfile_stable (const char *filename)
213
+ zfile_is_directory (zfile_t *self)
116
214
  {
117
- struct stat stat_buf;
118
- if (stat (filename, &stat_buf) == 0) {
119
- // File is 'stable' if more than 1 second old
120
- #if (defined (WIN32))
121
- # define EPOCH_DIFFERENCE 11644473600LL
122
- long age = (long) (zclock_time () - EPOCH_DIFFERENCE * 1000 - (stat_buf.st_mtime * 1000));
123
- #else
124
- long age = (long) (zclock_time () - (stat_buf.st_mtime * 1000));
125
- #endif
126
- return (age > 1000);
127
- }
128
- else
129
- return false; // File doesn't exist, so not stable
215
+ assert (self);
216
+ return (self->mode & S_IFDIR) != 0;
217
+ }
218
+
219
+
220
+ // --------------------------------------------------------------------------
221
+ // Return true if the file is a regular file. If you want this to reflect
222
+ // any external changes, call zfile_restat before checking this property.
223
+
224
+ bool
225
+ zfile_is_regular (zfile_t *self)
226
+ {
227
+ assert (self);
228
+ return (self->mode & S_IFREG) != 0;
229
+ }
230
+
231
+
232
+ // --------------------------------------------------------------------------
233
+ // Return true if the file is readable by this process. If you want this to
234
+ // reflect any external changes, call zfile_restat before checking this
235
+ // property.
236
+
237
+ bool
238
+ zfile_is_readable (zfile_t *self)
239
+ {
240
+ assert (self);
241
+ return (self->mode & S_IREAD) != 0;
242
+ }
243
+
244
+
245
+ // --------------------------------------------------------------------------
246
+ // Return true if the file is writeable by this process. If you want this
247
+ // to reflect any external changes, call zfile_restat before checking this
248
+ // property.
249
+
250
+ bool
251
+ zfile_is_writeable (zfile_t *self)
252
+ {
253
+ assert (self);
254
+ return (self->mode & S_IWRITE) != 0;
130
255
  }
131
256
 
132
257
 
133
258
  // --------------------------------------------------------------------------
134
- // Create a file path if it doesn't exist
259
+ // Check if file has stopped changing and can be safely processed.
260
+ // If you want this to reflect the current situation, call zfile_restat
261
+ // before checking this property.
262
+
263
+ bool
264
+ zfile_is_stable (zfile_t *self)
265
+ {
266
+ assert (self);
267
+ return self->stable;
268
+ }
269
+
270
+
271
+ // --------------------------------------------------------------------------
272
+ // Remove the file
273
+
274
+ void
275
+ zfile_remove (zfile_t *self)
276
+ {
277
+ assert (self);
278
+ // Restore ".ln" in file name if this was a symbolic link
279
+ if (self->link)
280
+ self->fullname [strlen (self->fullname)] = '.';
281
+ zfile_close (self);
282
+ zsys_file_delete (self->fullname);
283
+ }
284
+
285
+
286
+ // --------------------------------------------------------------------------
287
+ // Open file for reading
288
+ // Returns 0 if OK, -1 if not found or not accessible
135
289
 
136
290
  int
137
- zfile_mkdir (const char *pathname)
138
- {
139
- // Take copy of string as we're going to mess with it
140
- char *my_pathname = strdup (pathname);
141
-
142
- // Create parent directory levels if needed
143
- char *slash = strchr (my_pathname + 1, '/');
144
- do {
145
- if (slash)
146
- *slash = 0; // Cut at slash
147
- mode_t mode = zfile_mode (my_pathname);
148
- if (mode == (mode_t)-1) {
149
- // Does not exist, try to create it
150
- #if (defined (__WINDOWS__))
151
- if (!CreateDirectory (my_pathname, NULL))
152
- #else
153
- if (mkdir (my_pathname, 0775))
154
- #endif
155
- return -1; // Failed
156
- }
291
+ zfile_input (zfile_t *self)
292
+ {
293
+ assert (self);
294
+ if (self->handle)
295
+ zfile_close (self);
296
+
297
+ char *real_name = self->link? self->link: self->fullname;
298
+ self->handle = fopen (real_name, "rb");
299
+ if (self->handle) {
300
+ struct stat stat_buf;
301
+ if (stat (real_name, &stat_buf) == 0)
302
+ self->cursize = stat_buf.st_size;
157
303
  else
158
- if ((mode & S_IFDIR) == 0) {
159
- // Not a directory, abort
160
- }
161
- if (!slash) // End if last segment
162
- break;
163
- *slash = '/';
164
- slash = strchr (slash + 1, '/');
165
- } while (slash);
166
-
167
- free (my_pathname);
168
- return 0;
304
+ self->cursize = 0;
305
+ }
306
+ return self->handle? 0: -1;
169
307
  }
170
308
 
171
309
 
172
310
  // --------------------------------------------------------------------------
173
- // Remove a file path if empty
311
+ // Open file for writing, creating directory if needed
312
+ // File is created if necessary; chunks can be written to file at any
313
+ // location. Returns 0 if OK, -1 if error.
174
314
 
175
315
  int
176
- zfile_rmdir (const char *pathname)
316
+ zfile_output (zfile_t *self)
177
317
  {
178
- #if (defined (__WINDOWS__))
179
- return RemoveDirectory (pathname)? 0: -1;
180
- #else
181
- return rmdir (pathname);
182
- #endif
318
+ assert (self);
319
+
320
+ // Wipe symbolic link if that's what the file was
321
+ if (self->link) {
322
+ free (self->link);
323
+ self->link = NULL;
324
+ }
325
+ // Create file path if it doesn't exist
326
+ char *file_path = strdup (self->fullname);
327
+ char *last_slash = strrchr (file_path, '/');
328
+ if (last_slash)
329
+ *last_slash = 0;
330
+ if (zsys_dir_create (file_path))
331
+ return -1;
332
+ free (file_path);
333
+
334
+ // Create file if it doesn't exist
335
+ if (self->handle)
336
+ zfile_close (self);
337
+ self->handle = fopen (self->fullname, "r+b");
338
+ if (!self->handle) {
339
+ self->handle = fopen (self->fullname, "w+b");
340
+ if (!self->handle)
341
+ self->handle = fopen (self->fullname, "w+b");
342
+ }
343
+ return self->handle? 0: -1;
183
344
  }
184
345
 
185
346
 
186
347
  // --------------------------------------------------------------------------
187
- // Set private file creation mode; all files created from here will be
188
- // readable/writable by the owner only.
348
+ // Read chunk from file at specified position. If this was the last chunk,
349
+ // sets self->eof. Returns a null chunk in case of error.
189
350
 
190
- static mode_t s_old_mask = 0;
351
+ zchunk_t *
352
+ zfile_read (zfile_t *self, size_t bytes, off_t offset)
353
+ {
354
+ assert (self);
355
+ assert (self->handle);
356
+ // Calculate real number of bytes to read
357
+ if (offset > self->cursize)
358
+ bytes = 0;
359
+ else
360
+ if (bytes > (size_t) (self->cursize - offset))
361
+ bytes = (size_t) (self->cursize - offset);
362
+
363
+ int rc = fseek (self->handle, (long) offset, SEEK_SET);
364
+ if (rc == -1)
365
+ return NULL;
366
+
367
+ self->eof = false;
368
+ zchunk_t *chunk = zchunk_read (self->handle, bytes);
369
+ if (chunk)
370
+ self->eof = zchunk_size (chunk) < bytes;
371
+ return chunk;
372
+ }
191
373
 
192
- void
193
- zfile_mode_private (void)
374
+
375
+ // --------------------------------------------------------------------------
376
+ // Write chunk to file at specified position
377
+ // Return 0 if OK, else -1
378
+
379
+ int
380
+ zfile_write (zfile_t *self, zchunk_t *chunk, off_t offset)
194
381
  {
195
- # if !defined(__WINDOWS__)
196
- s_old_mask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
197
- # endif
382
+ assert (self);
383
+ assert (self->handle);
384
+ int rc = fseek (self->handle, (long) offset, SEEK_SET);
385
+ if (rc >= 0)
386
+ rc = zchunk_write (chunk, self->handle);
387
+ return rc;
198
388
  }
199
389
 
200
390
 
201
391
  // --------------------------------------------------------------------------
202
- // Reset default file creation mode; all files created from here will use
203
- // process file mode defaults.
392
+ // Close file, if open
204
393
 
205
394
  void
206
- zfile_mode_default (void)
395
+ zfile_close (zfile_t *self)
396
+ {
397
+ assert (self);
398
+ if (self->handle) {
399
+ fclose (self->handle);
400
+ zfile_restat (self);
401
+ }
402
+ self->handle = 0;
403
+ }
404
+
405
+
406
+ // --------------------------------------------------------------------------
407
+ // Return file handle, if opened
408
+
409
+ FILE *
410
+ zfile_handle (zfile_t *self)
207
411
  {
208
- // Reset process file create mask
209
- # if !defined(__WINDOWS__)
210
- if (s_old_mask)
211
- umask (s_old_mask);
212
- # endif
412
+ assert (self);
413
+ return self->handle;
414
+ }
415
+
416
+ // Deprecated API, moved to zsys class. The zfile class works with
417
+ // an object instance, which is more consistent with the CLASS style
418
+ // and lets us do more interesting things. These functions were
419
+ // essentially about portability, so now sit in zsys.
420
+
421
+ bool zfile_exists (const char *filename) {
422
+ return zsys_file_exists (filename);
423
+ }
424
+ ssize_t zfile_size (const char *filename) {
425
+ return zsys_file_size (filename);
426
+ }
427
+ mode_t zfile_mode (const char *filename) {
428
+ return zsys_file_mode (filename);
429
+ }
430
+ int zfile_delete (const char *filename) {
431
+ return zsys_file_delete (filename);
432
+ }
433
+ bool zfile_stable (const char *filename) {
434
+ return zsys_file_stable (filename);
435
+ }
436
+ int zfile_mkdir (const char *pathname) {
437
+ return zsys_dir_create (pathname);
438
+ }
439
+ int zfile_rmdir (const char *pathname) {
440
+ return zsys_dir_delete (pathname);
441
+ }
442
+ void zfile_mode_private (void) {
443
+ zsys_file_mode_private ();
444
+ }
445
+ void zfile_mode_default (void) {
446
+ zsys_file_mode_default ();
213
447
  }
214
448
 
215
449
 
216
450
  // --------------------------------------------------------------------------
217
- // Selftest
451
+ // Self test of this class
218
452
 
219
453
  int
220
454
  zfile_test (bool verbose)
@@ -222,16 +456,73 @@ zfile_test (bool verbose)
222
456
  printf (" * zfile: ");
223
457
 
224
458
  // @selftest
225
- int rc = zfile_delete ("nosuchfile");
226
- assert (rc == -1);
227
-
228
- bool rc_bool = zfile_exists ("nosuchfile");
229
- assert (rc_bool != true);
230
-
231
- rc = (int) zfile_size ("nosuchfile");
459
+ zfile_t *file = zfile_new (".", "bilbo");
460
+ assert (streq (zfile_filename (file, "."), "bilbo"));
461
+ assert (zfile_is_readable (file) == false);
462
+ zfile_destroy (&file);
463
+
464
+ // Create a test file in some random subdirectory
465
+ file = zfile_new ("./this/is/a/test", "bilbo");
466
+ int rc = zfile_output (file);
467
+ assert (rc == 0);
468
+ zchunk_t *chunk = zchunk_new (NULL, 100);
469
+ zchunk_fill (chunk, 0, 100);
470
+ // Write 100 bytes at position 1,000,000 in the file
471
+ rc = zfile_write (file, chunk, 1000000);
472
+ assert (rc == 0);
473
+ zchunk_destroy (&chunk);
474
+ zfile_close (file);
475
+ assert (zfile_is_readable (file));
476
+ assert (zfile_cursize (file) == 1000100);
477
+ zfile_restat (file);
478
+ assert (!zfile_is_stable (file));
479
+ zclock_sleep (1001);
480
+ assert (!zfile_is_stable (file));
481
+ zfile_restat (file);
482
+ assert (zfile_is_stable (file));
483
+
484
+ // Check we can read from file
485
+ rc = zfile_input (file);
486
+ assert (rc == 0);
487
+ chunk = zfile_read (file, 1000100, 0);
488
+ assert (chunk);
489
+ assert (zchunk_size (chunk) == 1000100);
490
+ zchunk_destroy (&chunk);
491
+ zfile_close (file);
492
+
493
+ // Try some fun with symbolic links
494
+ zfile_t *link = zfile_new ("./this/is/a/test", "bilbo.ln");
495
+ rc = zfile_output (link);
496
+ assert (rc == 0);
497
+ fprintf (zfile_handle (link), "./this/is/a/test/bilbo\n");
498
+ zfile_destroy (&link);
499
+
500
+ link = zfile_new ("./this/is/a/test", "bilbo.ln");
501
+ rc = zfile_input (link);
502
+ assert (rc == 0);
503
+ chunk = zfile_read (link, 1000100, 0);
504
+ assert (chunk);
505
+ assert (zchunk_size (chunk) == 1000100);
506
+ zchunk_destroy (&chunk);
507
+ zfile_destroy (&link);
508
+
509
+ // Remove file and directory
510
+ zdir_t *dir = zdir_new ("./this", NULL);
511
+ assert (zdir_cursize (dir) == 2000200);
512
+ zdir_remove (dir, true);
513
+ assert (zdir_cursize (dir) == 0);
514
+ zdir_destroy (&dir);
515
+
516
+ // Check we can no longer read from file
517
+ assert (zfile_is_readable (file));
518
+ zfile_restat (file);
519
+ assert (!zfile_is_readable (file));
520
+ rc = zfile_input (file);
232
521
  assert (rc == -1);
233
-
522
+ zfile_destroy (&file);
234
523
  // @end
524
+
235
525
  printf ("OK\n");
236
526
  return 0;
237
527
  }
528
+