YkLib 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+