Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid argument @ rb_sysopen - (Errno:EINVAL) when using local files on Windows #435

Closed
jakubklimek opened this issue Apr 13, 2022 · 10 comments

Comments

@jakubklimek
Copy link

jakubklimek commented Apr 13, 2022

When I try running e.g. rdf serialize --input-format tabular 1.csv on Windows, I get:

C:\Tools\rubyinstaller-3.1.1-1-x64\bin>rdf serialize --input-format tabular 1.csv-metadata.json
C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/util/file.rb:322:in `initialize': Invalid argument @ rb_sysopen - /C:/Tools/rubyinstaller-3.1.1-1-x64/bin/1.csv (Errno::EINVAL)
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/util/file.rb:322:in `open'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/util/file.rb:322:in `open_file'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/reader.rb:221:in `open'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-tabular-3.2.0/lib/rdf/tabular/reader.rb:217:in `block (2 levels) in each_statement'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-tabular-3.2.0/lib/rdf/tabular/metadata.rb:1345:in `block in each_table'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-tabular-3.2.0/lib/rdf/tabular/metadata.rb:1344:in `each'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-tabular-3.2.0/lib/rdf/tabular/metadata.rb:1344:in `each_table'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-tabular-3.2.0/lib/rdf/tabular/reader.rb:207:in `block in each_statement'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/util/logger.rb:264:in `log_depth'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/util/logger.rb:198:in `log_depth'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-tabular-3.2.0/lib/rdf/tabular/reader.rb:176:in `each_statement'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/cli.rb:537:in `block in exec'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/cli.rb:685:in `block (2 levels) in parse'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-tabular-3.2.0/lib/rdf/tabular/reader.rb:156:in `block (2 levels) in initialize'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/util/logger.rb:264:in `log_depth'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/util/logger.rb:198:in `log_depth'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-tabular-3.2.0/lib/rdf/tabular/reader.rb:97:in `block in initialize'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/reader.rb:319:in `instance_eval'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/reader.rb:319:in `initialize'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-tabular-3.2.0/lib/rdf/tabular/reader.rb:76:in `initialize'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/reader.rb:244:in `new'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/reader.rb:244:in `block in open'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/util/file.rb:340:in `open_file'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/reader.rb:221:in `open'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/reader.rb:212:in `open'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/cli.rb:683:in `block in parse'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/cli.rb:682:in `each'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/cli.rb:682:in `parse'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/cli.rb:536:in `exec'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/bin/rdf:13:in `<top (required)>'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/bin/rdf:32:in `load'
        from C:/Tools/rubyinstaller-3.1.1-1-x64/bin/rdf:32:in `<main>'

The descriptor points to the CSV file like this:

{
    "@id": "https://example.org/public-contracts/contracts2.csv-metadata.json",
    "@context": [
        "http://www.w3.org/ns/csvw",
        {
            "@language": "en"
        }
    ],
    "@type": "Table",
    "url": "1.csv",

When I try serializing the CSV file directly, I get a similar error

C:\Tools\rubyinstaller-3.1.1-1-x64\bin>rdf serialize --input-format tabular 1.csv
C:/Tools/rubyinstaller-3.1.1-1-x64/lib/ruby/gems/3.1.0/gems/rdf-3.2.6/lib/rdf/util/file.rb:322:in `initialize': Invalid argument @ rb_sysopen - /C:/Tools/rubyinstaller-3.1.1-1-x64/bin/1.csv-metadata.json (Errno::EINVAL)
@gkellogg
Copy link
Member

Line 322 is a call to Kernel.open.

rdf/lib/rdf/util/file.rb

Lines 322 to 330 in a083623

Kernel.open(url_no_frag_or_query, "r", **options) do |file|
document_options = {
base_uri: filename_or_url.to_s,
charset: file.external_encoding.to_s,
code: 200,
content_type: content_type,
last_modified:file.mtime,
headers: {content_type: content_type, last_modified: file.mtime.xmlschema}
}

So, it seems the error is that the format of the path you're giving to Kernel.open (/C:/Tools/rubyinstaller-3.1.1-1-x64/bin/1.csv-metadata.json) needs to be something that Ruby on Windows can handle. Perhaps without the leading /? I'm afraid I don't have a windows system available to me for testing.

@gkellogg
Copy link
Member

Depending on the table reference in 1.csv-metadata.json, it could be that there's some errant code that expands it to a non-relative path, but it would likely use File.expand_path. Sorry I can't be of more immediate help, but if you can identify where it needs to do something different, I'd be happy to look further.

@jakubklimek
Copy link
Author

That slash at the beginning of the path definitely seems suspect. Unfortunately, I do not code in ruby, so I am not able to debug this efficiently.

@jakubklimek jakubklimek changed the title Invalid argument @ rb_sysopen - (Errno:EINVAL) on Windows Invalid argument @ rb_sysopen - (Errno:EINVAL) when using local files on Windows Apr 14, 2022
@gkellogg
Copy link
Member

Maybe you could send a link to your 1.csv-metadata.json and a couple of lines from the referenced 1.csv, I might be able to see where the code is making assumptions that don't work on MS.

@jakubklimek
Copy link
Author

I have these files in C:\Tools (but I guess any other windows path would do). I added the .txt extension just so that it can be uploaded to GitHub. I use this in class, so it is not a long file. Just note that the same error is triggered also by just validating the CSV file, even without the JSON descriptor in place - as it crashes on the same error even when just trying to locate the descriptor.

1.csv
1.csv-metadata.json.txt

@gkellogg
Copy link
Member

It will be later next week before I can look into this properly, as I’m actually holiday for the next several days, and I need to figure out an MSWIn environment to use.

@jakubklimek
Copy link
Author

That is perfectly fine, thank you. Fortunately, there is a couple of workarounds:

  1. Use WSL (Windows Subsystem for Linux) or a Linux VM
  2. Upload the files somewhere they get an http(s) based URL - local webserver or GitHub, etc.

@gkellogg
Copy link
Member

There is a fix that addresses this released in RDF.rb 3.2.7, but there is also a change on the develop branch of the rdf-tabular gem. If you can clone the rdf-tabular gem, do a bundle install and try again from that project using bundle exec rdf serialize --input-format tabular 1.csv to see if that fixes the issue.

The problem is that expressed using forward slashes, C:/Tools/rubyinstaller-3.1.1-1-x64/bin/1.csv-metadata.json looks like an absolute URI using the "C" URI scheme. There is a non-standard provision for treating this as a component of the URI path instead (see RFC8089 Appendix E), so I added code for checking absolute or relative IRIs in RDF.rb to include this variation when working on the windows platform, and improved code in rdf-tabular for checking for relative IRIs.

@jakubklimek
Copy link
Author

@gkellogg Thank you, I can confirm that it works with the code from develop.

@gkellogg
Copy link
Member

Great, I’ll release an update of rdf-tabular tomorrow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants