From: Joel VanderWerf Date: 2004-03-11T15:18:42+09:00 Subject: Re: patch to tempfile.rb to handle ENAMETOOLONG Yukihiro Matsumoto wrote: > Hi, > > In message "patch to tempfile.rb to handle ENAMETOOLONG" > on 04/03/11, Joel VanderWerf writes: > > |Can anyone think of a better way to handle ENAMETOOLONG on systems that > |have limited filename lengths? > | > |On QNX, filenames are limited to 48 bytes. > > Handling ENAMETOOLONG sounds nice, but is it OK to chop off path name, > or should we just raise exception? Is the name of a tempfile significant, as long as it is unique? It looks like tempfile.rb makes an effort (10 tries) to find a unique name. Each try, it increments a counter at the end of the name: tmpname = sprintf('%s/%s%d.%d', tmpdir, basename, $$, n) lock = tmpname + '.lock' n += 1 The basename seems like the least important part of tmpname, which I why I chose to chop that part. But OTOH silently changing the user's input is not very nice. Also, I don't like the idea of chopping one char and retrying, until the string is short enough. Actually, all I care about is that irb works. So maybe irb should catch the ENAMETOOLONG exception and retry with a different filename. The problem remains: how to shorten the filename? In irb, the exception happens in locale.rb: def real_load(path, priv) tmp_base = path.tr("./:", "___") lc_file = Tempfile.new(tmp_base) So you can see how the name can be very long. (Is such a long name really necessary?) What about this: def real_load(path, priv) tmp_base = path.tr("./:", "___") begin lc_file = Tempfile.new(tmp_base) rescue Errno::ENAMETOOLONG tmp_base = File.basename(path).tr("./:", "___") retry end The retry should work, since File.basename(path) is known to be a legal filename. The disadvantage here is that the problem is fixed only in irb, and not in Tempfile itself. However, all other uses of Tempfile in the standard library use short literal filenames. The second approach seems to make sense. What do you think?