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,1001 @@
1
+ require 'Yk/path_aux'
2
+ require 'net/smtp'
3
+ require 'base64'
4
+ require 'uri'
5
+ require 'net/dns'
6
+ require 'socket'
7
+ require 'cgi'
8
+
9
+
10
+ #p > nil
11
+
12
+
13
+ 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])$/
14
+
15
+
16
+ class IO
17
+ def set_sio mode = nil
18
+ @sio = SIO.new self, mode
19
+ end
20
+ def sio
21
+ @sio
22
+ end
23
+ end
24
+
25
+
26
+ class String
27
+ SIOServers = Hash.new
28
+ TCPConnectTimeout = 1
29
+ def to_ip
30
+ SIOResolver.resolv self
31
+ end
32
+ def __open tmode, &prc
33
+ self =~ /:/
34
+ adr, port = $`, $'
35
+ a = adr
36
+ p adr
37
+ 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])$/
38
+ p
39
+ adr = adr.to_ip
40
+ p
41
+ end
42
+ if !adr
43
+ raise Exception.new("cannot resolv address: #{a}")
44
+ end
45
+ p adr
46
+ s = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
47
+ sock_addr = Socket.sockaddr_in(port, adr)
48
+ s.set_sio tmode
49
+ s.connect_nonblock(sock_addr) rescue IO::WaitWritable
50
+ SIO.select s.sio, :write, TCPConnectTimeout
51
+ opt = s.getsockopt(Socket::SOL_SOCKET, Socket::SO_ERROR)
52
+ p opt
53
+ if opt.int != 0
54
+ s.close
55
+ raise SystemCallError.new(opt.int)
56
+ end
57
+ if prc
58
+ begin
59
+ prc.call s.sio
60
+ ensure
61
+ s.sio.close
62
+ end
63
+ else
64
+ s.sio
65
+ end
66
+ end
67
+ def open_T &prc
68
+ __open :text, &prc
69
+ end
70
+ def open &prc
71
+ __open :binary, &prc
72
+ end
73
+ def __listen tmode, &prc
74
+ self =~ /:/
75
+ adr, port = $`, $'
76
+ a = adr
77
+ 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])$/
78
+ adr = adr.to_ip
79
+ end
80
+ if !adr
81
+ raise Exception.new("cannot resolv address: #{a}")
82
+ end
83
+ sio = nil
84
+ begin
85
+ p adr, port
86
+ sio = (SIOServers[self] ||= SIO.new(TCPServer.new(adr, port.to_i)))
87
+ loop do
88
+ p
89
+ SIO.select sio, :read
90
+ p
91
+ as = sio.io.accept
92
+ esio = SIO.new as, tmode
93
+ SIO.fork do
94
+ p
95
+ begin
96
+ p
97
+ yield esio
98
+ p
99
+ ensure
100
+ esio.close
101
+ end
102
+ end
103
+ p
104
+ end
105
+ ensure
106
+ p $!
107
+ sio.close
108
+ SIOServers.delete self
109
+ end
110
+ end
111
+ def accept &prc
112
+ __listen :binary, &prc
113
+ end
114
+ def accept_T &prc
115
+ __listen :text, &prc
116
+ end
117
+ def url_encode
118
+ CGI.escape self
119
+ end
120
+ def url_decode
121
+ CGI.unescape self
122
+ end
123
+ end
124
+
125
+
126
+ class Integer
127
+ def accept &prc
128
+ "0.0.0.0:#{self}".accept &prc
129
+ end
130
+ def accept_T &prc
131
+ "0.0.0.0:#{self}".accept_T &prc
132
+ end
133
+ end
134
+
135
+
136
+ def local *args
137
+ yield *args
138
+ end
139
+
140
+
141
+ class SIO
142
+ class ExpectException < Exception
143
+ end
144
+ attr :io
145
+ def initialize io, m = :binary
146
+ @io = io
147
+ @mode = m
148
+ @readBuff = ""
149
+ @residue = ""
150
+ end
151
+ def expect arg
152
+ arg = arg.lstrip
153
+ if arg == ""
154
+ return
155
+ end
156
+ loop do
157
+ @readBuff.lstrip!
158
+ break if @readBuff.size > 0
159
+ pre_read
160
+ end
161
+ p @readBuff
162
+ while @readBuff.size < arg.size && @readBuff == arg[0...@readBuff.size] && !@eof
163
+ pre_read
164
+ end
165
+ if @readBuff.size < arg.size
166
+ raise ExpectException.new "expected '#{arg}', but '#{@readBuff}' returned\n"
167
+ else
168
+ p @readBuff[0...arg.size]
169
+ p arg
170
+ p @readBuff[0...arg.size] != arg
171
+ if @readBuff[0...arg.size] != arg
172
+ raise ExpectException.new "expected '#{arg}', but '#{@readBuff}' returned\n"
173
+ end
174
+ @readBuff = @readBuff[arg.size ... @readBuff.size]
175
+ p @readBuff
176
+ return arg
177
+ end
178
+ end
179
+ def expectln arg = nil
180
+ if arg
181
+ expect arg + "\n"
182
+ else
183
+ loop do
184
+ if @readBuff.size == 0
185
+ if !@eof
186
+ pre_read
187
+ else
188
+ raise ExpectException.new "expected empty new line but reached eof\n"
189
+ end
190
+ end
191
+ if @eof
192
+ if @readBuff !~ /^[\t\f\r ]*\n/
193
+ if @readBuff.size == 0
194
+ raise ExpectException.new "expected empty new line but reached eof\n"
195
+ else
196
+ raise ExpectException.new "expected empty new line but read '#{@readBuff}'\n"
197
+ end
198
+ end
199
+ @readBuff = $'
200
+ while @readBuff =~ /^[\t\f\r ]*\n/
201
+ @readBuff = $'
202
+ end
203
+ return
204
+ else
205
+ while @readBuff =~ /^[\t\f\r ]+/
206
+ @readBuff = $'
207
+ if @readBuff.size == 0
208
+ pre_read
209
+ end
210
+ end
211
+ if @eof && @readBuff == ""
212
+ raise ExpectException.new "expected empty new line but reached eof\n"
213
+ end
214
+ if @readBuff[0] != "\n"
215
+ raise ExpectException.new "expected empty new line but read '#{@readBuff}'\n"
216
+ end
217
+ @readBuff = @readBuff[1...@readBuff.size]
218
+ loop do
219
+ while @readBuff =~ /^[\t\f\r ]+/
220
+ if $'.size > 0
221
+ break
222
+ elsif @eof # $'.size == 0
223
+ return
224
+ end
225
+ pre_read
226
+ end
227
+ if @readBuff[0] == "\n"
228
+ @readBuff = @readBuff[1...@readBuff.size]
229
+ next
230
+ end
231
+ return
232
+ end
233
+ end
234
+ end
235
+ end
236
+ end
237
+ def readline
238
+ idx = nil
239
+ res = @readBuff
240
+ @readBuff = ""
241
+ while !(idx = res.index "\n") && !@eof
242
+ pre_read
243
+ res += @readBuff
244
+ @readBuff = ""
245
+ end
246
+ p idx
247
+ if idx
248
+ ret = res[0..idx]
249
+ @readBuff = res[idx + 1 ... res.size]
250
+ else
251
+ ret = res
252
+ end
253
+ ret
254
+ end
255
+ def read_each_line
256
+ p
257
+ loop do
258
+ p
259
+ ret = readline
260
+ if ret != ""
261
+ yield ret
262
+ end
263
+ if @eof && (!@readBuff || @readBuff == "")
264
+ return
265
+ end
266
+ end
267
+ end
268
+ def setmode_B
269
+ if block_given?
270
+ tmp = @mode
271
+ begin
272
+ @mode = "B"
273
+ yield
274
+ ensure
275
+ @mode = tmp
276
+ end
277
+ else
278
+ @mode = "B"
279
+ end
280
+ end
281
+ def read
282
+ ret = ""
283
+ while !@eof
284
+ pre_read
285
+ ret += @readBuff
286
+ @readBuff = ""
287
+ end
288
+ ret
289
+ end
290
+ def unwind s
291
+ @readBuff = s + @readBuff
292
+ end
293
+ def select_write
294
+ self.class.select self, :write
295
+ end
296
+ def select_read
297
+ return if @eof
298
+ p
299
+ self.class.select self, :read
300
+ p
301
+ begin
302
+ p @io
303
+ @readBuff += @io.readpartial 0x3fffffff
304
+ p @readBuff
305
+ rescue EOFError
306
+ p
307
+ @eof = true
308
+ end
309
+ p
310
+ end
311
+ def write arg
312
+ if @mode == :text
313
+ arg = arg.gsub "\n", "\r\n"
314
+ end
315
+ select_write
316
+ p arg
317
+ return @io.write arg
318
+ end
319
+ def writeln arg
320
+ write arg + "\n"
321
+ end
322
+ def pre_read
323
+ loop do
324
+ if @readBuff.size > 0
325
+ break
326
+ end
327
+ @readBuff += @residue
328
+ p
329
+ select_read
330
+ p @readBuff
331
+ if @mode == :text
332
+ @readBuff.gsub! "\r\n", "\n"
333
+ if @mode == :text && @readBuff[-1] == "\r"
334
+ @readBuff.chop!
335
+ @residue = "\r"
336
+ end
337
+ end
338
+ if @readBuff != "" || @eof
339
+ break
340
+ end
341
+ end
342
+ end
343
+ def close
344
+ @io.close if !@io.closed?
345
+ end
346
+
347
+
348
+ class OrderedQueue < Array
349
+ def initialize &prc
350
+ @ev = prc
351
+ end
352
+ alias :_insert_at :insert
353
+ def _insert item, bg = 0, ed = size
354
+ if @ev.call(bg) == @ev.call(ed - 1)
355
+ _insert ed - 1, item
356
+ else
357
+ if ed - bg == 1
358
+ _insert_at ed, item
359
+ elsif ed - bg == 2
360
+ _insert_at ed - 1, item
361
+ else
362
+ m = (bg + ed).div 2
363
+ if @ev.call(item) < @ev.call(self[m])
364
+ _insert item, bg, m + 1
365
+ elsif @ev.call(self[m + 1]) <= @ev.call(item)
366
+ _insert item, m + 1, ed
367
+ else
368
+ _insert_at m + 1, item
369
+ end
370
+ end
371
+ end
372
+ end
373
+ def insert item
374
+ if size == 0
375
+ push item
376
+ else
377
+ if @ev.call(self[0]) > @ev.call(item)
378
+ unshift item
379
+ elsif @ev.call(self[-1]) <= @ev.call(item)
380
+ push item
381
+ else
382
+ _insert item
383
+ end
384
+ end
385
+ end
386
+ end
387
+
388
+ def self.fork *modes, &prc # mode : true, execute block firstly
389
+ fi = modes.index :first
390
+ li = modes.index :late
391
+ if !li
392
+ first = true
393
+ elsif !fi
394
+ first = false
395
+ elsif fi > li
396
+ first = true
397
+ else
398
+ first = false
399
+ end
400
+ auto_cleanup = modes.include?(:auto_cleanup) ? :auto_cleanup : nil
401
+ p prc
402
+ fProc = Proc.new do
403
+ begin
404
+ p :yellow
405
+ prc.call
406
+ p :cyan
407
+ rescue SIO::SIOTerminate
408
+ p :red
409
+ rescue Exception => ex
410
+ p :blue
411
+ p ex
412
+ ex.instance_eval {
413
+ ::STDERR.write "#{backtrace[0]}:#{ex} (#{self.class})".ln
414
+ backtrace[1..-1].each do |e|
415
+ ::STDERR.write(" " + e.ln)
416
+ end
417
+ }
418
+ p
419
+ @aborted = true
420
+ abort
421
+ end
422
+ SIO.sid.delete
423
+ p :blue
424
+ doSelect #never retrun
425
+ end
426
+ ret = SIOProc.new.set_params fProc, first ? :start : :pass, auto_cleanup
427
+ cc = callcc do |cont|
428
+ cont
429
+ end
430
+ p cc
431
+ if cc.is_a? Continuation
432
+ SIO.sid.set_params cc, first ? :pass : :start
433
+ p SIO.sid
434
+ doSelect
435
+ end
436
+ p ret
437
+ ret
438
+ end
439
+ class SIOTerminate < Exception
440
+ end
441
+ def self.select_it *args
442
+ cc = callcc do |cont|
443
+ cont
444
+ end
445
+ p cc
446
+ case cc
447
+ when Continuation
448
+ sid.set_params cc, *args
449
+ doSelect
450
+ when :terminate
451
+ p args
452
+ raise SIOTerminate.new
453
+ p
454
+ end
455
+ cc
456
+ end
457
+ def self.select sio, mode, timeout = nil
458
+ select_it mode, sio, timeout
459
+ end
460
+ def self.pass
461
+ select_it :pass
462
+ end
463
+ def self.sleep t = :stop
464
+ p :purple
465
+ select_it t
466
+ p :purple
467
+ end
468
+ def self.stopBy token, timeout = :stop
469
+ res = select_it token, timeout
470
+ if res == :start
471
+ :timeout
472
+ else
473
+ token
474
+ end
475
+ end
476
+ def self.awakeBy token
477
+ SIOProc::List.each do |prc|
478
+ if prc.token == token
479
+ prc.set_params :start
480
+ end
481
+ end
482
+ select_it :start
483
+ end
484
+ def self.timer t
485
+ loop do
486
+ yield
487
+ sleep t
488
+ end
489
+ end
490
+ def self.doSelect
491
+ wios = []
492
+ rios = []
493
+ active_procs = []
494
+ hasTimer = false
495
+ SIOProc::List.each do |prc|
496
+ if prc.timeout
497
+ hasTimer = true
498
+ break
499
+ end
500
+ end
501
+ now = Time.now if hasTimer
502
+ tmout, passProc = nil
503
+ tmoutList = []
504
+ wio2SIOPrc = Hash.new{|h, k| h[k] = []}
505
+ rio2SIOPrc = Hash.new{|h, k| h[k] = []}
506
+ SIOProc::List.each do |prc|
507
+ p prc.selected?, prc.mode, prc.preceeded
508
+ next if prc.preceeded
509
+ case prc.selected? || prc.mode
510
+ when :read, :write
511
+ if prc.mode == :read
512
+ rio2SIOPrc[prc.io].push prc
513
+ rios.push prc.io
514
+ else # :write
515
+ wio2SIOPrc[prc.io].push prc
516
+ wios.push prc.io
517
+ end
518
+ if prc.timeout
519
+ if !tmout || (tmout != 0 and tmout > prc.timeout - now and tmoutList.clear)
520
+ tmout = prc.timeout - now
521
+ tmout = 0 if tmout < 0
522
+ end
523
+ end
524
+ when :timer
525
+ if !tmout
526
+ tmout = prc.timeout - now
527
+ tmout = 0 if tmout < 0
528
+ tmoutList.push prc
529
+ elsif tmout == 0 && prc.timeout - now <= 0
530
+ tmoutList.push prc
531
+ elsif tmout == prc.timeout - now
532
+ tmoutList.push prc
533
+ elsif tmout > prc.timeout - now
534
+ tmout = prc.timeout - now
535
+ tmout = 0 if tmout < 0
536
+ tmoutList.clear
537
+ tmoutList.push prc
538
+ end
539
+ when :stop
540
+ # do nothing
541
+ when :terminate, :start, true
542
+ if !tmout
543
+ tmout = 0
544
+ tmoutList.push prc
545
+ elsif tmout == 0
546
+ tmoutList.push prc
547
+ else
548
+ tmout = 0
549
+ tmoutList.clear
550
+ tmoutList.push prc
551
+ end
552
+ when :pass
553
+ passProc = prc
554
+ prc.set_params :start
555
+ else # token
556
+ # do nothing
557
+ end
558
+ end
559
+ p tmout
560
+ p [rios, wios, tmoutList]
561
+ if rios.size + wios.size + tmoutList.size == 0
562
+ p
563
+ if passProc
564
+ p passProc
565
+ tmoutList.push passProc
566
+ else
567
+ p
568
+ raise Exception.new("no selectable SIOProc")
569
+ end
570
+ end
571
+ p
572
+ selectedList, srios, swios, seios = nil
573
+ if ((!tmout && rios.size + wios.size > 0) || (tmout && tmout != 0))
574
+ p
575
+ begin
576
+ p tmout, wios, rios
577
+ srios, swios, seios = IO.select rios, wios, rios + wios, tmout
578
+ rescue Errno::EINTR
579
+ retry
580
+ end
581
+ now = nil
582
+ timeouted = (!srios || srios.size == 0) && (!swios || swios.size == 0)
583
+ [[rios, srios, rio2SIOPrc], [wios, swios, wio2SIOPrc]].each do |ios, sios, io2SIOPrc|
584
+ ios.each do |io|
585
+ e = io2SIOPrc[io].shuffle[0]
586
+ if (sios && sios.include?(io)) || (e.timeout && e.timeout < (now ||= Time.now))
587
+ e.set_selected
588
+ (selectedList ||= []).push e
589
+ end
590
+ end
591
+ end
592
+ else #tmout = 0
593
+ p
594
+ timeouted = true
595
+ end
596
+ p srios
597
+ p swios
598
+ p seios
599
+ p selectedList
600
+ p tmoutList
601
+ if timeouted
602
+ (selectedList ||= []).push *tmoutList
603
+ end
604
+ current_proc = selectedList.shuffle[0]
605
+ current_proc.reset_selected if current_proc.selected?
606
+ p current_proc
607
+ current_proc.continue
608
+ end
609
+ class SIOProc
610
+ attr_reader :mode, :sio, :timeout, :token, :preceeded
611
+ List = []
612
+ def initialize
613
+ List.push self
614
+ @mutexStack = []
615
+ @lockStat = []
616
+ @mutexList = Hash.new{|h, k| h[k] = 0}
617
+ @preceeded = false
618
+ end
619
+ def delete
620
+ List.delete self
621
+ end
622
+ def auto_cleanup?
623
+ @auto_cleanup
624
+ end
625
+ def io
626
+ if sio.is_a? SIO
627
+ sio.io
628
+ else
629
+ sio
630
+ end
631
+ end
632
+ def set_params *args
633
+ @mode, @timeout, @sio, @token, @selected = nil
634
+ args.each do |e|
635
+ case e
636
+ when Continuation, Proc
637
+ @cont = e
638
+ when :auto_cleanup
639
+ p
640
+ @auto_cleanup = true
641
+ when Symbol
642
+ @mode = e
643
+ when Time
644
+ @timeout = e
645
+ when Numeric
646
+ @timeout = Time.now + e
647
+ when SIO
648
+ @sio = e
649
+ when nil
650
+ else
651
+ @token = e
652
+ end
653
+ end
654
+ @timeout and @mode ||= :timer
655
+ self
656
+ end
657
+ class SIOTerminate < Exception
658
+ end
659
+ def set_selected
660
+ @selected = true
661
+ end
662
+ def reset_selected
663
+ @selected = false
664
+ end
665
+ def selected?
666
+ return @selected
667
+ end
668
+ def awake_at t = 0
669
+ set_params t
670
+ end
671
+ def continue arg = nil
672
+ @mutexStack.each do |e|
673
+ if e.has_semi_lock_sid self
674
+ e.lock self
675
+ end
676
+ end
677
+ m = arg || @mode
678
+ cc = @cont
679
+ @cont, @mode, @timeout, @sio, @token = nil
680
+ SIO.set_sid self
681
+ cc.call m
682
+ end
683
+ def terminate
684
+ if SIO.sid == self
685
+ raise SIOTerminate.new
686
+ end
687
+ set_params :terminate
688
+ SIO.select_it :pass
689
+ end
690
+ def awake
691
+ set_params :start
692
+ SIO.select_it :pass
693
+ end
694
+ def set_awake
695
+ set_params :start
696
+ end
697
+ def set_preceeded
698
+ @preceeded = true
699
+ end
700
+ def reset_preceeded
701
+ @preceeded = false
702
+ end
703
+ def mutexSyncLock
704
+ mutex = @mutexStack[-1]
705
+ if !@lockStat[-1]
706
+ @lockStat[-1] = true
707
+ mutex.lock self
708
+ end
709
+ end
710
+ def mutexSyncUnlock
711
+ mutex = @mutexStack[-1]
712
+ mutex.unlock self
713
+ end
714
+ def mutexSync mutex, mode
715
+ res = nil
716
+ begin
717
+ @mutexList[mutex] += 1
718
+ @mutexStack.push mutex
719
+ @lockStat.push false
720
+ case mode
721
+ when :semi
722
+ mutex.set_semi_lock_sid self
723
+ else
724
+ mutexSyncLock
725
+ end
726
+ begin
727
+ res = yield
728
+ ensure
729
+ mutexSyncUnlock
730
+ end
731
+ ensure
732
+ tmp = (@mutexList[mutex] -= 1)
733
+ if tmp == 0
734
+ @mutexList.delete mutex
735
+ end
736
+ @mutexStack.pop
737
+ @lockStat.pop
738
+ res
739
+ end
740
+ end
741
+ end
742
+ class Mutex
743
+ def initialize
744
+ @stopped = {}
745
+ @semi_lock_sids = Hash.new{|h, k| h[k] = 0}
746
+ @waiting_sids = Hash.new
747
+ end
748
+ def lock sid
749
+ while @sid && @sid != sid
750
+ @waiting_sids[sid] = true
751
+ SIO.sleep
752
+ end
753
+ @sid = sid
754
+ @semi_lock_sids.keys.each do |e|
755
+ if e != sid
756
+ e.set_preceeded
757
+ end
758
+ end
759
+ @sid.reset_preceeded
760
+ end
761
+ def unlock sid
762
+ if @sid == sid
763
+ @semi_lock_sids.keys.each do |e|
764
+ if e != self
765
+ e.reset_preceeded
766
+ end
767
+ end
768
+ @waiting_sids.each do |e|
769
+ e.set_awake
770
+ end
771
+ @sid = nil
772
+ end
773
+ end
774
+ def set_semi_lock_sid sid
775
+ @semi_lock_sids[sid] += 1
776
+ end
777
+ def reset_semi_lock_sid sid
778
+ if @semi_lock_sids.key? sid
779
+ tmp = (@semi_lock_sids[sid] -= 1)
780
+ if tmp <= 0
781
+ @semi_lock_sids.delete sid
782
+ end
783
+ end
784
+ end
785
+ def has_semi_lock_sid sid
786
+ @semi_lock_sids.key? sid
787
+ end
788
+ def synchronize mode = :normal, &prc
789
+ SIO.sid.mutexSync self, mode, &prc
790
+ end
791
+ end
792
+ STDIN = SIO.new ::STDIN
793
+ STDOUT = SIO.new ::STDOUT
794
+ STDERR = SIO.new ::STDOUT
795
+ def tmode= m
796
+ @mode = m
797
+ end
798
+ def tmode
799
+ @mode
800
+ end
801
+ def self.set_sid arg
802
+ @sid = arg
803
+ end
804
+ def self.sid
805
+ @sid
806
+ end
807
+ self.set_sid SIOProc.new
808
+
809
+ at_exit do
810
+ p :cyan, $!
811
+ if $! && !$!.is_a?(SystemExit)
812
+ $!.instance_eval {
813
+ STDERR.write "#{backtrace[0]}:#{$!} (#{self.class})".ln
814
+ backtrace[1..-1].each do |e|
815
+ STDERR.write " " + e.ln
816
+ end
817
+ }
818
+ @aborted = true
819
+ abort
820
+ end
821
+ p SIOProc::List.size
822
+ toTerm = []
823
+ SIOProc::List.each do |prc|
824
+ if prc.auto_cleanup?
825
+ toTerm.push prc
826
+ end
827
+ end
828
+ p toTerm
829
+ p SIOProc::List.size
830
+ toTerm.each &:terminate
831
+ p SIOProc::List.size
832
+ if !@aborted && SIOProc::List.size > 1
833
+ p SIOProc::List
834
+ raise Exception.new("#{SIOProc::List.size - 1} SIO Fork procedure(s) not cleand")
835
+ end
836
+ p
837
+ end
838
+ end
839
+
840
+
841
+ class String
842
+ def strip_indent
843
+ mn = 1000000
844
+ last = nil
845
+ each_line do |ln|
846
+ break if ln[-1] != "\n" and last = ln
847
+ ln.chomp =~ /^\s*/
848
+ next if $'.size == 0
849
+ if $&.size < mn
850
+ mn = $&.size
851
+ end
852
+ end
853
+ res = ""
854
+ each_line do |ln|
855
+ break if ln[-1] != "\n"
856
+ res += ln[mn..-1] if ln[mn..-1]
857
+ end
858
+ if last
859
+ if last.size <= mn
860
+ res += last.lstrip
861
+ else
862
+ res += last[mn..-1]
863
+ end
864
+ end
865
+ replace(res)
866
+ self
867
+ end
868
+ end
869
+
870
+
871
+ class SIOResolver
872
+ Sock = SIO.new UDPSocket.open, :read
873
+ begin
874
+ Sock.io.bind("0.0.0.0", rand(1024..65535))
875
+ rescue => Errno::EADDRINUSE
876
+ retry
877
+ end
878
+ resolvers = []
879
+ "/etc/resolv.conf".read_each_line do |ln|
880
+ if ln.strip =~ /nameserver\s*/ && $' =~ IPv4Regexp
881
+ resolvers.push $&
882
+ end
883
+ end
884
+ Resolvers = resolvers
885
+ MaxRetrial = 5
886
+ EachResolvTimeout = 0.2
887
+ ResolvTimeout = 1.01
888
+
889
+ def self.check_init
890
+ if !@initialized
891
+ @initialized = true
892
+ SIO.fork :auto_cleanup do
893
+ p
894
+ loop do
895
+ p
896
+ SIO.select Sock, :read
897
+ p
898
+ pkt = Sock.io.recvfrom(1024)
899
+ parsed = Net::DNS::Packet::parse(pkt)
900
+ name, ip, ttl = nil
901
+ parsed.question.each do |rr|
902
+ p rr.qType.to_s
903
+ p rr.qType.to_s.class
904
+ if rr.qType.to_s == "A"
905
+ name = rr.qName
906
+ if name[-1..-1] == "."
907
+ name.chop!
908
+ end
909
+ break
910
+ end
911
+ end
912
+ parsed.answer.each do |rr|
913
+ if rr.type == "A"
914
+ ip, ttl = rr.address.to_s, rr.ttl
915
+ break
916
+ end
917
+ end
918
+ if ip and name
919
+ p [name, ip, ttl]
920
+ Status[name].setResult ip, ttl
921
+ p
922
+ SIO.awakeBy [self, name]
923
+ p
924
+ end
925
+ end
926
+ end
927
+ end
928
+ end
929
+
930
+ p
931
+ class Status
932
+ attr_reader :expiry, :ip
933
+ def self.[] name
934
+ @list ||= Hash.new{|h, k| h[k] = Status.new(k)}
935
+ @list[name]
936
+ end
937
+ def initialize name
938
+ @name = name
939
+ @expiry = Time.at(0)
940
+ end
941
+ def resolve
942
+ p
943
+ if @resolving
944
+ p
945
+ @retrialLeft = MaxRetrial
946
+ return
947
+ end
948
+ p
949
+ @resolving = true
950
+ p
951
+ @retrialLeft = MaxRetrial
952
+ p
953
+ SIO.fork do
954
+ p
955
+ begin
956
+ p
957
+ pkt = Net::DNS::Packet.new @name
958
+ p
959
+ begin
960
+ p
961
+ @retrialLeft -= 1
962
+ p
963
+ Sock.io.send(pkt.data, 0, Resolvers[rand(0...Resolvers.size)], 53)
964
+ p
965
+ if !SIO.stopBy [self, @name], EachResolvTimeout
966
+ p
967
+ redo if @retrialLeft > 0
968
+ end
969
+ p
970
+ end
971
+ ensure
972
+ @resolving = false
973
+ end
974
+ end
975
+ p
976
+ end
977
+ def setResult ip, ttl
978
+ @ip = ip
979
+ @expiry = Time.now + ttl
980
+ end
981
+ end
982
+
983
+ def self.resolv name
984
+ check_init
985
+ stat = Status[name]
986
+ if stat.expiry > Time.now
987
+ return stat.ip
988
+ end
989
+ p
990
+ stat.resolve
991
+ p
992
+ SIO.stopBy [self, name], ResolvTimeout
993
+ p stat.ip
994
+ return stat.ip
995
+ end
996
+
997
+
998
+ end
999
+
1000
+
1001
+