1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* doc/ChangeLog-1.8.0: add changes of Ruby/Tk

* ext/tcltklib/tcltklib.c : some methods have no effect if on slave-IP
* ext/tcltklib/tcltklib.c : can create a interpreter without Tk
* ext/tcltklib/tcltklib.c : bug fix on handling exceptions
* ext/tcltklib/MANUAL.euc : modify
* ext/tk/lib/tk.rb : freeze some core modules
* ext/tk/lib/multi-tk.rb : more secure
* ext/tk/lib/tk.rb: TkVariable.new(array) --> treat the array as the
  Tk's list
* ext/tk/lib/tk.rb: improve accessibility of TkVariable object
* ext/tk/lib/tk.rb, ext/tk/lib/tkfont.rb, ext/tk/lib/tkcanvas.rb,
  ext/tk/lib/tktext.rb : fix bug of font handling
* ext/tk/lib/tkfont.rb TkFont.new() accepts compound fonts
* process.c: bug fix
* process.c: add rb_secure(2) to methods of Process::{UID,GID,Sys}
* process.c: deny handling IDs during evaluating the block given to
  the Process::{UID,GID}.switch method


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4456 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nagai 2003-08-29 08:34:14 +00:00
parent 22a5aec4b3
commit 24ff3f4448
10 changed files with 1662 additions and 172 deletions

View file

@ -1,3 +1,34 @@
Fri Aug 29 17:30:15 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* process.c: bug fix
* process.c: add rb_secure(2) to methods of Process::{UID,GID,Sys}
* process.c: deny handling IDs during evaluating the block given to
the Process::{UID,GID}.switch method
* ext/tcltklib/tcltklib.c : some methods have no effect if on slave-IP
* ext/tcltklib/tcltklib.c : can create a interpreter without Tk
* ext/tcltklib/tcltklib.c : bug fix on handling exceptions
* ext/tcltklib/MANUAL.euc : modify
* ext/tk/lib/tk.rb : freeze some core modules
* ext/tk/lib/multi-tk.rb : more secure
* ext/tk/lib/tk.rb: TkVariable.new(array) --> treat the array as the
Tk's list
* ext/tk/lib/tk.rb: improve accessibility of TkVariable object
* ext/tk/lib/tk.rb, ext/tk/lib/tkfont.rb, ext/tk/lib/tkcanvas.rb,
ext/tk/lib/tktext.rb : fix bug of font handling
* ext/tk/lib/tkfont.rb TkFont.new() accepts compound fonts
Thu Aug 28 17:30:24 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* variable.c (rb_const_get_0): should check constants defined in

View file

