YkLib 0.1.0

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 (125) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +6 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +7 -0
  7. data/Gemfile.lock +34 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +44 -0
  10. data/Rakefile +6 -0
  11. data/YkLib.gemspec +29 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/lib/YkLib/Yk/__advance__.rb +151 -0
  15. data/lib/YkLib/Yk/__defun__.rb +44 -0
  16. data/lib/YkLib/Yk/__hook__.rb +244 -0
  17. data/lib/YkLib/Yk/__minmax__.rb +123 -0
  18. data/lib/YkLib/Yk/__stdlog.rb +329 -0
  19. data/lib/YkLib/Yk/adhocLiterals/email.rb +119 -0
  20. data/lib/YkLib/Yk/adhocLiterals/path.rb +402 -0
  21. data/lib/YkLib/Yk/adhocLiterals/tag.rb +19 -0
  22. data/lib/YkLib/Yk/adhocLiterals/url.rb +36 -0
  23. data/lib/YkLib/Yk/adhocLiterals.rb +199 -0
  24. data/lib/YkLib/Yk/auto_escseq.rb +5 -0
  25. data/lib/YkLib/Yk/auto_pstore.rb +179 -0
  26. data/lib/YkLib/Yk/bsearch.rb +120 -0
  27. data/lib/YkLib/Yk/clambda.rb +309 -0
  28. data/lib/YkLib/Yk/confLine.rb +423 -0
  29. data/lib/YkLib/Yk/create_tty_width_available.rb +24 -0
  30. data/lib/YkLib/Yk/crypt.rb +26 -0
  31. data/lib/YkLib/Yk/debug2 +1 -0
  32. data/lib/YkLib/Yk/debug2.rb +473 -0
  33. data/lib/YkLib/Yk/debugout.rb +139 -0
  34. data/lib/YkLib/Yk/email_tz.rb +533 -0
  35. data/lib/YkLib/Yk/enum_expect.rb +170 -0
  36. data/lib/YkLib/Yk/errlog.rb +5 -0
  37. data/lib/YkLib/Yk/escseq.rb +59 -0
  38. data/lib/YkLib/Yk/eval_alt.rb +281 -0
  39. data/lib/YkLib/Yk/expector.rb +93 -0
  40. data/lib/YkLib/Yk/fetch.rb +556 -0
  41. data/lib/YkLib/Yk/fetch_old.rb +290 -0
  42. data/lib/YkLib/Yk/fib.rb +158 -0
  43. data/lib/YkLib/Yk/file_aux.rb +843 -0
  44. data/lib/YkLib/Yk/file_aux2.rb +919 -0
  45. data/lib/YkLib/Yk/file_aux_old.rb +160 -0
  46. data/lib/YkLib/Yk/filemod.rb +19 -0
  47. data/lib/YkLib/Yk/force_escseq.rb +3 -0
  48. data/lib/YkLib/Yk/generator__.rb +144 -0
  49. data/lib/YkLib/Yk/generator__.rb.org +139 -0
  50. data/lib/YkLib/Yk/indenter/argless_case.rb +46 -0
  51. data/lib/YkLib/Yk/indenter/each_token.rb +671 -0
  52. data/lib/YkLib/Yk/indenter/free_case.rb +313 -0
  53. data/lib/YkLib/Yk/indenter/if_less.rb +53 -0
  54. data/lib/YkLib/Yk/indenter/independent_ensure.rb +23 -0
  55. data/lib/YkLib/Yk/indenter/independent_rescue.rb +23 -0
  56. data/lib/YkLib/Yk/indenter/operand_circumflex.rb +0 -0
  57. data/lib/YkLib/Yk/indenter/operand_period.rb +16 -0
  58. data/lib/YkLib/Yk/indenter/parenless_and.rb +37 -0
  59. data/lib/YkLib/Yk/indenter/post_test.rb +48 -0
  60. data/lib/YkLib/Yk/indenter/token.rb +1525 -0
  61. data/lib/YkLib/Yk/indenter.rb +1382 -0
  62. data/lib/YkLib/Yk/inot.rb +265 -0
  63. data/lib/YkLib/Yk/intf.rb +815 -0
  64. data/lib/YkLib/Yk/io_aux.rb +1332 -0
  65. data/lib/YkLib/Yk/ioctl.rb +60 -0
  66. data/lib/YkLib/Yk/ipcc.rb +87 -0
  67. data/lib/YkLib/Yk/ipcountry.rb +207 -0
  68. data/lib/YkLib/Yk/ipv4adr.rb +318 -0
  69. data/lib/YkLib/Yk/localmail.rb +276 -0
  70. data/lib/YkLib/Yk/method_chain.rb +359 -0
  71. data/lib/YkLib/Yk/misc_tz.rb +1716 -0
  72. data/lib/YkLib/Yk/missing_method.rb +50 -0
  73. data/lib/YkLib/Yk/mojiConv.rb +257 -0
  74. data/lib/YkLib/Yk/nostdlog.rb +4 -0
  75. data/lib/YkLib/Yk/on_marshal.rb +20 -0
  76. data/lib/YkLib/Yk/overrider.rb +47 -0
  77. data/lib/YkLib/Yk/path.rb +293 -0
  78. data/lib/YkLib/Yk/path_aux.rb +883 -0
  79. data/lib/YkLib/Yk/path_aux_alt.rb +0 -0
  80. data/lib/YkLib/Yk/path_rep.rb +1267 -0
  81. data/lib/YkLib/Yk/pg_setup.rb +917 -0
  82. data/lib/YkLib/Yk/procinfo.rb +314 -0
  83. data/lib/YkLib/Yk/proclist.rb +492 -0
  84. data/lib/YkLib/Yk/property.rb +863 -0
  85. data/lib/YkLib/Yk/ranger.rb +606 -0
  86. data/lib/YkLib/Yk/resolv_tz.rb +88 -0
  87. data/lib/YkLib/Yk/rlprompt.rb +73 -0
  88. data/lib/YkLib/Yk/rootexec.rb +48 -0
  89. data/lib/YkLib/Yk/rpm-packageproxy.rb +784 -0
  90. data/lib/YkLib/Yk/rpm-packageproxy2.rb +1430 -0
  91. data/lib/YkLib/Yk/rwhen.rb +21 -0
  92. data/lib/YkLib/Yk/selector.rb +124 -0
  93. data/lib/YkLib/Yk/set.rb +170 -0
  94. data/lib/YkLib/Yk/shellquote.rb +300 -0
  95. data/lib/YkLib/Yk/sio.rb +1001 -0
  96. data/lib/YkLib/Yk/sio0.rb +835 -0
  97. data/lib/YkLib/Yk/sio_aux.rb +1524 -0
  98. data/lib/YkLib/Yk/sio_inot.rb +86 -0
  99. data/lib/YkLib/Yk/sock_aux.rb +42 -0
  100. data/lib/YkLib/Yk/spipe.rb +843 -0
  101. data/lib/YkLib/Yk/sql_table.rb +565 -0
  102. data/lib/YkLib/Yk/stdlog.rb +4 -0
  103. data/lib/YkLib/Yk/syscommand.rb +173 -0
  104. data/lib/YkLib/Yk/sysinit.rb +75 -0
  105. data/lib/YkLib/Yk/ttyFontWidth.rb +46113 -0
  106. data/lib/YkLib/Yk/tty_char.dump +0 -0
  107. data/lib/YkLib/Yk/tty_char.rb +47 -0
  108. data/lib/YkLib/Yk/tty_char_create.rb +437031 -0
  109. data/lib/YkLib/Yk/tty_char_static.rb +437016 -0
  110. data/lib/YkLib/Yk/tty_rewrite.rb +142 -0
  111. data/lib/YkLib/Yk/tty_str.rb +461 -0
  112. data/lib/YkLib/Yk/tty_width.dat.rb +114 -0
  113. data/lib/YkLib/Yk/tty_width.rb +180 -0
  114. data/lib/YkLib/Yk/tty_width_available +569 -0
  115. data/lib/YkLib/Yk/tty_width_list +0 -0
  116. data/lib/YkLib/Yk/tty_width_list.linux +280 -0
  117. data/lib/YkLib/Yk/tty_width_list.windows +324 -0
  118. data/lib/YkLib/Yk/tz_tty +0 -0
  119. data/lib/YkLib/Yk/tz_tty.rb +0 -0
  120. data/lib/YkLib/Yk/uprepos.rb +94 -0
  121. data/lib/YkLib/Yk/userinfo.rb +91 -0
  122. data/lib/YkLib/Yk/with.rb +109 -0
  123. data/lib/YkLib/version.rb +3 -0
  124. data/lib/YkLib.rb +6 -0
  125. metadata +170 -0
