From: Heesob Park Date: 2009-01-29T14:47:11+09:00 Subject: Re: Errno::ENOMEM reading a device in Ruby, not in Java though 2009/1/29 Roger Pack : > Question on how to avoid an Errno::ENOMEM > > Currently if I open a tape device from my machine [/dev/st2] > in ruby reading the second file from it results in: > > read.rb:2:in `read': Cannot allocate memory - /dev/st2 (Errno::ENOMEM) > from read.rb:2 > > Java to do the same works, however. > > the "cat" command [i.e. cat memory" > > Here is an strace of the two: > > ruby: > > open("/dev/st2", O_RDONLY) = 3 > fstat(3, {st_mode=S_IFCHR|0660, st_rdev=makedev(9, 2), ...}) = 0 > fstat(3, {st_mode=S_IFCHR|0660, st_rdev=makedev(9, 2), ...}) = 0 > ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fff5721d900) = -1 EINVAL > (Invalid argument) > mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) > = 0x2b5b53902000 > read(3, 0x2b5b53902000, 4096) = -1 ENOMEM (Cannot allocate > memory) > > > java: > > [pid 25476] open("/dev/nst2", O_RDONLY) = 4 > [pid 25476] fstat(4, {st_mode=S_IFCHR|0660, st_rdev=makedev(9, 130), > ...}) = 0 > [pid 25476] mprotect(0x2aab3409b000, 65536, PROT_READ|PROT_WRITE) = 0 > [pid 25476] read(4, "\n > Anybody know if the difference between mmap and mprotect might be > causing this? The another difference between ruby and java is read buffer size. Ruby's buffer size is 4096 and java's buffer size is 65536. The man page of st says: RETURN VALUE ENOMEM The byte count in read() is smaller than the next physi- cal block on the tape. (Before 2.2.18 and 2.4.0-test6 the extra bytes have been silently ignored.) Refer to http://fts.ifac.cnr.it/cgi-bin/dwww?type=runman&location=st/4 Regards, Park Heesob