@ -40,6 +40,13 @@ Sun Aug 3 23:56:50 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
* eval.c (rb_call_super): should propagate previous block for
super call. [ruby-talk:77884]
Sun Aug 3 22:07:47 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tkentry.rb: support 'validatecommand' option of
TkEntry/TkSpinbox widget
* ext/tk/sample/{demos-en,demos-jp}/spin.rb: add
Sun Aug 3 19:25:28 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
* eval.c (call_trace_func): clear exception flag temporarily.
@ -51,6 +58,21 @@ Sun Aug 3 18:03:44 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* lib/un.h (help): new. % ruby -run -e help cp
Sun Aug 3 08:53:06 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/sample/{demos-en,demos-jp}/image3.rb: add
* ext/tk/lib/tkcanvas.rb: bug fix on Tk object ID management
* ext/tk/lib/tktext.rb: ditto
Sun Aug 3 02:55:52 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* process.c: modify macro to detect 'MacOS X' [ruby-talk:77849]
* ext/tcltklib/lib/tcltk.rb: bug fix ( NOT MAINTAINED : only
for running 'line2.rb' demo. )
Sun Aug 3 02:45:06 2003 Koji Arai <jca02266@nifty.ne.jp>
* numeric.c (flo_to_s): get rid of buffer overflow.
@ -60,6 +82,14 @@ Sat Aug 2 23:51:52 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* io.c (appendline): clearerr(3) before raising exception, since
exception may be captured by rescue. [ruby-talk:77794]
Sat Aug 2 09:58:13 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb: bug fix --- TkGrid failed to treat
RELATIVE PLACEMENT
* ext/tk/sample/demos-en/, demos-jp/: add or modify some
widget demo scripts
Sat Aug 2 20:59:38 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
* lib/webrick/https.rb: change an option name.
@ -90,6 +120,24 @@ Sat Aug 2 14:02:39 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
* variable.c (classname): find regular class name if not set.
[ruby-dev:20496]
Sat Aug 2 09:58:13 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb: bug fix --- forgot to entry a widget class
name of 'labelframe' widget
* ext/tk/sample/{demos-en,demos-jp}/{labelframe.rb,paned1.rb,
paned2.rb,spin.rb}: add demo-scripts to the JP/EN widget demos
Sat Aug 2 05:04:30 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tkentry.rb: bug fix of TkEntry#delete
* ext/tk/samples/: bug fix of some widget demos
* ext/tk/lib/tk.rb: support <TkVariable object> == <Symbol>
* ext/tk/lib/*.rb: freeze some object for security reason
Sat Aug 2 03:30:25 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* class.c (rb_obj_singleton_methods): should not go up to
@ -141,6 +189,10 @@ Fri Aug 1 19:48:56 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* gc.c (rb_gc): should mark backing store region on IA64.
Fri Aug 1 18:51:10 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* process.c: bug fix --- preprocessor errors occur on OpenBSD-current
Fri Aug 1 17:13:23 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
* ext/openssl/extconf.rb: should replace literally.
@ -184,6 +236,13 @@ Fri Aug 1 09:54:38 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* hash.c (env_clear): ditto.
Fri Aug 1 04:58:55 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb: bug fix --- forget to eval given block to
TkRoot.new method
* ext/tk/sample/tkoptdb-safeTk.rb: new sample script
Fri Aug 1 00:52:58 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* gc.c (Init_stack): IA64 requires STACK_LEVEL_MAX to be less than
@ -194,11 +253,38 @@ Thu Jul 31 23:44:00 2003 Masatoshi SEKI <m_seki@mva.biglobe.ne.jp>
* lib/erb.rb: import erb-2.0.4b4.
Thu Jul 31 23:04:45 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/sample/resource.en, ext/tk/sample/resource.jp:
wrong resource file format
* ext/tk/lib/tk.rb: add Tk::Encoding.{encoding_convertfrom,
encoding_convertto}
* ext/tk/lib/tk.rb: add TkOptionDB.read_with_encoding to read
non-utf8 resource file
Thu Jul 31 23:02:47 2003 NAKAMURA Usaku <usa@ruby-lang.org>
* ext/etc/etc.c: revert getenv()'s prototype. use it only when _WIN32
is not defined.
Thu Jul 31 20:52:40 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb: (IMPORTANT BUG FIX) scan of event keywords
doesn't work on recent versions of Tck/Tk
* ext/tk/lib/tk.rb: initialize error of instance variable on
TkComposite
* ext/tk/lib/multi-tk.rb: initialize error on encoding-system on
MultiTkIp
* ext/tk/lib/tk.rb: trouble on destroying widgets
* ext/tk/sample/demos-en/, demos-jp/: add JP and EN version of
Ruby/Tk widget demos
Thu Jul 31 15:25:12 2003 NAKAMURA Usaku <usa@ruby-lang.org>
* array.c (rb_ary_collect): must get length of array for each
@ -223,6 +309,17 @@ Thu Jul 31 08:18:00 2003 Nathaniel Talbott <ntalbott@ruby-lang.org>
* lib/test/unit.rb: A useful return code is now set if tests fail when
running automatically using the Console::TestRunner.
Thu Jul 31 07:59:18 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb: wrap the command-proc of TkScale --- pass
the numeric object to the proc
* ext/tk/lib/tk.rb: better support for widgets created on
Tk interpreter (without Ruby)
* ext/tk/lib/multi-tk.rb: a little more stable on Multiple Tk
interpreters running
Thu Jul 31 00:17:19 2003 Shugo Maeda <shugo@ruby-lang.org>
* lib/net/ftp.rb (return_code): obsolete.
@ -310,6 +407,23 @@ Wed Jul 30 09:31:55 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* ext/socket/socket.c (sock_initialize): rename from sock_init()
to get rid of conflict with OS/2 socket library.
Wed Jul 30 07:23:14 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tkentry.rb: fix lack of methods for TkEntry
* ext/tk/lib/multi-tk.rb, ext/tk/lib/tk.rb,
ext/tk/lib/tkdialog.rb, ext/tk/lib/tkentry.rb,
ext/tk/sample/safe-tk.rb, ext/tk/sample/tktimer2.rb: bug fix
* ext/tk/lib/multi-tk.rb: MultiTkIp.new_* accept a block to
eval under the new interpreter
Wed Jul 30 04:36:30 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tcltklib/tcltklib.c,
ext/tk/lib/tk.rb, ext/tk/lib/tkafter.rb: additional check of
Tk interpreters' status for a little more safety
Wed Jul 30 02:37:12 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* marshal.c (w_object): if object responds to 'marshal_dump',
@ -398,6 +512,18 @@ Mon Jul 28 22:57:52 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* io.c (rb_f_getc): $stdin may not be IO. [ruby-dev:20973]
Tue Jul 29 16:20:36 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tcltklib/tcltklib.c: bug fix and
change mainloop_abort_on_no_widget_cmd => mainloop_abort_on_exception
( to avoid thread timing trouble on accessing destroyed widgets )
* ext/tk/lib/multi-tk.rb: change default mode of
mainloop_abort_on_exception on multi-tk.rb
* ext/tk/lib/multi-tk.rb: fix a bug of the procedure for
'Delete' button on the safe-Tk frmae
Tue Jul 29 12:22:28 2003 why the lucky stiff <ruby-cvs@whytheluckystiff.net>
* ext/syck/token.c: prefixed many constants and definitions
@ -413,6 +539,12 @@ Tue Jul 29 12:15:37 2003 NAKAMURA Usaku <usa@ruby-lang.org>
* win32/win32.h: add arguments to definitions of functions if possible.
Tue Jul 29 08:05:30 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb, ext/tk/lib/tkdialog.rb, ext/tk/lib/tktext.rb,
ext/tk/sample/tkbiff.rb, ext/tk/sample/tkdialog.rb,
ext/tk/sample/tkform.rb: bug fix ( tested with Ruby/Tk widget demo )
Tue Jul 29 04:22:08 2003 why the lucky stiff <ruby-cvs@whytheluckystiff.net>
* ext/syck/syck.h: Added 'syck' yacc prefixes.
@ -428,6 +560,20 @@ Tue Jul 29 03:53:28 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
* ext/openssl/lib/net/https.rb (use_ssl=): raise ProtocolError if
connection is set up already.
Tue Jul 29 01:45:32 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tcltklib/tcltklib.c: use RTEST()
Tue Jul 29 01:24:32 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tcltklib/tcltklib.c: bug fix
* ext/tk/lib/multi-tk.rb: bug fix and pack options are pssed
to the safeTk container
* ext/tk/sample/safe-tk.rb: add example for pack options of
safeTk container
Mon Jul 28 23:23:08 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* file.c (Init_File): IO should include File::Const.
@ -460,6 +606,16 @@ Mon Jul 28 15:32:04 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* io.c (argf_forward): utility function to forward method to
current_file.
Mon Jul 28 06:10:13 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tcltklib/tcltklib.c: bug fix
* ext/lib/tk/multi-tk.rb: bug fix
* ext/lib/tk/multi-tk.rb: add methods depend on Tcl's 'interp' command
* ext/lib/tk/multi-tk.rb: suppot safe-level control of each interpreter
Mon Jul 28 03:08:47 2003 Akinori MUSHA <knu@iDaemons.org>
* lib/set.rb: each() should return self.
@ -482,6 +638,22 @@ Sun Jul 27 21:16:30 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* mkconfig.rb: initialize global variables to avoid warnings.
Sun Jul 27 19:35:06 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tcltklib/tcltklib.c: add some methods to support
multiple interpreters (low level)
* ext/tk/lib/multi-tk.rb: new library to support multiple Tk
interpreters (high level)
* ext/tcltklib/demo/safeTk.rb: new sample of safeTk interpreter
* ext/tk/sample/safe-tk.rb: new sample of multi-tk.rb
* ext/tk/lib/tk.rb: bug fix and add feature to supprt multi-tk
* ext/tk/lib/tkafter.rb: ditto
Sun Jul 27 14:43:37 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>
* lib/debug.rb: fix breakpoint parameter parsing/checking.
@ -558,6 +730,18 @@ Fri Jul 26 00:04:25 2003 NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>
- cert_store_view.rb: certificate store viewer with FXRuby. Uses
c_rehash.rb, crlstore.rb and certstore.rb.
Fri Jul 25 16:43:03 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tcltklib/tcltklib.c: add TclTkIp#create_slave,
TclTkIp#_make_safe and TclTkIp#safe?
* ext/tcltklib/MANUAL.euc: modify descriptions
* ext/tk/lib/tk.rb: bug fix [ruby-talk:76980] and modify to
support multi Tk IPs
* ext/tk/lib/tkafter.rb: modify to support multi Tk IPs
Fri Jul 25 15:47:39 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
* ext/openssl/extconf.rb: add check for BN_rand_range() and
@ -725,6 +909,18 @@ Wed Jul 23 18:21:52 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* ext/io/wait: imported.
Wed Jul 23 16:07:35 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* process.c: unify indentation
* configure.in: add --enable-setreuid option
* ext/tcltklib/tcltklib.c: TclTkIp.new accepts 'ip-name' and 'options'
* ext/tk/lib/tk.rb: support arguments of TclTkIp.new
* ext/tk/lib/tk*.rb: preparations for multi-Tk interpreter support
Wed Jul 23 15:49:01 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* string.c (rb_str_lstrip_bang): strip NUL along with white
@ -743,6 +939,12 @@ Wed Jul 23 10:11:15 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* ext/iconv/iconv.c (iconv_convert): stringify argument.
Wed Jul 23 02:39:46 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* process.c: add a module for raw syscalls to control UID/GID
* process.c: add modules for portable UID/GID control
Tue Jul 22 19:16:40 2003 Tanaka Akira <akr@m17n.org>
* ext/iconv/iconv.c (iconv_failure_initialize): limit
@ -906,6 +1108,11 @@ Thu Jul 17 13:42:53 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* lib/ftools.rb (File::makedirs): do not handle "//" as a directory.
Thu Jul 17 06:40:28 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb: recover and fix typo : Tk.chooseDirectory
(Tk8.4 feature)
Wed Jul 16 16:23:58 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (rb_proc_new): call svalue_to_avalue for yield argument.
@ -987,6 +1194,13 @@ Fri Jul 11 16:09:09 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* util.c (ruby_strtod): exp should be less than MDMAXEXPT.
Fri Jul 11 07:17:47 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb: not create a Tcl/Tk interpreter if already
defined TkCore::INTERP
* ext/tk/lib/tk.rb: bugfix on TkWindow#configure
Thu Jul 10 14:42:02 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* math.c (math_log): nan takes a dummy argument on Cygwin 1.5.0.
@ -1176,6 +1390,13 @@ Wed Jul 2 01:32:40 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* lib/net/pop.rb (Net::POP3#start): typofix.
Tue Jul 1 22:08:19 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb: TkWindow include TkWinfo
* ext/tk/lib/tk.rb: treat unknown widget classes as subclasses
of TkWindow
Tue Jul 1 19:02:12 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* parse.y (rb_intern): should use mbclen instead of mblen.
@ -1236,17 +1457,48 @@ Thu Jun 26 21:34:49 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
arguement type mismatch, and inline method_list().
[ruby-core:01198]
Wed Jun 25 14:40:33 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb: add and modify methods ---
TkWidget.database_class, TkWidget.database_classname,
TkWidget#database_class, TkWidget#database_classname
* ext/tk/lib/tk.rb: instances of a subclass of TkToplevel or
TkFrame are created with ":class=>subclass" option as default.
* ext/tk/sample/tkoptdb.rb: add a new part
Wed Jun 25 12:52:58 2003 Matthew Dempsky <jivera@flame.org>
* class.c (rb_generic_class_instance_methods): merge argument
check (and warning) into one function; following DRY principle.
[ruby-core:01193]
Wed Jun 25 05:49:10 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb: add widget destroy hook binding to TkBindTag::ALL
* ext/tk/lib/tkcanvas.rb: Although requiring manual control of GC,
memory eating problem of TkCanvas Items is fixed.
* ext/tk/lib/tktext.rb: add some methods and bug fix
Wed Jun 25 00:14:30 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* variable.c (autoload_delete): should delete Qundef from iv_tbl.
(ruby-bugs-ja PR#504)
Tue Jun 24 16:46:07 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb: bug fix on TkToplevel, TkFrame,
TkPanedwindow, TkOptionDB
* ext/tk/lib/tk.rb: TkOptionDB --- make it more secure to use procs
defined on resourceDB
* ext/tk/sample/tkoptdb.rb, resource.ja, resource.en:
sample script how to use TkOptionDB.
Tue Jun 24 14:22:41 2003 why the lucky stiff <ruby-cvs@whytheluckystiff.net>
* lib/yaml/types.rb: replaced Kernel::Hash reference with Object::Hash
@ -1318,6 +1570,10 @@ Mon Jun 23 16:18:12 2003 Tanaka Akira <akr@m17n.org>
* time.c (time_arg): initialize v[6] even when argc is 10 to
avoid valgrind error.
Mon Jun 23 14:22:44 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb: bug fix on TkRoot and TkToplevel
Mon Jun 23 08:24:01 2003 Florian Frank <flori@nixe.ping.de>
* string.c (rb_str_upto): generate sequence according to "succ"
@ -1352,6 +1608,18 @@ Sun Jun 22 23:42:20 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* file.c (rb_file_s_readlink): expand buffer until readlink
succeed.
Sun Jun 22 16:17:02 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb: TkRoot.new and TkToplevel.new accept Wm
commands as elements
* ext/tk/lib/tk.rb: TkMenu --- add some methods
* ext/tk/lib/tk.rb: TkOptionMenubutton --- bug fix
* ext/tk/sample/tkmenubutton.rb: sample of TkMenubutton and
TkOptionMenubutton
Sat Jun 21 23:15:08 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (proc_invoke): should not propagate distination tag if
@ -1366,6 +1634,25 @@ Sat Jun 21 13:56:09 2003 Takaaki Uematsu <uema2x@jcom.home.ne.jp>
* wince/resource.rb: include winver.h in wince3.0.
Sat Jun 21 12:55:17 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb: TkRoot.new and TkToplevel.new accept Wm commands
as elements of a hash argument.
* ext/tk/sample/tktimer2.rb: add comments about the usage of a
TkTimer object.
Sat Jun 21 08:47:22 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk*.rb: remove direct-accesses to TkComm::INTERP and
TkComm::INITIALIZE_TARGETS
* ext/tk/lib/tk*.rb: use TkINTERP_SETUP_SCRIPTS constant for setting
up the interpreter
* ext/tcltklib/tcltklib.c: support to create a safe interpreter
with safe-Tk
Fri Jun 20 23:28:27 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (proc_invoke): should not propagate TAG_BREAK and
@ -1385,6 +1672,10 @@ Fri Jun 20 15:04:28 2003 NAKAMURA Usaku <usa@ruby-lang.org>
* ruby.c (proc_options): ditto.
Fri Jun 20 14:52:46 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tcltklib/tcltklib.c: Tk interpreter returns TAINTED strings.
Fri Jun 20 03:09:21 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* parse.y (new_yield): distinguish "yield 1,2" and "yield [1,2]".
@ -1410,6 +1701,42 @@ Thu Jun 19 22:51:41 2003 Masatoshi SEKI <m_seki@mva.biglobe.ne.jp>
lib/drb/invokemethod.rb, lib/drb/observer.rb,
lib/drb/timeridconv.rb, lib/drb/unix.rb: import drb-2.0.4b3
Thu Jun 19 16:14:43 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tcltklib/tcltklib.c (lib_do_one_event): change default
value of the argument
* ext/tcltklib/tcltklib.c (lib_do_one_event): returns true/false
* ext/tcltklib/tcltklib.c: add TclTkLib::EventFlag::NONE ( == 0 )
* ext/tcltklib/tcltklib.c: add set_no_event_wait() and
get_no_event_wait()
* ext/tcltklib/MANUAL.euc: modify
* ext/tcltklib/README.euc: ditto
* ext/tk/lib/tk.rb: change default value of TkCore.do_one_event
argument
* ext/tk/lib/tk.rb: add TkCore.set_no_event_wait(wait) and
TkCore.get_no_event_wait
* ext/tk/lib/tk.rb: add Tk.exit ( == destroy root widget )
* ext/tk/lib/tkafter.rb: rename TkAfter => TkTimer (TkAfter is
an alias name)
* ext/tk/lib/tkafter.rb: set_callback returns self
* ext/tk/lib/tkafter.rb: continue() raises an exception, if already
running or no procedure.
* ext/tk/lib/tkafter.rb: skip() raises an exception, if not running.
* ext/tk/sample/tktimer2.rb: new sample for TkTimer class.
Thu Jun 19 16:13:54 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* rubytest.rb: add library path to include standard libraries.
@ -1435,6 +1762,88 @@ Wed Jun 18 23:41:27 2003 Marc Cartright <marc@isri.unlv.edu>
deflate/inflate will return Z_BUF_ERROR, even though another call
is required by the zlib library.
Wed Jun 18 19:46:21 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb: bug fix
* ext/tk/lib/tk.rb: rename 'no_create' option to 'without_creating'
* ext/tk/lib/tk.rb: add TkWindow#pack_in, TkWindow#grid_in,
TkWindow#place_in
* ext/tk/lib/tk.rb: add TkWindow#bind_class and TkWindow#database_class
* ext/tk/lib/tk.rb: add TkBindTag.new_by_name and TkDatabaseClass
for binding to database class
* ext/tk/lib/tk.rb: check varname whether already exsist or not.
(TkVarAccess.new)
* ext/tk/lib/tk.rb: TkTextWin#bbox returns an array of four numbers
* ext/tk/lib/tk.rb: autoload TkDialog2, TkWarning2
* ext/tk/lib/tk.rb: scan event callback arguments and convert
to proper type
* ext/tk/lib/tk.rb: TkBindTag.new accepts a block
* ext/tk/lib/tk.rb: If given taglist, TkWindow#bindtags(taglist)
returns taglist
* ext/tk/lib/tk.rb: add TkWindow#bindtags=(taglist)
* ext/tk/lib/tk.rb: Tk.focue and Tk.focus_lastfor return nil
if there is no target widget.
* ext/tk/lib/tk.rb: Tk::Wm.client returns the argument string
when setting name
* ext/tk/lib/tk.rb: TkGrid.columnconfiginfo and rowconfiginfo
given a slot return a number.
* ext/tk/lib/tk.rb: TkWindow.grid_columnconfiginfo and
grid_rowconfiginfo --- ditto
* ext/tk/lib/tk.rb: rename and define alias :: TkOption ==> TkOptionDB
* ext/tk/lib/tk.rb: define alias :: TkTimer ==> TkAfter
* ext/tk/lib/tk.rb: some instance methods change from public to private
* ext/tk/lib/tk.rb: some TkComm methods change to module functions
* ext/tk/lib/tk.rb: add support for -displayof option to some
TkWinfo methods
* ext/tk/lib/tk.rb: bind, bind_append and bind_remove ---
returns the target of event-binding
* ext/tk/lib/tk.rb: add Tk8.4 features
* ext/tk/lib/tk.rb: add TkPaneWindow
* ext/tk/lib/tkdialog.rb: bug fix
* ext/tk/lib/tkdialog.rb: some methods return self
* ext/tk/lib/tkdialog.rb: add TkTextMark#+(mod) and TkTextMark#-(mod)
* ext/tk/lib/tkdialog.rb: add some methods
* ext/tk/lib/tkcanvas.rb: bug fix and some methods return self
* ext/tk/lib/tkentry.rb: some methods return self
* ext/tk/lib/tkentry.rb: TkEntry#bbox returns an array of four numbers
* ext/tk/lib/tkentry.rb: scan validatecommand arguments and
convert to proper type
* ext/tk/lib/tkbgerror.rb: support to define a error handler by user
* ext/tcltklib/tcltklib.c: [ruby-talk:60759]
Wed Jun 18 13:50:06 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (rb_eval): should dispatch based on ID type.
@ -1520,6 +1929,27 @@ Fri Jun 13 09:24:39 2003 Shugo Maeda <shugo@ruby-lang.org>
* lib/net/ftp.rb (putbinaryfile): rescue FTPPermError.
Thu Jun 12 22:13:13 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb : add 'no_create' option to widget
initialize method.
* ext/tk/MANIFEST : forgot to commit when added tkmacpkg.rb
and tkwinpkg.rb
* ext/tk/lib/README : ditto.
Thu Jun 12 21:14:11 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb : widget configure returns self (for method
call chain)
* ext/tk/lib/tkmacpkg.rb : Mac resource (not new but not
included until now)
* ext/tk/lib/tkwinpkg.rb : Win DDE and registry (not new but not
included until now)
Tue Jun 10 14:26:30 2003 why the lucky stiff <ruby-cvs@whytheluckystiff.net>
* ext/syck/token.c: preserve newlines prepended to a block.
@ -1550,6 +1980,14 @@ Mon Jun 9 19:02:33 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* process.c (proc_getgroups, proc_setgroups): raise
NotImplementedError unless available. [ruby-talk:73014]
Mon Jun 9 18:09:11 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tcltklib/tcltklib.c: fixed 100% CPU problem of Tk.mainloop
Mon Jun 9 15:50:24 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tcltklib/tcltklib.c: renewal Tk.mainloop
Sun Jun 8 13:37:21 2003 Takaaki Uematsu <uema2x@jcom.home.ne.jp>
* wince/setup.mak: set SUBSYSTEM in each platform.
@ -7886,6 +8324,11 @@ Thu Jun 6 11:42:15 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* lib/thread.rb (Queue::pop): get rid of race condition.
Wed Jun 5 01:56:47 2002 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tcltklib/tcltklib.c: Stop the running zombi-eventloop when
mainloop_watchdog is killed.
Tue Jun 4 23:09:24 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
* range.c (range_include): should be based on "<=>", whereas
@ -7899,6 +8342,31 @@ Tue Jun 4 18:28:37 2002 WATANABE Hirofumi <eban@ruby-lang.org>
* ext/Win32API/extconf.rb: refactoring.
Tue Jun 4 07:03:33 2002 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tkfont.rb: Fix bugs on TkFont.init_widget_font for Tk8.x.
* ext/tk/lib/tkafter.rb: Add self to 1st argument of interval-
and loop-proc
TkAfter#current_interval returns an interval (sleep) time value
TkAfter#current_args returns an array of arguments
TkAfter#return_value returns a return value of last loop-proc
* ext/tk/lib/tk*.rb: Allow to use Symbols for parameters.
* ext/tk/lib/tkcanvas.rb: (TkcItem) Add 'coords' parameter to the
canvas item constructor (for new notation of constructor).
* ext/tcltklib/tcltklib.c: New 'mainloop' and 'mainloop_watchdog'.
* ext/tk/lib/tk.rb: (Tk.restart) Add 'app-name' paramater and
'use' parameter.
* ext/tk/lib/tk.rb: Add new parameter 'widgetname' to the widget
constructor to support effective use of Resource Database.
* ext/tk/lib/tk.rb: TkOption::get always returns a tainted string.
Tue Jun 4 00:45:50 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* ext/socket/addrinfo.h: typo.

View file

@ -1,5 +1,5 @@
(tof)
2003/07/25 Hidetoshi NAGAI
2003/08/07 Hidetoshi NAGAI
本ドキュメントには古い tcltk ライブラリtcltklib ライブラリの説明
が含まれていますが,その記述内容は古いものとなっています.
@ -263,6 +263,12 @@ require "tcltklib"
: Tk インタープリタ上で例外を発生した際に,イベントループをエ
: ラー停止させるかどうかの設定状態を true/false で得る.
num_of_mainwindows
: 現在のメインウィンドウ (ルートウィジェット) の数を返す.
: メインウィンドウは一つのインタープリタに付き最大一つである
: ので,この値は現在 Tk の機能が有効であるインタープリタの総
: 数に等しい.
クラス TclTkIp
クラスメソッド
@ -274,6 +280,11 @@ require "tcltklib"
: 引数として与えるオプションと同様の情報を文字列として与える.
: 与えられた情報はroot widget 生成の際に用いられる.
: ( e.g. TclTkIp.new('FOO', '-geometry 500x200 -use 0x2200009') )
: もし options に敢えて nil または false を与えた場合Tk ライ
: ブラリが導入されていない (つまりは Tcl のみの) インタープリ
: タを生成する.この場合は GUI 環境は必要ないため,ウインドウ
: システムが存在しない,または使用できない環境でも Tcl インター
: プリタを生成しTcl やその拡張ライブラリを活用することができる.
インスタンスメソッド
create_slave(name, safe=false)
@ -331,17 +342,26 @@ require "tcltklib"
_return_value
: 直前の Tcl/Tk 上での評価の実行結果としての戻り値を返す.
mainloop : 引数を含めて TclTkLib.mainloop に同じ
mainloop_watchdog : 引数を含めて TclTkLib.mainloop_watchdog に同じ
do_one_event : 引数を含めて TclTkLib.do_one_event に同じ
set_eventloop_tick : 引数を含めて TclTkLib.set_eventloop_tick に同じ
get_eventloop_tick : 引数を含めて TclTkLib.get_eventloop_tick に同じ
set_eventloop_weight : 引数を含めて TclTkLib.set_eventloop_weight に同じ
get_eventloop_weight : 引数を含めて TclTkLib.set_eventloop_weight に同じ
mainloop
mainloop_watchdog
: スレーブ IP の場合にはイベントループを起動せずに nil を返す.
: それ以外の点では引数を含めて TclTkLib の同名メソッドに同じ.
do_one_event
: スレーブ IP の場合には引数のイベントフラグに DONT_WAIT が
: 強制的に追加される (イベント待ちでスリープすることは禁止)
: それ以外の点では引数を含めて TclTkLib の同名メソッドに同じ.
set_eventloop_tick
get_eventloop_tick
set_no_event_wait
get_no_event_wait
set_eventloop_weight
get_eventloop_weight
mainloop_abort_on_exception
: 引数を含めて TclTkLib.mainloop_abort_on_exception に同じ
mainloop_abort_on_exception=
: 引数を含めて TclTkLib.mainloop_abort_on_exception= に同じ
: スレーブ IP の場合には値の設定が許されない (無視される)
: それ以外の点では引数を含めて TclTkLib の同名メソッドに同じ.
クラス TkCallbackBreak < StandardError
クラス TkCallbackContinue < StandardError

View file

@ -8,6 +8,13 @@
#include "rubysig.h"
#undef EXTERN /* avoid conflict with tcl.h of tcl8.2 or before */
#include <stdio.h>
#ifdef HAVE_STDARG_PROTOTYPES
#include <stdarg.h>
#define va_init_list(a,b) va_start(a,b)
#else
#include <varargs.h>
#define va_init_list(a,b) va_start(a)
#endif
#include <string.h>
#include <tcl.h>
#include <tk.h>
@ -93,6 +100,25 @@ static int ip_ruby _((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST*));
static int ip_ruby _((ClientData, Tcl_Interp *, int, char **));
#endif
/*---- class TclTkIp ----*/
struct tcltkip {
Tcl_Interp *ip; /* the interpreter */
int return_value; /* return value */
};
static struct tcltkip *
get_ip(self)
VALUE self;
{
struct tcltkip *ptr;
Data_Get_Struct(self, struct tcltkip, ptr);
if (ptr == 0) {
rb_raise(rb_eTypeError, "uninitialized TclTkIp");
}
return ptr;
}
/* Tk_ThreadTimer */
static Tcl_TimerToken timer_token = (Tcl_TimerToken)NULL;
@ -155,6 +181,27 @@ get_eventloop_tick(self)
return INT2NUM(timer_tick);
}
static VALUE
ip_set_eventloop_tick(self, tick)
VALUE self;
VALUE tick;
{
struct tcltkip *ptr = get_ip(self);
if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
/* slave IP */
return get_eventloop_tick(self);
}
return set_eventloop_tick(self, tick);
}
static VALUE
ip_get_eventloop_tick(self)
VALUE self;
{
return get_eventloop_tick(self);
}
static VALUE
set_no_event_wait(self, wait)
VALUE self;
@ -179,6 +226,27 @@ get_no_event_wait(self)
return INT2NUM(no_event_wait);
}
static VALUE
ip_set_no_event_wait(self, wait)
VALUE self;
VALUE wait;
{
struct tcltkip *ptr = get_ip(self);
if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
/* slave IP */
return get_no_event_wait(self);
}
return set_no_event_wait(self, wait);
}
static VALUE
ip_get_no_event_wait(self)
VALUE self;
{
return get_no_event_wait(self);
}
static VALUE
set_eventloop_weight(self, loop_max, no_event)
VALUE self;
@ -206,7 +274,29 @@ get_eventloop_weight(self)
}
static VALUE
rb_evloop_abort_on_exc(self)
ip_set_eventloop_weight(self, loop_max, no_event)
VALUE self;
VALUE loop_max;
VALUE no_event;
{
struct tcltkip *ptr = get_ip(self);
if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
/* slave IP */
return get_eventloop_weight(self);
}
return set_eventloop_weight(self, loop_max, no_event);
}
static VALUE
ip_get_eventloop_weight(self)
VALUE self;
{
return get_eventloop_weight(self);
}
static VALUE
lib_evloop_abort_on_exc(self)
VALUE self;
{
if (event_loop_abort_on_exc > 0) {
@ -219,7 +309,14 @@ rb_evloop_abort_on_exc(self)
}
static VALUE
rb_evloop_abort_on_exc_set(self, val)
ip_evloop_abort_on_exc(self)
VALUE self;
{
return lib_evloop_abort_on_exc(self);
}
static VALUE
lib_evloop_abort_on_exc_set(self, val)
VALUE self, val;
{
rb_secure(4);
@ -230,7 +327,27 @@ rb_evloop_abort_on_exc_set(self, val)
} else {
event_loop_abort_on_exc = 0;
}
return rb_evloop_abort_on_exc(self);
return lib_evloop_abort_on_exc(self);
}
static VALUE
ip_evloop_abort_on_exc_set(self, val)
VALUE self, val;
{
struct tcltkip *ptr = get_ip(self);
if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
/* slave IP */
return lib_evloop_abort_on_exc(self);
}
return lib_evloop_abort_on_exc_set(self, val);
}
static VALUE
lib_num_of_mainwindows(self)
VALUE self;
{
return INT2FIX(Tk_GetNumMainWindows());
}
VALUE
@ -379,6 +496,21 @@ lib_mainloop(argc, argv, self)
return lib_mainloop_launcher(check_rootwidget);
}
static VALUE
ip_mainloop(argc, argv, self)
int argc;
VALUE *argv;
VALUE self;
{
struct tcltkip *ptr = get_ip(self);
if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
/* slave IP */
return Qnil;
}
return lib_mainloop(argc, argv, self);
}
VALUE
lib_watchdog_core(check_rootwidget)
VALUE check_rootwidget;
@ -464,10 +596,26 @@ lib_mainloop_watchdog(argc, argv, self)
}
static VALUE
lib_do_one_event(argc, argv, self)
ip_mainloop_watchdog(argc, argv, self)
int argc;
VALUE *argv;
VALUE self;
{
struct tcltkip *ptr = get_ip(self);
if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
/* slave IP */
return Qnil;
}
return lib_mainloop_watchdog(argc, argv, self);
}
static VALUE
lib_do_one_event_core(argc, argv, self, is_ip)
int argc;
VALUE *argv;
VALUE self;
int is_ip;
{
VALUE vflags;
int flags;
@ -479,6 +627,16 @@ lib_do_one_event(argc, argv, self)
Check_Type(vflags, T_FIXNUM);
flags = FIX2INT(vflags);
}
if (is_ip) {
/* check IP */
struct tcltkip *ptr = get_ip(self);
if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
/* slave IP */
flags |= TCL_DONT_WAIT;
}
}
ret = Tcl_DoOneEvent(flags);
if (ret) {
return Qtrue;
@ -487,25 +645,25 @@ lib_do_one_event(argc, argv, self)
}
}
/*---- class TclTkIp ----*/
struct tcltkip {
Tcl_Interp *ip; /* the interpreter */
int return_value; /* return value */
};
static struct tcltkip *
get_ip(self)
static VALUE
lib_do_one_event(argc, argv, self)
int argc;
VALUE *argv;
VALUE self;
{
struct tcltkip *ptr;
Data_Get_Struct(self, struct tcltkip, ptr);
if (ptr == 0) {
rb_raise(rb_eTypeError, "uninitialized TclTkIp");
}
return ptr;
return lib_do_one_event_core(argc, argv, self, 0);
}
static VALUE
ip_do_one_event(argc, argv, self)
int argc;
VALUE *argv;
VALUE self;
{
return lib_do_one_event_core(argc, argv, self, 0);
}
/* Tcl command `ruby' */
static VALUE
ip_eval_rescue(failed, einfo)
@ -551,6 +709,19 @@ lib_restart(self)
return Qnil;
}
static VALUE
ip_restart(self)
VALUE self;
{
struct tcltkip *ptr = get_ip(self);
if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
/* slave IP */
return Qnil;
}
return lib_restart(self);
}
static int
#if TCL_MAJOR_VERSION >= 8
ip_ruby(clientData, interp, argc, argv)
@ -651,6 +822,7 @@ ip_init(argc, argv, self)
struct tcltkip *ptr; /* tcltkip data struct */
VALUE argv0, opts;
int cnt;
int with_tk = 1;
/* create object */
Data_Get_Struct(self, struct tcltkip, ptr);
@ -675,7 +847,12 @@ ip_init(argc, argv, self)
switch(cnt) {
case 2:
/* options */
Tcl_SetVar(ptr->ip, "argv", StringValuePtr(opts), 0);
if (opts == Qnil || opts == Qfalse) {
/* without Tk */
with_tk = 0;
} else {
Tcl_SetVar(ptr->ip, "argv", StringValuePtr(opts), 0);
}
case 1:
/* argv0 */
if (argv0 != Qnil) {
@ -687,17 +864,19 @@ ip_init(argc, argv, self)
}
/* from Tcl_AppInit() */
DUMP1("Tk_Init");
if (Tk_Init(ptr->ip) == TCL_ERROR) {
rb_raise(rb_eRuntimeError, "%s", ptr->ip->result);
}
DUMP1("Tcl_StaticPackage(\"Tk\")");
if (with_tk) {
DUMP1("Tk_Init");
if (Tk_Init(ptr->ip) == TCL_ERROR) {
rb_raise(rb_eRuntimeError, "%s", ptr->ip->result);
}
DUMP1("Tcl_StaticPackage(\"Tk\")");
#if TCL_MAJOR_VERSION >= 8
Tcl_StaticPackage(ptr->ip, "Tk", Tk_Init, Tk_SafeInit);
Tcl_StaticPackage(ptr->ip, "Tk", Tk_Init, Tk_SafeInit);
#else
Tcl_StaticPackage(ptr->ip, "Tk", Tk_Init,
(Tcl_PackageInitProc *) NULL);
Tcl_StaticPackage(ptr->ip, "Tk", Tk_Init,
(Tcl_PackageInitProc *) NULL);
#endif
}
/* add ruby command to the interpreter */
#if TCL_MAJOR_VERSION >= 8
@ -900,6 +1079,32 @@ ip_fromUTF8(self, str, encodename)
}
static VALUE
#ifdef HAVE_STDARG_PROTOTYPES
create_ip_exc(VALUE interp, VALUE exc, const char *fmt, ...)
#else
create_ip_exc(interp, exc, fmt, va_alist)
VALUE interp:
VALUE exc;
const char *fmt;
va_dcl
#endif
{
va_list args;
char buf[BUFSIZ];
VALUE einfo;
va_init_list(args,fmt);
vsnprintf(buf, BUFSIZ, fmt, args);
buf[BUFSIZ - 1] = '\0';
va_end(args);
einfo = rb_exc_new2(exc, buf);
rb_iv_set(einfo, "interp", interp);
Tcl_ResetResult(get_ip(interp)->ip);
return einfo;
}
static VALUE
ip_invoke_real(argc, argv, obj)
int argc;
@ -934,7 +1139,9 @@ ip_invoke_real(argc, argv, obj)
if (!Tcl_GetCommandInfo(ptr->ip, cmd, &info)) {
/* if (event_loop_abort_on_exc || cmd[0] != '.') { */
if (event_loop_abort_on_exc > 0) {
rb_raise(rb_eNameError, "invalid command name `%s'", cmd);
/*rb_ip_raise(obj, rb_eNameError, "invalid command name `%s'", cmd);*/
return create_ip_exc(obj, rb_eNameError,
"invalid command name `%s'", cmd);
} else {
if (event_loop_abort_on_exc < 0) {
rb_warning("invalid command name `%s' (ignore)", cmd);
@ -1021,7 +1228,8 @@ ip_invoke_real(argc, argv, obj)
/* exception on mainloop */
if (ptr->return_value == TCL_ERROR) {
if (event_loop_abort_on_exc > 0 && !Tcl_InterpDeleted(ptr->ip)) {
rb_raise(rb_eRuntimeError, "%s", ptr->ip->result);
/*rb_ip_raise(obj, rb_eRuntimeError, "%s", ptr->ip->result);*/
return create_ip_exc(obj, rb_eRuntimeError, "%s", ptr->ip->result);
} else {
if (event_loop_abort_on_exc < 0) {
rb_warning("%s (ignore)", ptr->ip->result);
@ -1137,6 +1345,9 @@ ip_invoke(argc, argv, obj)
/* get result & free allocated memory */
result = *alloc_result;
if (rb_obj_is_kind_of(result, rb_eException)) {
rb_exc_raise(result);
}
free(alloc_argv);
free(alloc_result);
@ -1197,6 +1408,10 @@ Init_tcltklib()
rb_define_module_function(lib, "mainloop_watchdog",
lib_mainloop_watchdog, -1);
rb_define_module_function(lib, "do_one_event", lib_do_one_event, -1);
rb_define_module_function(lib, "mainloop_abort_on_exception",
lib_evloop_abort_on_exc, 0);
rb_define_module_function(lib, "mainloop_abort_on_exception=",
lib_evloop_abort_on_exc_set, 1);
rb_define_module_function(lib, "set_eventloop_tick",set_eventloop_tick,1);
rb_define_module_function(lib, "get_eventloop_tick",get_eventloop_tick,0);
rb_define_module_function(lib, "set_no_event_wait", set_no_event_wait, 1);
@ -1205,10 +1420,8 @@ Init_tcltklib()
set_eventloop_weight, 2);
rb_define_module_function(lib, "get_eventloop_weight",
get_eventloop_weight, 0);
rb_define_module_function(lib, "mainloop_abort_on_exception",
rb_evloop_abort_on_exc, 0);
rb_define_module_function(lib, "mainloop_abort_on_exception=",
rb_evloop_abort_on_exc_set, 1);
rb_define_module_function(lib, "num_of_mainwindows",
lib_num_of_mainwindows, 0);
rb_define_alloc_func(ip, ip_alloc);
rb_define_method(ip, "initialize", ip_init, -1);
@ -1222,20 +1435,21 @@ Init_tcltklib()
rb_define_method(ip, "_fromUTF8",ip_fromUTF8,2);
rb_define_method(ip, "_invoke", ip_invoke, -1);
rb_define_method(ip, "_return_value", ip_retval, 0);
rb_define_method(ip, "mainloop", lib_mainloop, -1);
rb_define_method(ip, "mainloop_watchdog", lib_mainloop_watchdog, -1);
rb_define_method(ip, "do_one_event", lib_do_one_event, -1);
rb_define_method(ip, "mainloop", ip_mainloop, -1);
rb_define_method(ip, "mainloop_watchdog", ip_mainloop_watchdog, -1);
rb_define_method(ip, "do_one_event", ip_do_one_event, -1);
rb_define_method(ip, "mainloop_abort_on_exception",
rb_evloop_abort_on_exc, 0);
ip_evloop_abort_on_exc, 0);
rb_define_method(ip, "mainloop_abort_on_exception=",
rb_evloop_abort_on_exc_set, 1);
rb_define_method(ip, "set_eventloop_tick", set_eventloop_tick, 1);
rb_define_method(ip, "get_eventloop_tick", get_eventloop_tick, 0);
rb_define_method(ip, "set_no_event_wait", set_no_event_wait, 1);
rb_define_method(ip, "get_no_event_wait", get_no_event_wait, 0);
rb_define_method(ip, "set_eventloop_weight", set_eventloop_weight, 2);
rb_define_method(ip, "get_eventloop_weight", get_eventloop_weight, 0);
rb_define_method(ip, "restart", lib_restart, 0);
ip_evloop_abort_on_exc_set, 1);
rb_define_method(ip, "set_eventloop_tick", ip_set_eventloop_tick, 1);
rb_define_method(ip, "get_eventloop_tick", ip_get_eventloop_tick, 0);
rb_define_method(ip, "set_no_event_wait", ip_set_no_event_wait, 1);
rb_define_method(ip, "get_no_event_wait", ip_get_no_event_wait, 0);
rb_define_method(ip, "set_eventloop_weight", ip_set_eventloop_weight, 2);
rb_define_method(ip, "get_eventloop_weight", ip_get_eventloop_weight, 0);
rb_define_method(ip, "restart", ip_restart, 0);
eventloop_thread = 0;
watchdog_thread = 0;

View file

@ -6,10 +6,12 @@ require 'tcltklib'
require 'thread'
################################################
# ignore exception on the mainloop
# ignore exception on the mainloop?
TclTkLib.mainloop_abort_on_exception = true
# TclTkLib.mainloop_abort_on_exception = false
TclTkLib.mainloop_abort_on_exception = nil
# TclTkLib.mainloop_abort_on_exception = nil
################################################
@ -71,9 +73,16 @@ class MultiTkIp
end
private :_keys2opts
def _check_and_return(thread, exception, wait=3)
# wait to stop the caller thread
def _check_and_return(thread, exception, wait=0)
return nil unless thread
if wait == 0
# no wait
thread.raise exception
return thread
end
# wait to stop the caller thread
wait.times{
if thread.stop?
# ready to send exception
@ -104,22 +113,36 @@ class MultiTkIp
def _create_receiver_and_watchdog()
# command-procedures receiver
receiver = Thread.new{
safe_level = $SAFE
loop do
thread, cmd, *args = @cmd_queue.deq
if thread == @system
# control command
case cmd
when 'set_safe_level'
begin
$SAFE = args[0]
safe_level = args[0] if safe_level < args[0]
rescue Exception
nil
end
else
# ignore
end
else
# procedure
begin
ret = cmd.call(*args)
ret = proc{$SAFE = safe_level; cmd.call(*args)}.call
rescue SystemExit
# delete IP
unless @interp.deleted?
if @interp._invoke('info', 'command', '.') != ""
@interp._invoke('destroy', '.')
end
@interp.delete
end
_check_and_return(thread, MultiTkIp_OK.new(nil))
break
rescue Exception => e
# raise exception
_check_and_return(thread, e)
@ -134,7 +157,10 @@ class MultiTkIp
# watchdog of receiver
watchdog = Thread.new{
begin
receiver.join
loop do
sleep 1
break unless receiver.alive?
end
rescue Exception
# ignore all kind of Exception
end
@ -621,7 +647,9 @@ end
# instance methods to treat tables
class MultiTkIp
def _tk_cmd_tbl
MultiTkIp.tk_cmd_tbl.collect{|ent| ent.ip == self }
tbl = {}
MultiTkIp.tk_cmd_tbl.each{|id, ent| tbl[id] = ent if ent.ip == self }
tbl
end
def _tk_windows
@ -632,6 +660,10 @@ class MultiTkIp
@tk_table_list
end
def _add_new_tables
(@@TK_TABLE_LIST.size - @tk_table_list.size).times{ @tk_table_list << {} }
end
def _init_ip_env(script)
script.call(self)
end
@ -669,10 +701,10 @@ class MultiTkIp
__getip._tk_table_list[id]
end
def self.create_table
if __getip.slave?
raise SecurityError, "slave-IP has no permission creating a new table"
end
id = @@TK_TABLE_LIST.size
@@IP_TABLE.each{|tg, ip|
ip.instance_eval{@tk_table_list << {}}
}
obj = Object.new
@@TK_TABLE_LIST << obj
obj.instance_eval <<-EOD
@ -681,6 +713,7 @@ class MultiTkIp
end
EOD
obj.freeze
@@IP_TABLE.each{|tg, ip| ip._add_new_tables }
return obj
end
@ -719,33 +752,62 @@ end
# evaluate a procedure on the proper interpreter
class MultiTkIp
# instance method
def eval_proc_core(req_val=true, cmd = Proc.new, *args)
def eval_proc_core(req_val, cmd, *args)
# cmd string ==> proc
if cmd.kind_of?(String)
cmd = proc{ TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *args)) }
xcmd = cmd
xargs = args
cmd = proc{ TkComm._get_eval_string(TkUtil.eval_cmd(xcmd, *xargs)) }
args = []
end
# check
unless cmd.kind_of?(Proc)
raise RuntimeError, "A Proc object is expected for the 'cmd' argument"
end
# on IP thread
if (@cmd_receiver == Thread.current)
return cmd.call(*args)
begin
ret = cmd.call(*args)
rescue SystemExit
# exit IP
warn("Warning: "+ $! + " on " + self.inspect) if $DEBUG
self.delete
ret = nil
rescue Exception => e
warn("Warning: " + e.class.inspect +
((e.message.length > 0)? ' "' + e.message + '"': '') +
" on " + self.inspect)
ret = nil
end
return ret
end
# send cmd to the proc-queue
if req_val
@cmd_queue.enq([Thread.current, cmd, *args])
else
unless req_val
@cmd_queue.enq([nil, cmd, *args])
return nil
end
# wait and get return value by exception
# send and get return value by exception
begin
@cmd_queue.enq([Thread.current, cmd, *args])
Thread.stop
rescue MultiTkIp_OK => ret
# return value
return ret.value
rescue SystemExit
# exit IP
warn("Warning: " + $! + " on " + self.inspect) if $DEBUG
self.delete
rescue Exception => e
# others --> warning
warn("Warning: " + e.class.inspect +
((e.message.length > 0)? ' "' + e.message + '"': '') +
" on " + self.inspect)
end
return nil
end
private :eval_proc_core
@ -757,48 +819,57 @@ class MultiTkIp
eval_proc_core(true, cmd, *args)
end
alias call eval_proc
alias eval_string eval_proc
end
class << MultiTkIp
# class method
def self.eval_proc(cmd = Proc.new, *args)
def eval_proc(cmd = Proc.new, *args)
# class ==> interp object
__getip.eval_proc(cmd, *args)
end
alias call eval_proc
alias eval_string eval_proc
end
# depend on TclTkLib
# event loop
# all master/slave IPs are controled by only one event-loop
class << MultiTkIp
def mainloop(check_root = true)
TclTkLib.mainloop(check_root)
__getip.mainloop(check_root)
end
def mainloop_watchdog(check_root = true)
TclTkLib.mainloop_watchdog(check_root)
__getip.mainloop_watchdog(check_root)
end
def do_one_event(flag = TclTkLib::EventFlag::ALL)
TclTkLib.do_one_event(flag)
__getip.do_one_event(flag)
end
def mainloop_abort_on_exception
__getip.mainloop_abort_on_exception
end
def mainloop_abort_on_exception=(mode)
__getip.mainloop_abort_on_exception=(mode)
end
def set_eventloop_tick(tick)
TclTkLib.set_eventloop_tick(tick)
__getip.set_eventloop_tick(tick)
end
def get_eventloop_tick
TclTkLib.get_eventloop_tick
__getip.get_eventloop_tick
end
def set_no_event_wait(tick)
TclTkLib.set_no_event_wait(tick)
__getip.set_no_event_wait(tick)
end
def get_no_event_wait
TclTkLib.get_no_event_wait
__getip.get_no_event_wait
end
def set_eventloop_weight(loop_max, no_event_tick)
TclTkLib.set_eventloop_weight(loop_max, no_event_tick)
__getip.set_eventloop_weight(loop_max, no_event_tick)
end
def get_eventloop_weight
TclTkLib.get_eventloop_weight
__getip.get_eventloop_weight
end
end
# class methods to delegate to TclTkIp
class << MultiTkIp
def method_missing(id, *args)
@ -839,32 +910,76 @@ class << MultiTkIp
end
# wrap methods on TclTkLib : not permit calling TclTkLib module methods
class << TclTkLib
def mainloop(check_root = true)
MultiTkIp.mainloop(check_root)
end
def mainloop_watchdog(check_root = true)
MultiTkIp.mainloop_watchdog(check_root)
end
def do_one_event(flag = TclTkLib::EventFlag::ALL)
MultiTkIp.do_one_event(flag)
end
def mainloop_abort_on_exception
MultiTkIp.mainloop_abort_on_exception
end
def mainloop_abort_on_exception=(mode)
MultiTkIp.mainloop_abort_on_exception=(mode)
end
def set_eventloop_tick(tick)
MultiTkIp.set_eventloop_tick(tick)
end
def get_eventloop_tick
MultiTkIp.get_eventloop_tick
end
def set_no_event_wait(tick)
MultiTkIp.set_no_event_wait(tick)
end
def get_no_event_wait
MultiTkIp.get_no_event_wait
end
def set_eventloop_weight(loop_max, no_event_tick)
MultiTkIp.set_eventloop_weight(loop_max, no_event_tick)
end
def get_eventloop_weight
MultiTkIp.get_eventloop_weight
end
def restart
MultiTkIp.restart
end
end
# depend on TclTkIp
class MultiTkIp
def mainloop(check_root = true, restart_on_dead = true)
return self if self.slave?
unless restart_on_dead
@interp.mainloop(check_root)
else
begin
loop do
@interp.mainloop(check_root)
break unless self.alive?
if check_root
begin
break if @interp._invoke('winfo', 'exists?', '.') == "1"
break if TclTkLib.num_of_mainwindows == 0
rescue Exception
break
end
end
@interp.mainloop(check_root)
end
rescue StandardError
if TclTkLib.mainloop_abort_on_exception != nil
STDERR.print("warning: Tk mainloop on ", @interp.inspect,
STDERR.print("Warning: Tk mainloop on ", @interp.inspect,
" receives ", $!.class.inspect,
" exception (ignore) : ", $!.message, "\n");
end
retry
end
end
self
end
def make_safe
@ -1187,10 +1302,19 @@ class MultiTkIp
end
# remove methods for security
class MultiTkIp
undef_method :instance_eval
undef_method :instance_variable_get
undef_method :instance_variable_set
end
# end of MultiTkIp definition
MultiTkIp.freeze # defend against modification
# defend against modification
MultiTkIp.freeze
TclTkLib.freeze
########################################
# start Tk which depends on MultiTkIp

View file

@ -14,6 +14,7 @@ module TkComm
def None.to_s
'None'
end
None.freeze
#Tk_CMDTBL = {}
#Tk_WINDOWS = {}
@ -24,10 +25,16 @@ module TkComm
def Tk_CMDTBL.method_missing(id, *args)
TkCore::INTERP.tk_cmd_tbl.send(id, *args)
end
Tk_CMDTBL.freeze
Tk_WINDOWS = Object.new
def Tk_WINDOWS.method_missing(id, *args)
TkCore::INTERP.tk_windows.send(id, *args)
end
Tk_WINDOWS.freeze
self.instance_eval{
@cmdtbl = []
}
def error_at
frames = caller()
@ -894,30 +901,8 @@ module TkCore
tk_call('info', *args)
end
def mainloop(check_root = true, restart_on_dead = true)
unless restart_on_dead
TclTkLib.mainloop(check_root)
else
begin
loop do
TclTkLib.mainloop(check_root)
if check_root
begin
break if TkWinfo.exist?('.')
rescue Exception
break
end
end
end
rescue StandardError
if TclTkLib.mainloop_abort_on_exception != nil
STDERR.print("warning: Tk mainloop on ", TkCore::INTERP.inspect,
" receives ", $!.class.inspect,
" exception (ignore) : ", $!.message, "\n");
end
retry
end
end
def mainloop(check_root = true)
TclTkLib.mainloop(check_root)
end
def mainloop_watchdog(check_root = true)
@ -1020,15 +1005,15 @@ module TkCore
print "=> ", args.join(" ").inspect, "\n" if $DEBUG
begin
# res = INTERP._invoke(*args).taint
res = INTERP._invoke(*args) # _invoke returns a TAITED string
rescue NameError
err = $!
res = INTERP._invoke(*args) # _invoke returns a TAINTED string
rescue NameError => err
# err = $!
begin
args.unshift "unknown"
#res = INTERP._invoke(*args).taint
res = INTERP._invoke(*args) # _invoke returns a TAITED string
rescue
fail unless /^invalid command/ =~ $!
res = INTERP._invoke(*args) # _invoke returns a TAINTED string
rescue StandardError => err2
fail err2 unless /^invalid command/ =~ err2
fail err
end
end
@ -1136,7 +1121,7 @@ module Tk
TkRoot.new
end
def bell(nice = false)
def Tk.bell(nice = false)
if nice
tk_call 'bell', '-nice'
else
@ -1144,7 +1129,7 @@ module Tk
end
end
def bell_on_display(win, nice = false)
def Tk.bell_on_display(win, nice = false)
if nice
tk_call('bell', '-displayof', win, '-nice')
else
@ -1720,6 +1705,8 @@ class TkVariable
include Tk
extend TkCore
include Comparable
TkCommandNames = ['tkwait'.freeze].freeze
#TkVar_CB_TBL = {}
@ -1749,13 +1736,16 @@ class TkVariable
@trace_elem = nil
@trace_opts = nil
=begin
if val == []
INTERP._eval(format('global %s; set %s(0) 0; unset %s(0)',
@id, @id, @id))
# INTERP._eval(format('global %s; set %s(0) 0; unset %s(0)',
# @id, @id, @id))
elsif val.kind_of?(Array)
a = []
val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))}
s = '"' + a.join(" ").gsub(/[\[\]$"]/, '\\\\\&') + '"'
# val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))}
# s = '"' + a.join(" ").gsub(/[\[\]$"]/, '\\\\\&') + '"'
val.each_with_index{|e,i| a.push(i); a.push(e)}
s = '"' + array2tk_list(a).gsub(/[\[\]$"]/, '\\\\\&') + '"'
INTERP._eval(format('global %s; array set %s %s', @id, @id, s))
elsif val.kind_of?(Hash)
s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\
@ -1765,6 +1755,15 @@ class TkVariable
s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"'
INTERP._eval(format('global %s; set %s %s', @id, @id, s))
end
=end
if val.kind_of?(Hash)
s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\
.gsub(/[\[\]$"]/, '\\\\\&') + '"'
INTERP._eval(format('global %s; array set %s %s', @id, @id, s))
else
s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"'
INTERP._eval(format('global %s; set %s %s', @id, @id, s))
end
end
def wait
@ -1782,8 +1781,9 @@ class TkVariable
if INTERP._eval(format('global %s; array exists %s', @id, @id)) != "1"
fail
else
Hash[*tk_split_simplelist(INTERP._eval(format('global %s; array get %s',
@id, @id)))]
Hash[*tk_split_simplelist(INTERP.
_eval(format('global %s; array get %s',
@id, @id)))]
end
end
end
@ -1827,6 +1827,20 @@ class TkVariable
_get_eval_string(index), _get_eval_string(val)))
end
def numeric
number(value)
end
def numeric=(val)
case val
when Numeric
self.value=(val)
when TkVariable
self.value=(val.numeric)
else
raise ArgumentError, "Numeric is expected"
end
end
def to_i
number(value).to_i
end
@ -1843,10 +1857,104 @@ class TkVariable
value.intern
end
def list
tk_split_list(value)
end
alias to_a list
def list=(val)
case val
when Array
self.value=(val)
when TkVariable
self.value=(val.list)
else
raise ArgumentError, "Array is expected"
end
end
def inspect
format "#<TkVariable: %s>", @id
end
def coerce(other)
case other
when TkVariable
[other.value, self.value]
when String
[other, self.to_s]
when Symbol
[other, self.to_sym]
when Integer
[other, self.to_i]
when Float
[other, self.to_f]
when Array
[other, self.to_a]
else
[other, self.value]
end
end
def &(other)
if other.kind_of?(Array)
self.to_a & other.to_a
else
self.to_i & other.to_i
end
end
def |(other)
if other.kind_of?(Array)
self.to_a | other.to_a
else
self.to_i | other.to_i
end
end
def +(other)
case other
when Array
self.to_a + other
when String
self.value + other
else
begin
number(self.value) + other
rescue
self.value + other.to_s
end
end
end
def -(other)
if other.kind_of?(Array)
self.to_a - other
else
number(self.value) - other
end
end
def *(other)
begin
number(self.value) * other
rescue
self.value * other
end
end
def /(other)
number(self.value) / other
end
def %(other)
begin
number(self.value) % other
rescue
self.value % other
end
end
def **(other)
number(self.value) ** other
end
def =~(other)
self.value =~ other
end
def ==(other)
case other
when TkVariable
@ -1861,13 +1969,38 @@ class TkVariable
self.to_f == other
when Array
self.to_a == other
when Hash
self.value == other
else
false
end
end
def to_a
list(value)
def zero?
numeric.zero?
end
def nonzero?
!(numeric.zero?)
end
def <=>(other)
if other.kind_of?(TkVariable)
begin
val = other.numeric
other = val
rescue
other = other.value
end
end
if other.kind_of?(Numeric)
begin
return self.numeric <=> other
rescue
return self.value <=> other.to_s
end
else
return self.value <=> other
end
end
def to_eval
@ -3082,9 +3215,16 @@ TkOption = TkOptionDB
TkResourceDB = TkOptionDB
module TkTreatFont
def font_configinfo
def font_configinfo(name = nil)
ret = TkFont.used_on(self.path)
if ret == nil
=begin
if name
ret = name
else
ret = TkFont.init_widget_font(self.path, self.path, 'configure')
end
=end
ret = TkFont.init_widget_font(self.path, self.path, 'configure')
end
ret
@ -3097,7 +3237,10 @@ module TkTreatFont
if fnt.kind_of? TkFont
return fnt.call_font_configure(self.path, self.path,'configure',slot)
else
latinfont_configure(fnt) if fnt
if fnt
latinfont_configure(fnt)
kanjifont_configure(fnt)
end
end
end
if (ltn = slot.delete('latinfont'))
@ -3192,10 +3335,18 @@ module TkTreatItemFont
end
private :__conf_cmd, :__item_pathname
def tagfont_configinfo(tagOrId)
def tagfont_configinfo(tagOrId, name = nil)
pathname = __item_pathname(tagOrId)
ret = TkFont.used_on(pathname)
if ret == nil
=begin
if name
ret = name
else
ret = TkFont.init_widget_font(pathname, self.path,
__conf_cmd(0), __conf_cmd(1), tagOrId)
end
=end
ret = TkFont.init_widget_font(pathname, self.path,
__conf_cmd(0), __conf_cmd(1), tagOrId)
end
@ -3212,7 +3363,10 @@ module TkTreatItemFont
__conf_cmd(0), __conf_cmd(1),
tagOrId, slot)
else
latintagfont_configure(tagOrId, fnt) if fnt
if fnt
latintagfont_configure(tagOrId, fnt)
kanjitagfont_configure(tagOrId, fnt)
end
end
end
if (ltn = slot.delete('latinfont'))
@ -3358,6 +3512,12 @@ class TkObject<TkKernel
case slot.to_s
when 'text', 'label', 'show', 'data', 'file'
tk_call path, 'cget', "-#{slot}"
when 'font', 'kanjifont'
fnt = tk_tcl2ruby(tk_call(path, 'cget', "-#{slot}"))
unless fnt.kind_of?(TkFont)
fnt = fontobj(fnt)
end
fnt
else
tk_tcl2ruby tk_call(path, 'cget', "-#{slot}")
end
@ -3398,7 +3558,10 @@ class TkObject<TkKernel
def configinfo(slot = nil)
if slot == 'font' || slot == :font ||
slot == 'kanjifont' || slot == :kanjifont
fontobj
conf = tk_split_simplelist(tk_send('configure', "-#{slot}") )
conf[0] = conf[0][1..-1]
conf[4] = fontobj(conf[4])
conf
else
if slot
case slot.to_s
@ -3436,7 +3599,7 @@ class TkObject<TkKernel
fontconf = ret.assoc('font')
if fontconf
ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'}
fontconf[4] = fontobj
fontconf[4] = fontobj(fontconf[4])
ret.push(fontconf)
else
ret
@ -4367,6 +4530,7 @@ class TkPanedWindow<TkWindow
end
self
end
alias pane_config paneconfigure
def paneconfiginfo(win, key=nil)
if key
@ -4395,6 +4559,7 @@ class TkPanedWindow<TkWindow
}
end
end
alias pane_configinfo paneconfiginfo
def panes
list(tk_send('panes'))
@ -4717,6 +4882,12 @@ class TkListbox<TkTextWin
case key.to_s
when 'text', 'label', 'show'
tk_send('itemcget', index, "-#{key}")
when 'font', 'kanjifont'
fnt = tk_tcl2ruby(tk_send('itemcget', index, "-#{key}"))
unless fnt.kind_of?(TkFont)
fnt = tagfontobj(index, fnt)
end
fnt
else
tk_tcl2ruby(tk_send('itemcget', index, "-#{key}"))
end
@ -4750,13 +4921,17 @@ class TkListbox<TkTextWin
case key.to_s
when 'text', 'label', 'show'
conf = tk_split_simplelist(tk_send('itemconfigure',index,"-#{key}"))
when 'font', 'kanjifont'
conf = tk_split_simplelist(tk_send('itemconfigure',index,"-#{key}") )
conf[4] = tagfont_configinfo(index, conf[4])
else
conf = tk_split_list(tk_send('itemconfigure',index,"-#{key}"))
end
conf[0] = conf[0][1..-1]
conf
else
tk_split_simplelist(tk_send('itemconfigure', index)).collect{|conflist|
ret = tk_split_simplelist(tk_send('itemconfigure',
index)).collect{|conflist|
conf = tk_split_simplelist(conflist)
conf[0] = conf[0][1..-1]
case conf[0]
@ -4779,6 +4954,14 @@ class TkListbox<TkTextWin
end
conf
}
fontconf = ret.assoc('font')
if fontconf
ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'}
fontconf[4] = tagfont_configinfo(index, fontconf[4])
ret.push(fontconf)
else
ret
end
end
end
end
@ -4881,8 +5064,14 @@ class TkMenu<TkWindow
case key.to_s
when 'text', 'label', 'show'
tk_send 'entrycget', index, "-#{key}"
when 'font', 'kanjifont'
fnt = tk_tcl2ruby(tk_send('entrycget', index, "-#{key}"))
unless fnt.kind_of?(TkFont)
fnt = tagfontobj(index, fnt)
end
fnt
else
tk_tcl2ruby tk_send('entrycget', index, "-#{key}")
tk_tcl2ruby(tk_send('entrycget', index, "-#{key}"))
end
end
def entryconfigure(index, key, val=None)
@ -4914,13 +5103,17 @@ class TkMenu<TkWindow
case key.to_s
when 'text', 'label', 'show'
conf = tk_split_simplelist(tk_send('entryconfigure',index,"-#{key}"))
when 'font', 'kanjifont'
conf = tk_split_simplelist(tk_send('entryconfigure',index,"-#{key}"))
conf[4] = tagfont_configinfo(index, conf[4])
else
conf = tk_split_list(tk_send('entryconfigure',index,"-#{key}"))
end
conf[0] = conf[0][1..-1]
conf
else
tk_split_simplelist(tk_send('entryconfigure', index)).collect{|conflist|
ret = tk_split_simplelist(tk_send('entryconfigure',
index)).collect{|conflist|
conf = tk_split_simplelist(conflist)
conf[0] = conf[0][1..-1]
case conf[0]
@ -4943,6 +5136,13 @@ class TkMenu<TkWindow
end
conf
}
if fontconf
ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'}
fontconf[4] = tagfont_configinfo(index, fontconf[4])
ret.push(fontconf)
else
ret
end
end
end
end
@ -5246,6 +5446,16 @@ TkBindTag::ALL.bind(TkVirtualEvent.new('Destroy'), proc{|xpath|
end
}, 'x%W')
# freeze core modules
TclTkLib.freeze
TclTkIp.freeze
TkUtil.freeze
TkKernel.freeze
TkComm.freeze
TkComm::Event.freeze
TkCore.freeze
Tk.freeze
# autoload
autoload :TkCanvas, 'tkcanvas'
autoload :TkImage, 'tkcanvas'

View file

@ -211,6 +211,12 @@ class TkCanvas<TkWindow
end
when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'
tk_send 'itemcget', tagid(tagOrId), "-#{option}"
when 'font', 'kanjifont'
fnt = tk_tcl2ruby(tk_send('itemcget', tagid(tagOrId), "-#{option}"))
unless fnt.kind_of?(TkFont)
fnt = tagfontobj(tagid(tagOrId), fnt)
end
fnt
else
tk_tcl2ruby tk_send('itemcget', tagid(tagOrId), "-#{option}")
end
@ -264,6 +270,10 @@ class TkCanvas<TkWindow
when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'
conf = tk_split_simplelist(tk_send('itemconfigure',
tagid(tagOrId), "-#{key}"))
when 'font', 'kanjifont'
conf = tk_split_simplelist(tk_send('itemconfigure',
tagid(tagOrId),"-#{key}") )
conf[4] = tagfont_configinfo(tagid(tagOrId), conf[4])
else
conf = tk_split_list(tk_send('itemconfigure',
tagid(tagOrId), "-#{key}"))
@ -271,8 +281,8 @@ class TkCanvas<TkWindow
conf[0] = conf[0][1..-1]
conf
else
tk_split_simplelist(tk_send('itemconfigure',
tagid(tagOrId))).collect{|conflist|
ret = tk_split_simplelist(tk_send('itemconfigure',
tagid(tagOrId))).collect{|conflist|
conf = tk_split_simplelist(conflist)
conf[0] = conf[0][1..-1]
case conf[0]
@ -302,6 +312,14 @@ class TkCanvas<TkWindow
end
conf
}
fontconf = ret.assoc('font')
if fontconf
ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'}
fontconf[4] = tagfont_configinfo(tagid(tagOrId), fontconf[4])
ret.push(fontconf)
else
ret
end
end
end

View file

@ -34,19 +34,21 @@ class TkFont
# Tcl/Tk-JP for Windows
ltn = 'defaultgui'
knj = 'defaultgui'
when /Mincho:Helvetica-12/
when /Mincho:Helvetica-Bold-12/
# Tcl/Tk-JP for UNIX/X
ltn, knj = tk_split_simplelist(tk_call('font', 'configure',
'Mincho:Helvetica-12',
'Mincho:Helvetica-Bold-12',
'-compound'))
else
# unknown Tcl/Tk-JP
platform = tk_call('set', 'tcl_platform(platform)')
case platform
when 'unix'
ltn = {'family'=>'Helvetica'.freeze, 'size'=>-12}
knj = 'k14'
ltn = {'family'=>'Helvetica'.freeze,
'size'=>-12, 'weight'=>'bold'.freeze}
#knj = 'k14'
#knj = '-misc-fixed-medium-r-normal--14-*-*-*-c-*-jisx0208.1983-0'
knj = '-*-fixed-bold-r-normal--12-*-*-*-c-*-jisx0208.1983-0'
when 'windows'
ltn = {'family'=>'MS Sans Serif'.freeze, 'size'=>8}
knj = 'mincho'
@ -68,9 +70,11 @@ class TkFont
platform = tk_call('set', 'tcl_platform(platform)')
case platform
when 'unix'
ltn = {'family'=>'Helvetica'.freeze, 'size'=>-12}
knj = 'k14'
ltn = {'family'=>'Helvetica'.freeze,
'size'=>-12, 'weight'=>'bold'.freeze}
#knj = 'k14'
#knj = '-misc-fixed-medium-r-normal--14-*-*-*-c-*-jisx0208.1983-0'
knj = '-*-fixed-bold-r-normal--12-*-*-*-c-*-jisx0208.1983-0'
when 'windows'
ltn = {'family'=>'MS Sans Serif'.freeze, 'size'=>8}
knj = 'mincho'
@ -133,7 +137,7 @@ class TkFont
end
def TkFont.create_copy(font)
fail 'source-font need to be TkFont' unless font.kind_of? TkFont
fail 'source-font must be a TkFont object' unless font.kind_of? TkFont
keys = {}
font.configinfo.each{|key,value| keys[key] = value }
TkFont.new(font.latin_font, font.kanji_font, keys)
@ -220,11 +224,46 @@ class TkFont
###################################
private
###################################
def initialize(ltn=DEFAULT_LATIN_FONT_NAME, knj=nil, keys=nil)
def initialize(ltn=nil, knj=nil, keys=nil)
@id = Tk_FontID.join
Tk_FontID[1].succ!
Tk_FontNameTBL[@id] = self
knj = DEFAULT_KANJI_FONT_NAME if JAPANIZED_TK && !knj
if knj.kind_of?(Hash) && !keys
keys = knj
knj = nil
end
# compound font check
if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK
begin
compound = tk_split_simplelist(tk_call('font', 'configure',
ltn, '-compound'))
if knj == nil
if compound != []
ltn, knj = compound
end
else
if compound != []
ltn = compound[0]
end
compound = tk_split_simplelist(tk_call('font', 'configure',
knj, '-compound'))
if compound != []
knj = compound[1]
end
end
rescue
end
end
if ltn
knj = ltn if JAPANIZED_TK && !knj
else
ltn = DEFAULT_LATIN_FONT_NAME
knj = DEFAULT_KANJI_FONT_NAME if JAPANIZED_TK && !knj
end
create_compoundfont(ltn, knj, keys)
end
@ -457,8 +496,48 @@ class TkFont
@compoundfont = @id + 'c'
if JAPANIZED_TK
@fontslot = {'font'=>@compoundfont}
tk_call('font', 'create', @compoundfont,
'-compound', [@latinfont, @kanjifont], *hash_kv(keys))
begin
tk_call('font', 'create', @compoundfont,
'-compound', [@latinfont, @kanjifont], *hash_kv(keys))
rescue RuntimeError => e
if ltn == knj
if e.message =~ /kanji font .* specified/
tk_call('font', 'delete', @latinfont)
create_latinfont(DEFAULT_LATIN_FONT_NAME)
opts = []
Hash[*(tk_split_simplelist(tk_call('font', 'configure',
@kanjifont)))].each{|k,v|
case k
when '-size', '-weight', '-slant', '-underline', '-overstrike'
opts << k << v
end
}
tk_call('font', 'configure', @latinfont, *opts)
tk_call('font', 'create', @compoundfont,
'-compound', [@latinfont, @kanjifont], *hash_kv(keys))
elsif e.message =~ /ascii font .* specified/
tk_call('font', 'delete', @kanjifont)
create_kanjifont(DEFAULT_KANJI_FONT_NAME)
opts = []
Hash[*(tk_split_simplelist(tk_call('font', 'configure',
@latinfont)))].each{|k,v|
case k
when '-size', '-weight', '-slant', '-underline', '-overstrike'
opts << k << v
end
}
tk_call('font', 'configure', @kanjifont, *opts)
tk_call('font', 'create', @compoundfont,
'-compound', [@latinfont, @kanjifont], *hash_kv(keys))
else
raise e
end
else
raise e
end
end
else
tk_call('font', 'create', @compoundfont)
@ -529,7 +608,8 @@ class TkFont
end
def configure_core_tk4x(font, slot, value=None)
""
#""
self
end
def configinfo_core_tk4x(font, option=nil)
@ -544,11 +624,70 @@ class TkFont
end
def configure_core_tk8x(font, slot, value=None)
if slot.kind_of? Hash
tk_call 'font', 'configure', font, *hash_kv(slot)
if JAPANIZED_TK
begin
padjust = tk_call('font', 'configure', font, '-pointadjust')
rescue
padjust = nil
end
else
tk_call 'font', 'configure', font, "-#{slot}", value
padjust = nil
end
if slot.kind_of? Hash
if JAPANIZED_TK && (slot.key?('family') || slot.key?(:family))
slot = _symbolkey2str(slot)
configure_core_tk8x(font, 'family', slot.delete('family'))
end
if ((slot.key?('size') || slot.key?(:size)) &&
padjust && !slot.key?('pointadjust') && !slot.key?(:pointadjust))
tk_call('font', 'configure', font,
'-pointadjust', padjust, *hash_kv(slot))
else
tk_call('font', 'configure', font, *hash_kv(slot))
end
elsif (slot == 'size' || slot == :size) && padjust != nil
tk_call('font', 'configure', font,
"-#{slot}", value, '-pointadjust', padjust)
elsif JAPANIZED_TK && (slot == 'family' || slot == :family)
# coumpund font?
begin
compound = tk_split_simplelist(tk_call('font', 'configure',
font, '-compound'))
rescue
tk_call('font', 'configure', font, '-family', value)
return self
end
if compound == []
tk_call('font', 'configure', font, '-family', value)
return self
end
ltn, knj = compound
lfnt = tk_call('font', 'create', '-copy', ltn)
begin
tk_call('font', 'configure', lfnt, '-family', value)
latin_replace_core_tk8x(lfnt)
rescue RuntimeError => e
fail e if $DEBUG
ensure
tk_call('font', 'delete', lfnt) if lfnt != ''
end
kfnt = tk_call('font', 'create', '-copy', knj)
begin
tk_call('font', 'configure', kfnt, '-family', value)
kanji_replace_core_tk8x(lfnt)
rescue RuntimeError => e
fail e if $DEBUG
ensure
tk_call('font', 'delete', kfnt) if kfnt != ''
end
else
tk_call('font', 'configure', font, "-#{slot}", value)
end
self
end
def configinfo_core_tk8x(font, option=nil)
@ -659,20 +798,90 @@ class TkFont
end
def latin_replace_core_tk8x(ltn)
if JAPANIZED_TK
begin
tk_call('font', 'delete', '@font_tmp')
rescue
end
begin
fnt_bup = tk_call('font', 'create', '@font_tmp', '-copy', @latinfont)
rescue
fnt_bup = ''
end
end
begin
tk_call('font', 'delete', @latinfont)
rescue
end
create_latinfont(ltn)
if JAPANIZED_TK
keys = self.configinfo
tk_call('font', 'delete', @compoundfont)
begin
tk_call('font', 'create', @compoundfont,
'-compound', [@latinfont, @kanjifont], *hash_kv(keys))
rescue RuntimeError => e
tk_call('font', 'delete', @latinfont)
if fnt_bup != ''
tk_call('font', 'create', @latinfont, '-copy', fnt_bup)
tk_call('font', 'create', @compoundfont,
'-compound', [@latinfont, @kanjifont], *hash_kv(keys))
tk_call('font', 'delete', fnt_bup)
end
fail e
end
else
latinkeys = {}
begin
actual_core(@latinfont).each{|key,val| latinkeys[key] = val}
rescue
latinkeys {}
end
if latinkeys != {}
tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys))
end
end
self
end
def kanji_replace_core_tk8x(knj)
if JAPANIZED_TK
begin
tk_call('font', 'delete', '@font_tmp')
rescue
end
begin
fnt_bup = tk_call('font', 'create', '@font_tmp', '-copy', @kanjifont)
rescue
fnt_bup = ''
end
end
begin
tk_call('font', 'delete', @kanjifont)
rescue
end
create_kanjifont(knj)
if JAPANIZED_TK
keys = self.configinfo
tk_call('font', 'delete', @compoundfont)
begin
tk_call('font', 'create', @compoundfont,
'-compound', [@latinfont, @kanjifont], *hash_kv(keys))
rescue RuntimeError => e
tk_call('font', 'delete', @kanjifont)
if fnt_bup != ''
tk_call('font', 'create', @kanjifont, '-copy', fnt_bup)
tk_call('font', 'create', @compoundfont,
'-compound', [@latinfont, @kanjifont], *hash_kv(keys))
tk_call('font', 'delete', fnt_bup)
end
fail e
end
end
self
end
@ -737,7 +946,7 @@ class TkFont
alias measure_core measure_core_tk4x
alias metrics_core metrics_core_tk4x
when /^8\.[0123]/
when /^8\.[0-4]/
alias create_latinfont create_latinfont_tk8x
alias create_kanjifont create_kanjifont_tk8x
alias create_compoundfont create_compoundfont_tk8x

View file

@ -330,6 +330,12 @@ class TkText<TkTextWin
case key.to_s
when 'text', 'label', 'show', 'data', 'file'
tk_call(@path, 'tag', 'cget', tag, "-#{key}")
when 'font', 'kanjifont'
fnt = tk_tcl2ruby(tk_send('tag', 'cget', tag, "-#{key}"))
unless fnt.kind_of?(TkFont)
fnt = tagfontobj(tag, fnt)
end
fnt
else
tk_tcl2ruby(tk_call(@path, 'tag', 'cget', tag, "-#{key}"))
end
@ -363,13 +369,17 @@ class TkText<TkTextWin
case key.to_s
when 'text', 'label', 'show', 'data', 'file'
conf = tk_split_simplelist(tk_send('tag','configure',tag,"-#{key}"))
when 'font', 'kanjifont'
conf = tk_split_simplelist(tk_send('tag','configure',tag,"-#{key}") )
conf[4] = tagfont_configinfo(tag, conf[4])
else
conf = tk_split_list(tk_send('tag','configure',tag,"-#{key}"))
end
conf[0] = conf[0][1..-1]
conf
else
tk_split_simplelist(tk_send('tag', 'configure', tag)).collect{|conflist|
ret = tk_split_simplelist(tk_send('tag', 'configure',
tag)).collect{|conflist|
conf = tk_split_simplelist(conflist)
conf[0] = conf[0][1..-1]
case conf[0]
@ -392,6 +402,14 @@ class TkText<TkTextWin
end
conf
}
fontconf = ret.assoc('font')
if fontconf
ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'}
fontconf[4] = tagfont_configinfo(tag, fontconf[4])
ret.push(fontconf)
else
ret
end
end
end
@ -431,6 +449,12 @@ class TkText<TkTextWin
case slot.to_s
when 'text', 'label', 'show', 'data', 'file'
tk_send('window', 'cget', index, "-#{slot}")
when 'font', 'kanjifont'
fnt = tk_tcl2ruby(tk_send('window', 'cget', index, "-#{slot}"))
unless fnt.kind_of?(TkFont)
fnt = tagfontobj(index, fnt)
end
fnt
else
tk_tcl2ruby(tk_send('window', 'cget', index, "-#{slot}"))
end
@ -853,8 +877,14 @@ class TkTextTag<TkObject
case key.to_s
when 'text', 'label', 'show', 'data', 'file'
tk_call @t.path, 'tag', 'cget', @id, "-#{key}"
when 'font', 'kanjifont'
fnt = tk_tcl2ruby(tk_call(@t.path, 'tag', 'cget', @id, "-#{key}"))
unless fnt.kind_of?(TkFont)
fnt = tagfontobj(@id, fnt)
end
fnt
else
tk_tcl2ruby tk_call(@t.path, 'tag', 'cget', @id, "-#{key}")
tk_tcl2ruby(tk_call(@t.path, 'tag', 'cget', @id, "-#{key}"))
end
end

188
process.c
View file

@ -1180,11 +1180,18 @@ proc_setpriority(obj, which, who, prio)
#endif
}
static int under_uid_switch = 0;
static int under_gid_switch = 0;
static VALUE
p_sys_setuid(obj, id)
VALUE obj, id;
{
#if defined HAVE_SETUID
rb_secure(2);
if (under_uid_switch) {
rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
}
if (setuid(NUM2INT(id)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@ -1197,6 +1204,10 @@ p_sys_setruid(obj, id)
VALUE obj, id;
{
#if defined HAVE_SETRUID
rb_secure(2);
if (under_uid_switch) {
rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
}
if (setruid(NUM2INT(id)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@ -1209,6 +1220,10 @@ p_sys_seteuid(obj, id)
VALUE obj, id;
{
#if defined HAVE_SETEUID
rb_secure(2);
if (under_uid_switch) {
rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
}
if (seteuid(NUM2INT(id)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@ -1221,6 +1236,10 @@ p_sys_setreuid(obj, rid, eid)
VALUE obj, rid, eid;
{
#if defined HAVE_SETREUID
rb_secure(2);
if (under_uid_switch) {
rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
}
if (setreuid(NUM2INT(rid),NUM2INT(eid)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@ -1233,6 +1252,10 @@ p_sys_setresuid(obj, rid, eid, sid)
VALUE obj, rid, eid, sid;
{
#if defined HAVE_SETRESUID
rb_secure(2);
if (under_uid_switch) {
rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
}
if (setresuid(NUM2INT(rid),NUM2INT(eid),NUM2INT(sid)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@ -1254,6 +1277,10 @@ proc_setuid(obj, id)
{
int uid = NUM2INT(id);
rb_secure(2);
if (under_uid_switch) {
rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
}
#if defined(HAVE_SETRESUID) && !defined(__CHECKER__)
if (setresuid(uid, -1, -1) < 0) rb_sys_fail(0);
#elif defined HAVE_SETREUID
@ -1284,6 +1311,11 @@ p_uid_change_privilege(obj, id)
extern int errno;
int uid;
rb_secure(2);
if (under_uid_switch) {
rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
}
uid = NUM2INT(id);
if (geteuid() == 0) { /* root-user */
@ -1420,6 +1452,10 @@ p_sys_setgid(obj, id)
VALUE obj, id;
{
#if defined HAVE_SETGID
rb_secure(2);
if (under_gid_switch) {
rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
}
if (setgid(NUM2INT(id)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@ -1432,6 +1468,10 @@ p_sys_setrgid(obj, id)
VALUE obj, id;
{
#if defined HAVE_SETRGID
rb_secure(2);
if (under_gid_switch) {
rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
}
if (setrgid(NUM2INT(id)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@ -1444,6 +1484,10 @@ p_sys_setegid(obj, id)
VALUE obj, id;
{
#if defined HAVE_SETEGID
rb_secure(2);
if (under_gid_switch) {
rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
}
if (setegid(NUM2INT(id)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@ -1456,6 +1500,10 @@ p_sys_setregid(obj, rid, eid)
VALUE obj, rid, eid;
{
#if defined HAVE_SETREGID
rb_secure(2);
if (under_gid_switch) {
rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
}
if (setregid(NUM2INT(rid),NUM2INT(eid)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@ -1468,6 +1516,10 @@ p_sys_setresgid(obj, rid, eid, sid)
VALUE obj, rid, eid, sid;
{
#if defined HAVE_SETRESGID
rb_secure(2);
if (under_gid_switch) {
rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
}
if (setresgid(NUM2INT(rid),NUM2INT(eid),NUM2INT(sid)) != 0) rb_sys_fail(0);
#else
rb_notimplement();
@ -1505,6 +1557,10 @@ proc_setgid(obj, id)
{
int gid = NUM2INT(id);
rb_secure(2);
if (under_gid_switch) {
rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
}
#if defined(HAVE_SETRESGID) && !defined(__CHECKER__)
if (setresgid(gid, -1, -1) < 0) rb_sys_fail(0);
#elif defined HAVE_SETREGID
@ -1650,6 +1706,11 @@ p_gid_change_privilege(obj, id)
extern int errno;
int gid;
rb_secure(2);
if (under_gid_switch) {
rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
}
gid = NUM2INT(id);
if (geteuid() == 0) { /* root-user */
@ -1794,6 +1855,10 @@ static VALUE
proc_seteuid(obj, euid)
VALUE obj, euid;
{
rb_secure(2);
if (under_uid_switch) {
rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
}
#if defined(HAVE_SETRESUID) && !defined(__CHECKER__)
if (setresuid(-1, NUM2INT(euid), -1) < 0) rb_sys_fail(0);
#elif defined HAVE_SETREUID
@ -1820,6 +1885,11 @@ rb_seteuid_core(euid)
{
int uid;
rb_secure(2);
if (under_uid_switch) {
rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
}
uid = getuid();
#if defined(HAVE_SETRESUID) && !defined(__CHECKER__)
@ -1868,6 +1938,9 @@ proc_setegid(obj, egid)
VALUE obj, egid;
{
rb_secure(2);
if (under_gid_switch) {
rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
}
#if defined(HAVE_SETRESGID) && !defined(__CHECKER__)
if (setresgid(-1, NUM2INT(egid), -1) < 0) rb_sys_fail(0);
#elif defined HAVE_SETREGID
@ -1894,6 +1967,11 @@ rb_setegid_core(egid)
{
int gid;
rb_secure(2);
if (under_gid_switch) {
rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
}
gid = getgid();
#if defined(HAVE_SETRESGID) && !defined(__CHECKER__)
@ -1946,6 +2024,11 @@ p_uid_exchange(obj)
{
int uid, euid;
rb_secure(2);
if (under_uid_switch) {
rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
}
uid = getuid();
euid = geteuid();
@ -1979,6 +2062,11 @@ p_gid_exchange(obj)
{
int gid, egid;
rb_secure(2);
if (under_gid_switch) {
rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
}
gid = getgid();
egid = getegid();
@ -2004,6 +2092,16 @@ p_uid_have_saved_id()
#endif
}
#if defined(HAVE_SETRESUID) || defined(HAVE_SETEUID) || defined(_POSIX_SAVED_IDS)
static VALUE
p_uid_sw_ensure(id)
int id;
{
under_uid_switch = 0;
return rb_seteuid_core(id);
}
static VALUE
p_uid_switch(obj)
VALUE obj;
@ -2011,21 +2109,27 @@ p_uid_switch(obj)
extern int errno;
int uid, euid;
rb_secure(2);
if (under_uid_switch) {
rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
}
uid = getuid();
euid = geteuid();
#if defined(HAVE_SETRESUID) || defined(HAVE_SETEUID) || defined(_POSIX_SAVED_IDS)
if (uid != euid) {
proc_seteuid(obj, INT2FIX(uid));
if (rb_block_given_p()) {
return rb_ensure(rb_yield, Qnil, rb_seteuid_core, SAVED_USER_ID);
under_uid_switch = 1;
return rb_ensure(rb_yield, Qnil, p_uid_sw_ensure, SAVED_USER_ID);
} else {
return INT2FIX(euid);
}
} else if (euid != SAVED_USER_ID) {
proc_seteuid(obj, INT2FIX(SAVED_USER_ID));
if (rb_block_given_p()) {
return rb_ensure(rb_yield, Qnil, rb_seteuid_core, euid);
under_uid_switch = 1;
return rb_ensure(rb_yield, Qnil, p_uid_sw_ensure, euid);
} else {
return INT2FIX(uid);
}
@ -2033,14 +2137,39 @@ p_uid_switch(obj)
errno = EPERM;
rb_sys_fail(0);
}
#else
static VALUE
p_uid_sw_ensure(obj)
VALUE obj;
{
under_uid_switch = 0;
return p_uid_exchange(obj);
}
static VALUE
p_uid_switch(obj)
VALUE obj;
{
extern int errno;
int uid, euid;
rb_secure(2);
if (under_uid_switch) {
rb_raise(rb_eRuntimeError, "can't handle UID during evaluating the block given to the Process::UID.switch method");
}
uid = getuid();
euid = geteuid();
if (uid == euid) {
errno = EPERM;
rb_sys_fail(0);
}
p_uid_switch(obj);
p_uid_exchange(obj);
if (rb_block_given_p()) {
return rb_ensure(rb_yield, Qnil, p_uid_switch, obj);
under_uid_switch = 1;
return rb_ensure(rb_yield, Qnil, p_uid_sw_ensure, obj);
} else {
return INT2FIX(euid);
}
@ -2057,6 +2186,15 @@ p_gid_have_saved_id()
#endif
}
#if defined(HAVE_SETRESGID) || defined(HAVE_SETEGID) || defined(_POSIX_SAVED_IDS)
static VALUE
p_gid_sw_ensure(id)
int id;
{
under_gid_switch = 0;
rb_setegid_core(id);
}
static VALUE
p_gid_switch(obj)
VALUE obj;
@ -2064,22 +2202,27 @@ p_gid_switch(obj)
extern int errno;
int gid, egid;
rb_secure(2);
if (under_gid_switch) {
rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
}
gid = getgid();
egid = getegid();
#if defined(HAVE_SETRESGID) || defined(HAVE_SETEGID) || defined(_POSIX_SAVED_IDS)
if (gid != egid) {
proc_setegid(obj, INT2FIX(gid));
if (rb_block_given_p()) {
return rb_ensure(rb_yield, Qnil, proc_setegid,
INT2FIX(SAVED_GROUP_ID));
under_gid_switch = 1;
return rb_ensure(rb_yield, Qnil, p_gid_sw_ensure, SAVED_GROUP_ID);
} else {
return INT2FIX(egid);
}
} else if (egid != SAVED_GROUP_ID) {
proc_setegid(obj, INT2FIX(SAVED_GROUP_ID));
if (rb_block_given_p()) {
return rb_ensure(rb_yield, Qnil, proc_setegid, INT2FIX(egid));
under_gid_switch = 1;
return rb_ensure(rb_yield, Qnil, p_gid_sw_ensure, egid);
} else {
return INT2FIX(gid);
}
@ -2088,13 +2231,36 @@ p_gid_switch(obj)
rb_sys_fail(0);
}
#else
p_gid_sw_ensure(obj)
VALUE obj;
{
under_gid_switch = 0;
p_gid_exchange(obj);
}
static VALUE
p_gid_switch(obj)
VALUE obj;
{
extern int errno;
int gid, egid;
rb_secure(2);
if (under_gid_switch) {
rb_raise(rb_eRuntimeError, "can't handle GID during evaluating the block given to the Process::GID.switch method");
}
gid = getgid();
egid = getegid();
if (gid == egid) {
errno = EPERM;
rb_sys_fail(0);
}
p_gid_switch(obj);
p_gid_exchange(obj);
if (rb_block_given_p()) {
return rb_ensure(rb_yield, Qnil, p_gid_switch, obj);
under_gid_switch = 1;
return rb_ensure(rb_yield, Qnil, p_gid_sw_ensure, obj);
} else {
return INT2FIX(egid);
}