@@ -0,0 +1,835 @@
1
+ require 'Yk/path_aux'
2
+ require 'net/smtp'
3
+ require 'base64'
4
+ require 'uri'
5
+ require 'net/dns'
6
+
7
+
8
+ IPv4Regexp = /^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/
9
+
10
+
11
+ class IO
12
+ def set_sio mode = nil
13
+ @sio = SIO.new self, mode
14
+ end
15
+ def sio
16
+ @sio
17
+ end
18
+ end
19
+
20
+
21
+ class String
22
+ SIOServers = Hash.new
23
+ def to_ip
24
+ SIOResolver.resolv self
25
+ end
26
+ def __open tmode, &prc
27
+ self =~ /:/
28
+ adr, port = $`, $'
29
+ if adr !~ /^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/
30
+ p
31
+ adr = adr.to_ip
32
+ p
33
+ end
34
+ s = TCPSocket.new(adr, port.to_i)
35
+ s.set_sio tmode
36
+ if prc
37
+ begin
38
+ prc.call s.sio
39
+ ensure
40
+ s.sio.close
41
+ end
42
+ else
43
+ s.sio
44
+ end
45
+ end
46
+ def open_T &prc
47
+ __open :text, &prc
48
+ end
49
+ def open &prc
50
+ __open :binary, &prc
51
+ end
52
+ def __listen tmode
53
+ self =~ /:/
54
+ adr, port = $`, $'
55
+ if adr !~ /^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/
56
+ adr = adr.to_ip
57
+ end
58
+ sio = nil
59
+ begin
60
+ sio = (SIOServers[self] ||= SIO.new(TCPServer.new(adr, port.to_i)))
61
+ loop do
62
+ SIO.select sio, :read
63
+ sio.io.accept do |s|
64
+ s.set_sio tmode
65
+ SIO.fork do
66
+ yield s.sio
67
+ end
68
+ end
69
+ end
70
+ ensure
71
+ sio.close
72
+ SIOServers.delete self
73
+ end
74
+ end
75
+ def listen
76
+ __listen :binary
77
+ end
78
+ def listen_T
79
+ __listen :text
80
+ end
81
+ def url_encode
82
+ URI.url_escape self
83
+ end
84
+ def url_decode
85
+ URI.url_unescape self
86
+ end
87
+ end
88
+
89
+
90
+ class Integer
91
+ def listen &prc
92
+ "0.0.0.0:#{self}".listen &prc
93
+ end
94
+ end
95
+
96
+
97
+ def local *args
98
+ yield *args
99
+ end
100
+
101
+
102
+ class SIO
103
+ class ExpectException < Exception
104
+ end
105
+ attr :io
106
+ def initialize io, m
107
+ @io = io
108
+ @mode = m
109
+ @readBuff = ""
110
+ @residue = ""
111
+ end
112
+ def expect arg
113
+ loop do
114
+ @readBuff.lstrip!
115
+ break if @readBuff.size > 0
116
+ pre_read
117
+ end
118
+ p @readBuff
119
+ while @readBuff.size < arg.size && @readBuff == arg[0...@readBuff.size] && !@eof
120
+ pre_read
121
+ end
122
+ if @readBuff.size < arg.size
123
+ raise ExceptException.new "expected '#{arg}', but '#{@readBuff}' returned\n"
124
+ else
125
+ p @readBuff
126
+ @readBuff = @readBuff[arg.size ... @readBuff.size]
127
+ p @readBuff
128
+ return arg
129
+ end
130
+ end
131
+ def expectln arg = nil
132
+ if arg
133
+ expect arg + "\n"
134
+ else
135
+ loop do
136
+ if @readBuff.size == 0
137
+ if !@eof
138
+ pre_read
139
+ else
140
+ raise ExceptException.new "expected empty new line but reached eof\n"
141
+ end
142
+ end
143
+ if @eof
144
+ if @readBuff !~ /^[\t\f\r ]*\n/
145
+ if @readBuff.size == 0
146
+ raise ExceptException.new "expected empty new line but reached eof\n"
147
+ else
148
+ raise ExceptException.new "expected empty new line but read '#{@readBuff}'\n"
149
+ end
150
+ end
151
+ @readBuff = $'
152
+ while @readBuff =~ /^[\t\f\r ]*\n/
153
+ @readBuff = $'
154
+ end
155
+ return
156
+ else
157
+ while @readBuff =~ /^[\t\f\r ]+/
158
+ @readBuff = $'
159
+ if @readBuff.size == 0
160
+ pre_read
161
+ end
162
+ end
163
+ if @eof && @readBuff == ""
164
+ raise ExceptException.new "expected empty new line but reached eof\n"
165
+ end
166
+ if @readBuff[0] != "\n"
167
+ raise ExceptException.new "expected empty new line but read '#{@readBuff}'\n"
168
+ end
169
+ @readBuff = @readBuff[1...@readBuff.size]
170
+ loop do
171
+ while @readBuff =~ /^[\t\f\r ]+/
172
+ if $'.size > 0
173
+ break
174
+ elsif @eof # $'.size == 0
175
+ return
176
+ end
177
+ pre_read
178
+ end
179
+ if @readBuff[0] == "\n"
180
+ @readBuff = @readBuff[1...@readBuff.size]
181
+ next
182
+ end
183
+ return
184
+ end
185
+ end
186
+ end
187
+ end
188
+ end
189
+ def readline
190
+ idx = nil
191
+ res = @readBuff
192
+ @readBuff = ""
193
+ while !(idx = res.index "\n") && !@eof
194
+ pre_read
195
+ res += @readBuff
196
+ @readBuff = ""
197
+ end
198
+ p idx
199
+ if idx
200
+ ret = res[0..idx]
201
+ @readBuff = res[idx + 1 ... res.size]
202
+ else
203
+ ret = res
204
+ end
205
+ ret
206
+ end
207
+ def read_each_line
208
+ p
209
+ loop do
210
+ p
211
+ ret = readline
212
+ if ret != ""
213
+ yield ret
214
+ end
215
+ if @eof && (!@readBuff || @readBuff == "")
216
+ return
217
+ end
218
+ end
219
+ end
220
+ def read
221
+ ret = ""
222
+ while !@eof
223
+ pre_read
224
+ ret += @readBuff
225
+ @readBuff = ""
226
+ end
227
+ end
228
+ def unwind s
229
+ @readBuff = s + @readBuff
230
+ end
231
+ def select_write
232
+ self.class.select self, :write
233
+ end
234
+ def select_read
235
+ return if @eof
236
+ p
237
+ self.class.select self, :read
238
+ p
239
+ begin
240
+ @readBuff += @io.readpartial 0x3fffffff
241
+ p @readBuff
242
+ rescue EOFError
243
+ p
244
+ @eof = true
245
+ end
246
+ p
247
+ end
248
+ def write arg
249
+ if @mode == :text
250
+ arg = arg.gsub "\n", "\r\n"
251
+ end
252
+ select_write
253
+ p arg
254
+ return @io.write arg
255
+ end
256
+ def writeln arg
257
+ write arg + "\n"
258
+ end
259
+ def pre_read
260
+ loop do
261
+ if @readBuff.size > 0
262
+ break
263
+ end
264
+ @readBuff += @residue
265
+ p
266
+ select_read
267
+ p @readBuff
268
+ if @mode == :text
269
+ @readBuff.gsub! "\r\n", "\n"
270
+ if @mode == :text && @readBuff[-1] == "\r"
271
+ @readBuff.chop!
272
+ @residue = "\r"
273
+ end
274
+ end
275
+ if @readBuff != "" || @eof
276
+ break
277
+ end
278
+ end
279
+ end
280
+ def close
281
+ @io.close
282
+ end
283
+ def self.continue_procs
284
+ @main_cont.call
285
+ end
286
+ def self.exit
287
+ if @proc_to_select.size > 0
288
+ @select_one.call
289
+ else
290
+ Kernel.exit status
291
+ end
292
+ end
293
+
294
+
295
+ class OrderedQueue < Array
296
+ def initialize &prc
297
+ @ev = prc
298
+ end
299
+ alias :_insert_at :insert
300
+ def _insert item, bg = 0, ed = size
301
+ if @ev.call(bg) == @ev.call(ed - 1)
302
+ _insert ed - 1, item
303
+ else
304
+ if ed - bg == 1
305
+ _insert_at ed, item
306
+ elsif ed - bg == 2
307
+ _insert_at ed - 1, item
308
+ else
309
+ m = (bg + ed).div 2
310
+ if @ev.call(item) < @ev.call(self[m])
311
+ _insert item, bg, m + 1
312
+ elsif @ev.call(self[m + 1]) <= @ev.call(item)
313
+ _insert item, m + 1, ed
314
+ else
315
+ _insert_at m + 1, item
316
+ end
317
+ end
318
+ end
319
+ end
320
+ def insert item
321
+ if size == 0
322
+ push item
323
+ else
324
+ if @ev.call(self[0]) > @ev.call(item)
325
+ unshift item
326
+ elsif @ev.call(self[-1]) <= @ev.call(item)
327
+ push item
328
+ else
329
+ _insert item
330
+ end
331
+ end
332
+ end
333
+ end
334
+
335
+
336
+ class ForkObj
337
+ def awake_at t
338
+ SIO.proc_to_select.each do |prc|
339
+ if prc.forkObj == self && prc.sio._?.is_a?(Time).__it > t
340
+ prc.set_sio t
341
+ break
342
+ end
343
+ end
344
+ end
345
+ def exit
346
+
347
+ end
348
+ end
349
+ def self.forkObj
350
+ @forkObj ||= ForkObj.new
351
+ end
352
+ def self.fork mode = false, &prc # mode : true, execute block firstly
353
+ cc = callcc do |cont|
354
+ cont
355
+ end
356
+ p cc
357
+ if cc.is_a? Continuation
358
+ cc_frk = callcc do |cont|
359
+ cont
360
+ end
361
+ end
362
+ p cc, cc_frk
363
+ case [cc.is_a?(Continuation), cc_frk.is_a?(Continuation)]
364
+ when [true, true]
365
+ cc, cc_frk = cc_frk, cc if mode
366
+ (@proc_to_select ||= []).push SIOProc.new(cc, :pass)
367
+ @proc_to_select.push SIOProc.new(cc_frk, :fork)
368
+ @select_one.call
369
+ when [false, true]
370
+ cc = cc_frk
371
+ begin
372
+ prc.call
373
+ rescue Exception => ex
374
+ ex.instance_eval {
375
+ STDERR.write "#{backtrace[0]}:#{ex} (#{self.class})".ln
376
+ backtrace[1..-1].each do |e|
377
+ STDERR.write " " + e.ln
378
+ end
379
+ }
380
+ @aborted = true
381
+ abort
382
+ end
383
+ if @proc_to_select.size > 0
384
+ @select_one.call
385
+ else
386
+ raise Exception.new "unknown fork finalization error\n"
387
+ end
388
+ when [true, false]
389
+ cc_frk = cc
390
+ return forkObj
391
+ else
392
+ raise Exception.new "unknown fork finalization error\n"
393
+ end
394
+ end
395
+ def self.pass
396
+ cc = callcc do |cont|
397
+ cont
398
+ end
399
+ if cc.is_a? Continuation
400
+ (@proc_to_select ||= []).push SIOProc.new(cc, :pass)
401
+ @select_one.call
402
+ end
403
+ end
404
+ def self.sleep t = :stop
405
+ cc = callcc do |cont|
406
+ cont
407
+ end
408
+ if cc.is_a? Continuation
409
+ t != :stop and t += Time.now
410
+ (@proc_to_select ||= []).push SIOProc.new(cc, t)
411
+ @select_one.call
412
+ end
413
+ end
414
+ def self.stopBy token, timeout = :stop
415
+ cc = callcc do |cont|
416
+ cont
417
+ end
418
+ if cc.is_a? Continuation
419
+ (@proc_to_select ||= []).push SIOProc.new(cc, timeout, token)
420
+ @select_one.call
421
+ else
422
+ if cc == :start
423
+ :timeout
424
+ else
425
+ token
426
+ end
427
+ end
428
+ end
429
+ def self.awakeBy token
430
+ cc = callcc do |cont|
431
+ cont
432
+ end
433
+ if cc.is_a? Continuation
434
+ (@proc_to_select ||= []).each do |prc|
435
+ if prc.token == token
436
+ prc.set_sio :start
437
+ end
438
+ end
439
+ (@proc_to_select ||= []).push SIOProc.new(cc, :start)
440
+ @select_one.call
441
+ end
442
+ end
443
+ def self.timer t
444
+ loop do
445
+ yield
446
+ sleep t
447
+ end
448
+ end
449
+ def self.select_one
450
+ p5
451
+ cc = callcc do |cont|
452
+ cont
453
+ end
454
+ if cc.is_a? Continuation
455
+ @select_one = cc
456
+ else
457
+ wios = []
458
+ rios = []
459
+ active_procs = []
460
+ hasTimer = false
461
+ @proc_to_select.each do |prc|
462
+ if prc.timeout
463
+ hasTimer = true
464
+ break
465
+ end
466
+ end
467
+ now = Time.now if hasTimer
468
+ tmout = nil
469
+ tmoutList = []
470
+ wio2SIOPrc = Hash.new{|h, k| h[k] = []}
471
+ rio2SIOPrc = Hash.new{|h, k| h[k] = []}
472
+ p
473
+ @proc_to_select.each do |prc|
474
+ p prc.selected?, prc.mode
475
+ case prc.selected? || prc.mode
476
+ when :read, :write
477
+ if prc.mode == :read
478
+ rio2SIOPrc[prc.io].push prc
479
+ rios.push prc.io
480
+ else # :write
481
+ wio2SIOPrc[prc.io].push prc
482
+ wios.push prc.io
483
+ end
484
+ if prc.timeout
485
+ if !tmout || (tmout != 0 and tmout > prc.timeout - now and tmoutList.clear)
486
+ tmout = prc.timeout - now
487
+ tmout = 0 if tmout < 0
488
+ end
489
+ end
490
+ when :timer
491
+ if !tmout
492
+ tmout = prc.timeout - now
493
+ tmout = 0 if tmout < 0
494
+ tmoutList.push prc
495
+ elsif tmout == 0 && prc.timeout - now <= 0
496
+ tmoutList.push prc
497
+ elsif tmout == prc.timeout - now
498
+ tmoutList.push prc
499
+ elsif tmout > prc.timeout - now
500
+ tmout = prc.timeout - now
501
+ tmout = 0 if tmout < 0
502
+ tmoutList.clear
503
+ tmoutList.push prc
504
+ end
505
+ when :stop
506
+ # do nothing
507
+ when :start, true
508
+ if !tmout
509
+ tmout = 0
510
+ tmoutList.push prc
511
+ elsif tmout == 0
512
+ tmoutList.push prc
513
+ else
514
+ tmout = 0
515
+ tmoutList.clear
516
+ tmoutList.push prc
517
+ end
518
+ when :pass
519
+ prc.set_sio :start
520
+ else # token
521
+ # do nothing
522
+ end
523
+ end
524
+ # p @proc_to_select
525
+ p tmout
526
+ p [rios, wios, tmoutList]
527
+ selectedList, srios, swios = nil
528
+ if !tmout || tmout != 0
529
+ begin
530
+ srios, swios, = IO.select rios, wios, [], tmout
531
+ rescue Errno::EINTR
532
+ retry
533
+ end
534
+ now = nil
535
+ timeouted = (!srios || srios.size == 0) && (!swios || swios.size == 0)
536
+ [[rios, srios, rio2SIOPrc], [wios, swios, wio2SIOPrc]].each do |ios, sios, io2SIOPrc|
537
+ ios.each do |io|
538
+ io2SIOPrc[io].each do |e|
539
+ if (sios && sios.include?(io)) || (e.timeout && e.timeout < (now ||= Time.now))
540
+ e.set_selected
541
+ (selectedList ||= []).push e
542
+ end
543
+ end
544
+ end
545
+ end
546
+ else #tmout = 0
547
+ timeouted = true
548
+ end
549
+ p rios
550
+ p wios
551
+ p selectedList
552
+ p tmoutList
553
+ if timeouted
554
+ (selectedList ||= []).push *tmoutList
555
+ end
556
+ current_proc = selectedList.shuffle[0]
557
+ current_proc.reset_selected if current_proc.selected?
558
+ @proc_to_select.delete current_proc
559
+ @forkObj = current_proc.forkObj
560
+ p current_proc
561
+ current_proc.continue
562
+ end
563
+ end
564
+ def self.select sio, mode, timeout = nil
565
+ prc = SIOProc.new
566
+ if prc.set_cont sio, mode, timeout
567
+ (@proc_to_select ||= []).push prc
568
+ @select_one.call
569
+ end
570
+ end
571
+ class SIOProc
572
+ attr_reader :mode, :sio, :forkObj, :timeout, :token
573
+ def io
574
+ if sio.is_a? SIO
575
+ sio.io
576
+ else
577
+ sio
578
+ end
579
+ end
580
+ def initialize *args
581
+ args.each do |e|
582
+ case e
583
+ when Continuation
584
+ @cont = e
585
+ when :fork
586
+ @mode = :start
587
+ @forkObj = ForkObj.new
588
+ when Symbol
589
+ @mode = e
590
+ when Time
591
+ @timeout = e
592
+ when Numeric
593
+ @timeout = Time.now + e
594
+ else
595
+ @token = e
596
+ end
597
+ end
598
+ @timeout and @mode ||= :timer
599
+ @forkObj ||= SIO.forkObj
600
+ end
601
+ def set_sio t
602
+ if t.is_a? Time
603
+ @mode = :timer
604
+ @timeout = t
605
+ elsif t == :pass
606
+ @mode = :pass
607
+ @sio = nil
608
+ elsif t == :start
609
+ @mode = :start
610
+ @sio = nil
611
+ end
612
+ end
613
+ def set_cont sio, mode, timeout
614
+ @sio = sio
615
+ @mode = mode
616
+ if timeout
617
+ @timeout = timeout.is_a?(Numeric) ? timeout + Time.now : timeout
618
+ end
619
+ cc = callcc do |cont|
620
+ cont
621
+ end
622
+ if cc.is_a? Continuation
623
+ @cont = cc
624
+ true
625
+ else
626
+ false
627
+ end
628
+ end
629
+ def set_selected
630
+ @selected = true
631
+ end
632
+ def reset_selected
633
+ @selected = false
634
+ end
635
+ def selected?
636
+ return @selected
637
+ end
638
+ def continue
639
+ @sio = nil
640
+ mode = @mode
641
+ @mode = nil
642
+ @cont.call mode
643
+ end
644
+ end
645
+ def self.proc_to_select
646
+ @proc_to_select ||= []
647
+ end
648
+ def self._exit
649
+ if @proc_to_select.size > 0
650
+ @select_one.call
651
+ end
652
+ end
653
+ STDIN = ::STDIN.set_sio
654
+ STDOUT = ::STDOUT.set_sio
655
+ STDERR = ::STDOUT.set_sio
656
+ def tmode= m
657
+ @mode = m
658
+ end
659
+ def tmode
660
+ @mode
661
+ end
662
+ self.select_one
663
+ at_exit do
664
+ if $!
665
+ $!.instance_eval {
666
+ STDERR.write "#{backtrace[0]}:#{$!} (#{self.class})".ln
667
+ backtrace[1..-1].each do |e|
668
+ STDERR.write " " + e.ln
669
+ end
670
+ }
671
+ @aborted = true
672
+ abort
673
+ end
674
+ if !@aborted && proc_to_select.size > 0
675
+ p
676
+ pass
677
+ end
678
+ end
679
+ end
680
+
681
+
682
+ class String
683
+ def strip_indent
684
+ mn = 1000000
685
+ last = nil
686
+ each_line do |ln|
687
+ break if (last = ln)[-1] != "\n"
688
+ ln.chomp =~ /^\s*/
689
+ next if $'.size == 0
690
+ if $&.size < mn
691
+ mn = $&.size
692
+ end
693
+ end
694
+ res = ""
695
+ each_line do |ln|
696
+ break if ln[-1] != "\n"
697
+ res += ln[mn..-1] if ln[mn..-1]
698
+ end
699
+ if last && last.size <= mn
700
+ res += last.lstrip
701
+ else
702
+ res += last[mn..-1]
703
+ end
704
+ replace(res)
705
+ self
706
+ end
707
+ end
708
+
709
+
710
+ class SIOResolver
711
+ Sock = SIO.new UDPSocket.open, :read
712
+ begin
713
+ Sock.io.bind("0.0.0.0", rand(1024..65535))
714
+ rescue => Errno::EADDRINUSE
715
+ retry
716
+ end
717
+ resolvers = []
718
+ "/etc/resolv.conf".read_each_line do |ln|
719
+ if ln.strip =~ /nameserver\s*/ && $' =~ IPv4Regexp
720
+ resolvers.push $&
721
+ end
722
+ end
723
+ Resolvers = resolvers
724
+ MaxRetrial = 5
725
+ EachResolvTimeout = 0.2
726
+ ResolvTimeout = 1.01
727
+
728
+ p
729
+ SIO.fork true do
730
+ p
731
+ loop do
732
+ p
733
+ SIO.select Sock, :read
734
+ p
735
+ pkt = Sock.io.recvfrom(1024)
736
+ parsed = Net::DNS::Packet::parse(pkt)
737
+ name, ip, ttl = nil
738
+ parsed.question.each do |rr|
739
+ p rr.qType.to_s
740
+ p rr.qType.to_s.class
741
+ if rr.qType.to_s == "A"
742
+ name = rr.qName
743
+ if name[-1..-1] == "."
744
+ name.chop!
745
+ end
746
+ break
747
+ end
748
+ end
749
+ parsed.answer.each do |rr|
750
+ if rr.type == "A"
751
+ ip, ttl = rr.address.to_s, rr.ttl
752
+ break
753
+ end
754
+ end
755
+ if ip and name
756
+ p [name, ip, ttl]
757
+ Status[name].setResult ip, ttl
758
+ p
759
+ SIO.awakeBy [self, name]
760
+ p
761
+ end
762
+ end
763
+ end
764
+
765
+ p
766
+ class Status
767
+ attr_reader :expiry, :ip
768
+ def self.[] name
769
+ @list ||= Hash.new{|h, k| h[k] = Status.new(k)}
770
+ @list[name]
771
+ end
772
+ def initialize name
773
+ @name = name
774
+ @expiry = Time.at(0)
775
+ end
776
+ def resolve
777
+ p
778
+ if @resolving
779
+ p
780
+ @retrialLeft = MaxRetrial
781
+ return
782
+ end
783
+ p
784
+ @resolving = true
785
+ p
786
+ @retrialLeft = MaxRetrial
787
+ p
788
+ SIO.fork do
789
+ p
790
+ begin
791
+ p
792
+ pkt = Net::DNS::Packet.new @name
793
+ p
794
+ begin
795
+ p
796
+ @retrialLeft -= 1
797
+ p
798
+ Sock.io.send(pkt.data, 0, Resolvers[rand(0...Resolvers.size)], 53)
799
+ p
800
+ if !SIO.stopBy [self, @name], EachResolvTimeout
801
+ p
802
+ redo if @retrialLeft > 0
803
+ end
804
+ p
805
+ end
806
+ ensure
807
+ @resolving = false
808
+ end
809
+ end
810
+ p
811
+ end
812
+ def setResult ip, ttl
813
+ @ip = ip
814
+ @expiry = Time.now + ttl
815
+ end
816
+ end
817
+
818
+ def self.resolv name
819
+ stat = Status[name]
820
+ if stat.expiry > Time.now
821
+ return stat.ip
822
+ end
823
+ p
824
+ stat.resolve
825
+ p
826
+ SIO.stopBy [self, name], ResolvTimeout
827
+ p stat.ip
828
+ return stat.ip
829
+ end
830
+
831
+
832
+ end
833
+
834
+ p
835
+