diff options
author | Jeremy Evans <code@jeremyevans.net> | 2021-03-02 12:17:23 -0800 |
---|---|---|
committer | git <svn-admin@ruby-lang.org> | 2021-03-06 00:18:32 +0900 |
commit | 14e1739ff3ec81c9ea87a8aba03393f0bf0433a7 (patch) | |
tree | b06b0ca59362886a320ecb79f13ad37b85b3febb /lib/irb/ext/save-history.rb | |
parent | 182cde8dfbbc6b9044d9b76c0bfdcf031bcda778 (diff) | |
download | ruby-14e1739ff3ec81c9ea87a8aba03393f0bf0433a7.tar.gz |
[ruby/irb] Make save-history extension safe for concurrent use
This makes the save-history extension check for modifications to
the history file before saving it. If the history file was modified
after the history was loaded and before it was saved, append only
the new history lines to the history file.
This can result in more lines in the history file than SAVE_HISTORY
allows. However, that will be fixed the next time irb is run and
the history is saved.
Fixes [Bug #13654]
https://github.com/ruby/irb/commit/041ef53845
Diffstat (limited to 'lib/irb/ext/save-history.rb')
-rw-r--r-- | lib/irb/ext/save-history.rb | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/lib/irb/ext/save-history.rb b/lib/irb/ext/save-history.rb index ac358c8ccb..7acaebe36a 100644 --- a/lib/irb/ext/save-history.rb +++ b/lib/irb/ext/save-history.rb @@ -81,6 +81,8 @@ module IRB end } end + @loaded_history_lines = history.size + @loaded_history_mtime = File.mtime(history_file) end end @@ -105,12 +107,20 @@ module IRB raise end - open(history_file, "w:#{IRB.conf[:LC_MESSAGES].encoding}", 0600) do |f| + if File.exist?(history_file) && @loaded_history_mtime && + File.mtime(history_file) != @loaded_history_mtime + history = history[@loaded_history_lines..-1] + append_history = true + end + + open(history_file, "#{append_history ? 'a' : 'w'}:#{IRB.conf[:LC_MESSAGES].encoding}", 0600) do |f| hist = history.map{ |l| l.split("\n").join("\\\n") } - begin - hist = hist.last(num) if hist.size > num and num > 0 - rescue RangeError # bignum too big to convert into `long' - # Do nothing because the bignum should be treated as inifinity + unless append_history + begin + hist = hist.last(num) if hist.size > num and num > 0 + rescue RangeError # bignum too big to convert into `long' + # Do nothing because the bignum should be treated as inifinity + end end f.puts(hist) end |