Clojure

slurp fails on /proc files (linux)

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Declined
  • Affects Version/s: Release 1.3
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None
  • Environment:
    linux

Description

On my machine,
(slurp "/proc/cpuinfo")
fails with:
java.io.IOException: Argument invalide (NO_SOURCE_FILE:0)

whereas the following succeeds:
(with-open [f (java.io.FileReader. "/proc/cpuinfo")] (slurp f))

Activity

Hide
Andy Fingerhut added a comment -

I contacted Romain, the submitter, and they agreed that trying to work around this JVM bug in Clojure's slurp might be a bit excessive, and that closing the ticket was reasonable.

I have added a note about Romain's workaround at http://clojuredocs.org/clojure_core/1.3.0/clojure.core/slurp in hopes that others will be able to find it more easily.

Show
Andy Fingerhut added a comment - I contacted Romain, the submitter, and they agreed that trying to work around this JVM bug in Clojure's slurp might be a bit excessive, and that closing the ticket was reasonable. I have added a note about Romain's workaround at http://clojuredocs.org/clojure_core/1.3.0/clojure.core/slurp in hopes that others will be able to find it more easily.
Hide
Andy Fingerhut added a comment - - edited

This is not a fix, but a workaround for this issue with the JVM: call slurp on a reader that you force to be constructed as unbuffered. For example:

(slurp (java.io.InputStreamReader. (java.io.FileInputStream. "/proc/cpuinfo")))

(tested with Sun/Oracle JDK 1.7.0_02)

This is less efficient for large files, so I wouldn't recommend that the slurp code be modified to work this way for all files.

One can imagine an implementation of Clojure slurp and clojure.java.io/reader that first tried the slurp call with buffered I/O, and if an exception like this one occurs fall back to unbuffered I/O. However, that sounds like it would get very hairy very quickly, and would be difficult to write it in such a way that it did not mask I/O errors that should be visible to the caller. Also that seems like unwanted complexity in Clojure to work around what is likely a bug in the JVM. Someone (Tassilo?) filed a bug with Oracle about this exception:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7132461

Show
Andy Fingerhut added a comment - - edited This is not a fix, but a workaround for this issue with the JVM: call slurp on a reader that you force to be constructed as unbuffered. For example: (slurp (java.io.InputStreamReader. (java.io.FileInputStream. "/proc/cpuinfo"))) (tested with Sun/Oracle JDK 1.7.0_02) This is less efficient for large files, so I wouldn't recommend that the slurp code be modified to work this way for all files. One can imagine an implementation of Clojure slurp and clojure.java.io/reader that first tried the slurp call with buffered I/O, and if an exception like this one occurs fall back to unbuffered I/O. However, that sounds like it would get very hairy very quickly, and would be difficult to write it in such a way that it did not mask I/O errors that should be visible to the caller. Also that seems like unwanted complexity in Clojure to work around what is likely a bug in the JVM. Someone (Tassilo?) filed a bug with Oracle about this exception: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7132461
Hide
Tassilo Horn added a comment -

It seems this is not an error in Clojure but an error in the native implementation of FileInputStream.available(). For example, this Java code throws the same exception.

    FileInputStream fis = new FileInputStream("/home/horn/dead.letter");
    System.out.println(fis.available());  // Works fine

    fis = new FileInputStream("/proc/cpuinfo");
    System.out.println(fis.available());  // IOException is thrown

Tested with sun-jdk 1.6.0.29 and IcedTea 7.2.0.

Show
Tassilo Horn added a comment - It seems this is not an error in Clojure but an error in the native implementation of FileInputStream.available(). For example, this Java code throws the same exception.
    FileInputStream fis = new FileInputStream("/home/horn/dead.letter");
    System.out.println(fis.available());  // Works fine

    fis = new FileInputStream("/proc/cpuinfo");
    System.out.println(fis.available());  // IOException is thrown
Tested with sun-jdk 1.6.0.29 and IcedTea 7.2.0.

People

  • Assignee:
    Unassigned
    Reporter:
    Romain
Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: