file:write() fails silently for read-only files

classic Classic list List threaded Threaded
27 messages Options
12
Reply | Threaded
Open this post in threaded view
|

file:write() fails silently for read-only files

Rena
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> f=io.open('foo.foo', 'r')
> f:write('ffd')
> f:close()
>

Call me crazy, but I feel like f:write() should throw an error when
trying to write to a read-only file, instead of just doing nothing.

--
Sent from my toaster.

Reply | Threaded
Open this post in threaded view
|

Re: file:write() fails silently for read-only files

Josh Simmons
On Tue, Sep 6, 2011 at 4:39 PM, HyperHacker <[hidden email]> wrote:

> Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
>> f=io.open('foo.foo', 'r')
>> f:write('ffd')
>> f:close()
>>
>
> Call me crazy, but I feel like f:write() should throw an error when
> trying to write to a read-only file, instead of just doing nothing.
>
> --
> Sent from my toaster.
>
>

Check the return value of write.

Reply | Threaded
Open this post in threaded view
|

Re: file:write() fails silently for read-only files

Rena
On Tue, Sep 6, 2011 at 00:51, Josh Simmons <[hidden email]> wrote:

> On Tue, Sep 6, 2011 at 4:39 PM, HyperHacker <[hidden email]> wrote:
>> Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
>>> f=io.open('foo.foo', 'r')
>>> f:write('ffd')
>>> f:close()
>>>
>>
>> Call me crazy, but I feel like f:write() should throw an error when
>> trying to write to a read-only file, instead of just doing nothing.
>>
>> --
>> Sent from my toaster.
>>
>>
>
> Check the return value of write.
>
>

I get "bad file descriptor" which seems rather misleading. No return
value is documented in the manual though.

--
Sent from my toaster.

Reply | Threaded
Open this post in threaded view
|

Re: file:write() fails silently for read-only files

startx
In reply to this post by Rena
On Tue, 6 Sep 2011 00:39:00 -0600
HyperHacker <[hidden email]> wrote:

> Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> > f=io.open('foo.foo', 'r')
> > f:write('ffd')
> > f:close()
> >
>
> Call me crazy, but I feel like f:write() should throw an error when
> trying to write to a read-only file, instead of just doing nothing.
>

hm, when i do that ( on linux ) i _do_ get an error

  lua: filer.lua:2: attempt to index global 'f' (a nil value)
  stack traceback:
          filer.lua:2: in main chunk
          [C]: ?

startx

Reply | Threaded
Open this post in threaded view
|

Re: file:write() fails silently for read-only files

Rena
On Tue, Sep 6, 2011 at 01:10, startx <[hidden email]> wrote:

> On Tue, 6 Sep 2011 00:39:00 -0600
> HyperHacker <[hidden email]> wrote:
>
>> Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
>> > f=io.open('foo.foo', 'r')
>> > f:write('ffd')
>> > f:close()
>> >
>>
>> Call me crazy, but I feel like f:write() should throw an error when
>> trying to write to a read-only file, instead of just doing nothing.
>>
>
> hm, when i do that ( on linux ) i _do_ get an error
>
>  lua: filer.lua:2: attempt to index global 'f' (a nil value)
>  stack traceback:
>          filer.lua:2: in main chunk
>          [C]: ?
>
> startx
>
>

You'd need to create a file "foo.foo" first...

--
Sent from my toaster.

Reply | Threaded
Open this post in threaded view
|

Re: file:write() fails silently for read-only files

Sean Conner
In reply to this post by Rena
It was thus said that the Great HyperHacker once stated:

> On Tue, Sep 6, 2011 at 00:51, Josh Simmons <[hidden email]> wrote:
> > On Tue, Sep 6, 2011 at 4:39 PM, HyperHacker <[hidden email]> wrote:
> >> Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> >>> f=io.open('foo.foo', 'r')
> >>> f:write('ffd')
> >>> f:close()
> >>>
> >>
> >> Call me crazy, but I feel like f:write() should throw an error when
> >> trying to write to a read-only file, instead of just doing nothing.
> >>
> >> --
> >> Sent from my toaster.
> >>
> >>
> >
> > Check the return value of write.
> >
> >
>
> I get "bad file descriptor" which seems rather misleading. No return
> value is documented in the manual though.

  Re-read section 5.7:

        Unless otherwise stated, all I/O functions return nil on failure
        (plus an error message as a second result and a system-dependent
        error code as a third result) and some value different from nil on
        success.

  Also, under Unix, the write() system call (which is the system call that
f:write() eventually calls) can return EBADF (which translates to "bad file
descriptor") as described in the man page:

        ERRORS

                EBADF fd is not a valid file descriptor or is not open for
                writing.

                ...

  -spc


Reply | Threaded
Open this post in threaded view
|

Re: file:write() fails silently for read-only files

Rena
On Tue, Sep 6, 2011 at 01:14, Sean Conner <[hidden email]> wrote:

> It was thus said that the Great HyperHacker once stated:
>> On Tue, Sep 6, 2011 at 00:51, Josh Simmons <[hidden email]> wrote:
>> > On Tue, Sep 6, 2011 at 4:39 PM, HyperHacker <[hidden email]> wrote:
>> >> Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
>> >>> f=io.open('foo.foo', 'r')
>> >>> f:write('ffd')
>> >>> f:close()
>> >>>
>> >>
>> >> Call me crazy, but I feel like f:write() should throw an error when
>> >> trying to write to a read-only file, instead of just doing nothing.
>> >>
>> >> --
>> >> Sent from my toaster.
>> >>
>> >>
>> >
>> > Check the return value of write.
>> >
>> >
>>
>> I get "bad file descriptor" which seems rather misleading. No return
>> value is documented in the manual though.
>
>  Re-read section 5.7:
>
>        Unless otherwise stated, all I/O functions return nil on failure
>        (plus an error message as a second result and a system-dependent
>        error code as a third result) and some value different from nil on
>        success.
>
>  Also, under Unix, the write() system call (which is the system call that
> f:write() eventually calls) can return EBADF (which translates to "bad file
> descriptor") as described in the man page:
>
>        ERRORS
>
>                EBADF fd is not a valid file descriptor or is not open for
>                writing.
>
>                ...
>
>  -spc
>
>
>

Ahh, serves me right for only looking at the specific function and not
the section header.

Just because Unix does it that way though doesn't necessarily mean
it's the best way. I think throwing an error makes more sense than
returning a system-dependent, odd-sounding error code/message.

--
Sent from my toaster.

Reply | Threaded
Open this post in threaded view
|

Re: file:write() fails silently for read-only files

Josh Simmons
In reply to this post by Rena
On Tue, Sep 6, 2011 at 5:09 PM, HyperHacker <[hidden email]> wrote:

> On Tue, Sep 6, 2011 at 00:51, Josh Simmons <[hidden email]> wrote:
>> On Tue, Sep 6, 2011 at 4:39 PM, HyperHacker <[hidden email]> wrote:
>>> Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
>>>> f=io.open('foo.foo', 'r')
>>>> f:write('ffd')
>>>> f:close()
>>>>
>>>
>>> Call me crazy, but I feel like f:write() should throw an error when
>>> trying to write to a read-only file, instead of just doing nothing.
>>>
>>> --
>>> Sent from my toaster.
>>>
>>>
>>
>> Check the return value of write.
>>
>>
>
> I get "bad file descriptor" which seems rather misleading. No return
> value is documented in the manual though.
>
> --
> Sent from my toaster.
>
>

Odd that it's not mentioned.

All IO functions use the luaL_fileresult function however, which uses
errno+strerror to report any error message and so the actual error
message is outside Lua's control.

Reply | Threaded
Open this post in threaded view
|

Re: file:write() fails silently for read-only files

Josh Simmons
On Tue, Sep 6, 2011 at 5:16 PM, Josh Simmons <[hidden email]> wrote:

> On Tue, Sep 6, 2011 at 5:09 PM, HyperHacker <[hidden email]> wrote:
>> On Tue, Sep 6, 2011 at 00:51, Josh Simmons <[hidden email]> wrote:
>>> On Tue, Sep 6, 2011 at 4:39 PM, HyperHacker <[hidden email]> wrote:
>>>> Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
>>>>> f=io.open('foo.foo', 'r')
>>>>> f:write('ffd')
>>>>> f:close()
>>>>>
>>>>
>>>> Call me crazy, but I feel like f:write() should throw an error when
>>>> trying to write to a read-only file, instead of just doing nothing.
>>>>
>>>> --
>>>> Sent from my toaster.
>>>>
>>>>
>>>
>>> Check the return value of write.
>>>
>>>
>>
>> I get "bad file descriptor" which seems rather misleading. No return
>> value is documented in the manual though.
>>
>> --
>> Sent from my toaster.
>>
>>
>
> Odd that it's not mentioned.
>
> All IO functions use the luaL_fileresult function however, which uses
> errno+strerror to report any error message and so the actual error
> message is outside Lua's control.
>

The error message does make sense too when you consider that you're
calling the write function and passing a fd, the descriptor is invalid
for the given function.

Reply | Threaded
Open this post in threaded view
|

Re: file:write() fails silently for read-only files

startx
In reply to this post by Rena
On Tue, 6 Sep 2011 01:12:07 -0600
HyperHacker <[hidden email]> wrote:

>> On Tue, Sep 6, 2011 at 01:10, startx <[hidden email]> wrote:
> > hm, when i do that ( on linux ) i _do_ get an error
> >
> >  lua: filer.lua:2: attempt to index global 'f' (a nil value)
> >  stack traceback:
> >          filer.lua:2: in main chunk
> >          [C]: ?
> >
> > startx
> >
> >

>
> You'd need to create a file "foo.foo" first...
>

yes, you are correct.

however, you do something like

  f = io.open('foo.foo', 'r')
  success = f:write('ffd')
  f:close()

success will be NIL if the file cannot be written to.
one one hand i see your point that it could throw an error instead, but
then again ...

startx



Reply | Threaded
Open this post in threaded view
|

Re: file:write() fails silently for read-only files

Josh Simmons
On Tue, Sep 6, 2011 at 5:21 PM, startx <[hidden email]> wrote:

> On Tue, 6 Sep 2011 01:12:07 -0600
> HyperHacker <[hidden email]> wrote:
>
>>> On Tue, Sep 6, 2011 at 01:10, startx <[hidden email]> wrote:
>> > hm, when i do that ( on linux ) i _do_ get an error
>> >
>> >  lua: filer.lua:2: attempt to index global 'f' (a nil value)
>> >  stack traceback:
>> >          filer.lua:2: in main chunk
>> >          [C]: ?
>> >
>> > startx
>> >
>> >
>
>>
>> You'd need to create a file "foo.foo" first...
>>
>
> yes, you are correct.
>
> however, you do something like
>
>  f = io.open('foo.foo', 'r')
>  success = f:write('ffd')
>  f:close()
>
> success will be NIL if the file cannot be written to.
> one one hand i see your point that it could throw an error instead, but
> then again ...
>
> startx
>
>
>
>

Lua's general policy is to throw errors when there's programmer error
(like 'coroutine.wrap(7)', and return nil+error message for
environmental issues (like files missing or bad permissions).

Reply | Threaded
Open this post in threaded view
|

Re: file:write() fails silently for read-only files

steve donovan
In reply to this post by startx
On Tue, Sep 6, 2011 at 9:21 AM, startx <[hidden email]> wrote:
> success will be NIL if the file cannot be written to.
> one one hand i see your point that it could throw an error instead, but
> then again ...

You could wrap up the Lua file object so that the write/read methods
throw errors, so it's not difficult to choose the error handling mode
you need.

steve d.

Reply | Threaded
Open this post in threaded view
|

Re: file:write() fails silently for read-only files

steve donovan
In reply to this post by startx
On Tue, Sep 6, 2011 at 9:21 AM, startx <[hidden email]> wrote:
>  f = io.open('foo.foo', 'r')
>  success = f:write('ffd')
>  f:close()
> success will be NIL if the file cannot be written to.

Ah, but not always!

f = io.open('errio.lua')
for i = 1,3 do
  print(f:read())
end
print(f:write('hello dolly'))
f:close()

On this machine (Windows XP) that write returns true - a silent error!
Must be Windows weirdness, because this script does behave as you
expect on Linux.

steve d.

Reply | Threaded
Open this post in threaded view
|

Re: file:write() fails silently for read-only files

Dirk Laurie
In reply to this post by Rena
On Tue, Sep 06, 2011 at 08:39:00AM +0200, HyperHacker wrote:
> Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> > f=io.open('foo.foo', 'r')
> > f:write('ffd')
> > f:close()
> >
>
> Call me crazy, but I feel like f:write() should throw an error when
> trying to write to a read-only file, instead of just doing nothing.

There are two ways of handling errors: testable return values, and
throwing errors.  Among programming languages that I use, Lua is unique
in giving you a seamless way of overriding whatever default choice it
has made.  So you can do this:

local io_write = io.write
io.write = function(...)
    local test, message, code = io_write(...)
    if test==nil then error(message,2) end
    end

If io.write had thrown an error instead, you could similarly have
overridden it by a wrapper that uses pcall.

Dirk

Reply | Threaded
Open this post in threaded view
|

Re: file:write() fails silently for read-only files

Xavier Wang
In reply to this post by Rena

fwrite may not know its operating a read mode file....

在 2011-9-6 下午2:39,"HyperHacker" <[hidden email]>写道:
> Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
>> f=io.open('foo.foo', 'r')
>> f:write('ffd')
>> f:close()
>>
>
> Call me crazy, but I feel like f:write() should throw an error when
> trying to write to a read-only file, instead of just doing nothing.
>
> --
> Sent from my toaster.
>
Reply | Threaded
Open this post in threaded view
|

Re: file:write() fails silently for read-only files

Gé Weijers
In reply to this post by Dirk Laurie

You can use 'assert' in many cases:

f = assert(io.open('foo.foo', 'r'))
assert(f:write("xyzzy"))
assert(f:close())




On Tue, 6 Sep 2011, Dirk Laurie wrote:

> On Tue, Sep 06, 2011 at 08:39:00AM +0200, HyperHacker wrote:
>> Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
>>> f=io.open('foo.foo', 'r')
>>> f:write('ffd')
>>> f:close()
>>>
>>
>> Call me crazy, but I feel like f:write() should throw an error when
>> trying to write to a read-only file, instead of just doing nothing.
>
> There are two ways of handling errors: testable return values, and
> throwing errors.  Among programming languages that I use, Lua is unique
> in giving you a seamless way of overriding whatever default choice it
> has made.  So you can do this:
>
> local io_write = io.write
> io.write = function(...)
>    local test, message, code = io_write(...)
>    if test==nil then error(message,2) end
>    end
>
> If io.write had thrown an error instead, you could similarly have
> overridden it by a wrapper that uses pcall.
>
> Dirk
>
>
Reply | Threaded
Open this post in threaded view
|

Re: file:write() fails silently for read-only files

Lorenzo Donati-2
In reply to this post by steve donovan
On 06/09/2011 9.37, steve donovan wrote:

> On Tue, Sep 6, 2011 at 9:21 AM, startx<[hidden email]>  wrote:
>>   f = io.open('foo.foo', 'r')
>>   success = f:write('ffd')
>>   f:close()
>> success will be NIL if the file cannot be written to.
>
> Ah, but not always!
>
> f = io.open('errio.lua')
> for i = 1,3 do
>    print(f:read())
> end
> print(f:write('hello dolly'))
> f:close()
>
> On this machine (Windows XP) that write returns true - a silent error!
> Must be Windows weirdness, because this script does behave as you
> expect on Linux.
>
> steve d.
>
>
>

If errio.lua contains just two lines:

blah
blih

I get:

blah
blih
nil
nil No error 0


I.e.: the "write" operation kindly informs me that there was no error!
:-) (the last 0 is another mistery).

I'm on WinXP sp2; Lua 5.1.4 and 5.2 beta produce the same result. They
were compiled with tdm-gcc 4.5.2.

-- Lorenzo


Reply | Threaded
Open this post in threaded view
|

Re: file:write() fails silently for read-only files

Enrico Colombini
In reply to this post by steve donovan
On 06/09/2011 9.37, steve donovan wrote:

> Ah, but not always!
>
> f = io.open('errio.lua')
> for i = 1,3 do
>    print(f:read())
> end
> print(f:write('hello dolly'))
> f:close()
>
> On this machine (Windows XP) that write returns true - a silent error!

That's strange: on my XP, Lua 5.1.2 prints:

  1
  2
  3
  nil     No error        0

Apart from the interesting "No error" error description, it seems to be
as expected.
errio.lua contains five lines.

--
   Enrico

Reply | Threaded
Open this post in threaded view
|

Re: file:write() fails silently for read-only files

Josh Simmons
On Wed, Sep 7, 2011 at 4:55 AM, Enrico Colombini <[hidden email]> wrote:

> On 06/09/2011 9.37, steve donovan wrote:
>>
>> Ah, but not always!
>>
>> f = io.open('errio.lua')
>> for i = 1,3 do
>>   print(f:read())
>> end
>> print(f:write('hello dolly'))
>> f:close()
>>
>> On this machine (Windows XP) that write returns true - a silent error!
>
> That's strange: on my XP, Lua 5.1.2 prints:
>
>  1
>  2
>  3
>  nil     No error        0
>
> Apart from the interesting "No error" error description, it seems to be as
> expected.
> errio.lua contains five lines.
>
> --
>  Enrico
>
>

The third number is the value of errno.
nil, strerror(errno), errno

Cheers,
Josh.

Reply | Threaded
Open this post in threaded view
|

Re: file:write() fails silently for read-only files

Josh Simmons
On Wed, Sep 7, 2011 at 9:06 AM, Josh Simmons <[hidden email]> wrote:

> On Wed, Sep 7, 2011 at 4:55 AM, Enrico Colombini <[hidden email]> wrote:
>> On 06/09/2011 9.37, steve donovan wrote:
>>>
>>> Ah, but not always!
>>>
>>> f = io.open('errio.lua')
>>> for i = 1,3 do
>>>   print(f:read())
>>> end
>>> print(f:write('hello dolly'))
>>> f:close()
>>>
>>> On this machine (Windows XP) that write returns true - a silent error!
>>
>> That's strange: on my XP, Lua 5.1.2 prints:
>>
>>  1
>>  2
>>  3
>>  nil     No error        0
>>
>> Apart from the interesting "No error" error description, it seems to be as
>> expected.
>> errio.lua contains five lines.
>>
>> --
>>  Enrico
>>
>>
>
> The third number is the value of errno.
> nil, strerror(errno), errno
>
> Cheers,
> Josh.
>

The failure is not triggered be errno itself though, so it's possible
for any of the functions to return error but not set errno (on windows
anyway).

12