opening a write-only file

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

opening a write-only file

douglas mcpherson
Is there a way to open a write-only file in Squeak? On both Mac and Linux attempting to open such a file fails.

For example, if you create a write-only file, i.e. in a shell, after cd to default directory

echo nada > foo
chmod 200 foo

Then from Squeak

StandardFileStream fileNamed: 'foo'

returns nil.

If the file is given read permission (i.e. chmod 600 foo) then Squeak can open it.

Anyone know a workaround?

Thanks,
Doug


Reply | Threaded
Open this post in threaded view
|

Re: opening a write-only file

David T. Lewis
On Sat, May 31, 2014 at 10:00:06AM -0700, Douglas McPherson wrote:

> Is there a way to open a write-only file in Squeak? On both Mac and Linux attempting to open such a file fails.
>
> For example, if you create a write-only file, i.e. in a shell, after cd to default directory
>
> echo nada > foo
> chmod 200 foo
>
> Then from Squeak
>
> StandardFileStream fileNamed: 'foo'
>
> returns nil.
>
> If the file is given read permission (i.e. chmod 600 foo) then Squeak can open it.
>
> Anyone know a workaround?
>

Sure, you can use FileStream readOnlyFileNamed: 'foo'.

Dave

Reply | Threaded
Open this post in threaded view
|

Re: opening a write-only file

douglas mcpherson
Yes, but the file is write-only, not read-only :)

Interestingly, trying FileStream readOnlyFileNamed: 'foo' yields a FileDoesNotExistException, although the file does exist, it just happens to be write-only.

StandardFileStream fileNamed: 'foo' does not raise FileDoesNotExistException, instead fails to open the file and returns nil. 

Doug


On May 31, 2014, at 10:46 , David T. Lewis wrote:

On Sat, May 31, 2014 at 10:00:06AM -0700, Douglas McPherson wrote:
Is there a way to open a write-only file in Squeak? On both Mac and Linux attempting to open such a file fails.

For example, if you create a write-only file, i.e. in a shell, after cd to default directory

echo nada > foo
chmod 200 foo

Then from Squeak

StandardFileStream fileNamed: 'foo'

returns nil.

If the file is given read permission (i.e. chmod 600 foo) then Squeak can open it.

Anyone know a workaround?


Sure, you can use FileStream readOnlyFileNamed: 'foo'.

Dave




Reply | Threaded
Open this post in threaded view
|

Re: opening a write-only file

Eliot Miranda-2
In reply to this post by douglas mcpherson
Hi Doug,


On Sat, May 31, 2014 at 10:00 AM, Douglas McPherson <[hidden email]> wrote:
Is there a way to open a write-only file in Squeak? On both Mac and Linux attempting to open such a file fails.

Squeak has forceNewFileNamed: & forceNewFileNamed:do:.  If you look at sqFileOpen in platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c you'll see it first attempts to open read-write and if that fails, opens write-only.  So it should work.

HTH

For example, if you create a write-only file, i.e. in a shell, after cd to default directory

echo nada > foo
chmod 200 foo

Then from Squeak

StandardFileStream fileNamed: 'foo'

returns nil.

If the file is given read permission (i.e. chmod 600 foo) then Squeak can open it.

Anyone know a workaround?

Thanks,
Doug


--
best,
Eliot


Reply | Threaded
Open this post in threaded view
|

Re: opening a write-only file

douglas mcpherson
Ahh, thanks. I'll try it out when back in front of my machine.

Thanks,
Doug

Sent from my iPhone

On May 31, 2014, at 14:23, Eliot Miranda <[hidden email]> wrote:

Hi Doug,


On Sat, May 31, 2014 at 10:00 AM, Douglas McPherson <[hidden email]> wrote:
Is there a way to open a write-only file in Squeak? On both Mac and Linux attempting to open such a file fails.

Squeak has forceNewFileNamed: & forceNewFileNamed:do:.  If you look at sqFileOpen in platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c you'll see it first attempts to open read-write and if that fails, opens write-only.  So it should work.

HTH

For example, if you create a write-only file, i.e. in a shell, after cd to default directory

echo nada > foo
chmod 200 foo

Then from Squeak

StandardFileStream fileNamed: 'foo'

returns nil.

If the file is given read permission (i.e. chmod 600 foo) then Squeak can open it.

Anyone know a workaround?

Thanks,
Doug


--
best,
Eliot



Reply | Threaded
Open this post in threaded view
|

Re: opening a write-only file

douglas mcpherson
It turns out #forceNewFileNamed: does not work either.

I believe the immediate cause of the problem is in the function you pointed me at: sqFileOpen() in platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c:

if (writeFlag) {
/* First try to open an existing file read/write: */
setFile(f, fopen(cFileName, "r+b"));
if (getFile(f) == NULL) {
/* Previous call fails if file does not exist. In that case,
  try opening it in write mode to create a new, empty file.
*/
setFile(f, fopen(cFileName, "w+b"));
if (getFile(f) != NULL) {
   char type[4],creator[4];
dir_GetMacFileTypeAndCreator(sqFileName, sqFileNameSize, type, creator);
if (strncmp(type,"BINA",4) == 0 || strncmp(type,"????",4) == 0 || *(int *)type == 0 ) 
   dir_SetMacFileTypeAndCreator(sqFileName, sqFileNameSize,"TEXT","R*ch");
}
}

The first call to fopen() indeed fails if the file does not exist. But it also fails if the file exists but does not have both read and write "r+b" permission. So in that case the intent, as you mentioned, is to try to open in write-only but "w+b" is not the write-only mode, it is also a read and write mode, see [1]. So this fopen() attempt also fails if the file has write-only permission. A fix may be to use mode "wb" instead of "w+b", but I'm not sure if there are unintended consequences to doing this.


On May 31, 2014, at 14:45 , Douglas McPherson wrote:

Ahh, thanks. I'll try it out when back in front of my machine.

Thanks,
Doug

Sent from my iPhone

On May 31, 2014, at 14:23, Eliot Miranda <[hidden email]> wrote:

Hi Doug,


On Sat, May 31, 2014 at 10:00 AM, Douglas McPherson <[hidden email]> wrote:
Is there a way to open a write-only file in Squeak? On both Mac and Linux attempting to open such a file fails.

Squeak has forceNewFileNamed: & forceNewFileNamed:do:.  If you look at sqFileOpen in platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c you'll see it first attempts to open read-write and if that fails, opens write-only.  So it should work.

HTH

For example, if you create a write-only file, i.e. in a shell, after cd to default directory

echo nada > foo
chmod 200 foo

Then from Squeak

StandardFileStream fileNamed: 'foo'

returns nil.

If the file is given read permission (i.e. chmod 600 foo) then Squeak can open it.

Anyone know a workaround?

Thanks,
Doug


--
best,
Eliot





Reply | Threaded
Open this post in threaded view
|

Re: opening a write-only file

douglas mcpherson
Hi All, 

I've tested a fix for this on OS X and Linux. The fix simply adds an extra attempt to open the file after the "w+b" attempt using this code:

         if (getFile(f) == NULL) {
            setFile(f, fopen(cFileName, "wb"));
         }

If the previous attempts to open the file failed (because the file exists with write-only permission, no read permission) then the above will actually open the file write-only. Adding the extra attempt preserves existing behaviour for the success paths, so the change should be transparent to existing code.

BTW, AFAICT the same issue exists in Pharo.

Thoughts?

Doug


On Jun 1, 2014, at 19:44 , Douglas McPherson wrote:

It turns out #forceNewFileNamed: does not work either.

I believe the immediate cause of the problem is in the function you pointed me at: sqFileOpen() in platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c:

if (writeFlag) {
/* First try to open an existing file read/write: */
setFile(f, fopen(cFileName, "r+b"));
if (getFile(f) == NULL) {
/* Previous call fails if file does not exist. In that case,
  try opening it in write mode to create a new, empty file.
*/
setFile(f, fopen(cFileName, "w+b"));
if (getFile(f) != NULL) {
   char type[4],creator[4];
dir_GetMacFileTypeAndCreator(sqFileName, sqFileNameSize, type, creator);
if (strncmp(type,"BINA",4) == 0 || strncmp(type,"????",4) == 0 || *(int *)type == 0 ) 
   dir_SetMacFileTypeAndCreator(sqFileName, sqFileNameSize,"TEXT","R*ch");
}
}

The first call to fopen() indeed fails if the file does not exist. But it also fails if the file exists but does not have both read and write "r+b" permission. So in that case the intent, as you mentioned, is to try to open in write-only but "w+b" is not the write-only mode, it is also a read and write mode, see [1]. So this fopen() attempt also fails if the file has write-only permission. A fix may be to use mode "wb" instead of "w+b", but I'm not sure if there are unintended consequences to doing this.


On May 31, 2014, at 14:45 , Douglas McPherson wrote:

Ahh, thanks. I'll try it out when back in front of my machine.

Thanks,
Doug

Sent from my iPhone

On May 31, 2014, at 14:23, Eliot Miranda <[hidden email]> wrote:

Hi Doug,


On Sat, May 31, 2014 at 10:00 AM, Douglas McPherson <[hidden email]> wrote:
Is there a way to open a write-only file in Squeak? On both Mac and Linux attempting to open such a file fails.

Squeak has forceNewFileNamed: & forceNewFileNamed:do:.  If you look at sqFileOpen in platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c you'll see it first attempts to open read-write and if that fails, opens write-only.  So it should work.

HTH

For example, if you create a write-only file, i.e. in a shell, after cd to default directory

echo nada > foo
chmod 200 foo

Then from Squeak

StandardFileStream fileNamed: 'foo'

returns nil.

If the file is given read permission (i.e. chmod 600 foo) then Squeak can open it.

Anyone know a workaround?

Thanks,
Doug


--
best,
Eliot







Reply | Threaded
Open this post in threaded view
|

Re: opening a write-only file

Bert Freudenberg

On 04.06.2014, at 18:19, Douglas McPherson <[hidden email]> wrote:

Hi All, 

I've tested a fix for this on OS X and Linux. The fix simply adds an extra attempt to open the file after the "w+b" attempt using this code:

         if (getFile(f) == NULL) {
            setFile(f, fopen(cFileName, "wb"));
         }

If the previous attempts to open the file failed (because the file exists with write-only permission, no read permission) then the above will actually open the file write-only. Adding the extra attempt preserves existing behaviour for the success paths, so the change should be transparent to existing code.

BTW, AFAICT the same issue exists in Pharo.

Thoughts?

Doug

Sounds reasonable to me.

- Bert -




On Jun 1, 2014, at 19:44 , Douglas McPherson wrote:

It turns out #forceNewFileNamed: does not work either.

I believe the immediate cause of the problem is in the function you pointed me at: sqFileOpen() in platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c:

if (writeFlag) {
/* First try to open an existing file read/write: */
setFile(f, fopen(cFileName, "r+b"));
if (getFile(f) == NULL) {
/* Previous call fails if file does not exist. In that case,
  try opening it in write mode to create a new, empty file.
*/
setFile(f, fopen(cFileName, "w+b"));
if (getFile(f) != NULL) {
   char type[4],creator[4];
dir_GetMacFileTypeAndCreator(sqFileName, sqFileNameSize, type, creator);
if (strncmp(type,"BINA",4) == 0 || strncmp(type,"????",4) == 0 || *(int *)type == 0 ) 
   dir_SetMacFileTypeAndCreator(sqFileName, sqFileNameSize,"TEXT","R*ch");
}
}

The first call to fopen() indeed fails if the file does not exist. But it also fails if the file exists but does not have both read and write "r+b" permission. So in that case the intent, as you mentioned, is to try to open in write-only but "w+b" is not the write-only mode, it is also a read and write mode, see [1]. So this fopen() attempt also fails if the file has write-only permission. A fix may be to use mode "wb" instead of "w+b", but I'm not sure if there are unintended consequences to doing this.


On May 31, 2014, at 14:45 , Douglas McPherson wrote:

Ahh, thanks. I'll try it out when back in front of my machine.

Thanks,
Doug

Sent from my iPhone

On May 31, 2014, at 14:23, Eliot Miranda <[hidden email]> wrote:

Hi Doug,


On Sat, May 31, 2014 at 10:00 AM, Douglas McPherson <[hidden email]> wrote:
Is there a way to open a write-only file in Squeak? On both Mac and Linux attempting to open such a file fails.

Squeak has forceNewFileNamed: & forceNewFileNamed:do:.  If you look at sqFileOpen in platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c you'll see it first attempts to open read-write and if that fails, opens write-only.  So it should work.

HTH

For example, if you create a write-only file, i.e. in a shell, after cd to default directory

echo nada > foo
chmod 200 foo

Then from Squeak

StandardFileStream fileNamed: 'foo'

returns nil.

If the file is given read permission (i.e. chmod 600 foo) then Squeak can open it.

Anyone know a workaround?

Thanks,
Doug


--
best,
Eliot











smime.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [Vm-dev] Re: [squeak-dev] opening a write-only file

David T. Lewis
On Thu, Jun 05, 2014 at 06:50:31PM +0200, Bert Freudenberg wrote:

>  
>
> On 04.06.2014, at 18:19, Douglas McPherson <[hidden email]> wrote:
>
> > Hi All,
> >
> > I've tested a fix for this on OS X and Linux. The fix simply adds an extra attempt to open the file after the "w+b" attempt using this code:
> >
> >          if (getFile(f) == NULL) {
> >             setFile(f, fopen(cFileName, "wb"));
> >          }
> >
> > If the previous attempts to open the file failed (because the file exists with write-only permission, no read permission) then the above will actually open the file write-only. Adding the extra attempt preserves existing behaviour for the success paths, so the change should be transparent to existing code.
> >
> > BTW, AFAICT the same issue exists in Pharo.
> >
> > Thoughts?
> >
> > Doug
>
> Sounds reasonable to me.
>
> - Bert -

I have not tested it yet, but I think that this would truncate an existing file,
so that if the write-only file exists and contains data, the data would be lost.

Doug, could you check this with your patched VM?

Thanks,
Dave

>
>
> >
> >
> > On Jun 1, 2014, at 19:44 , Douglas McPherson wrote:
> >
> >> It turns out #forceNewFileNamed: does not work either.
> >>
> >> I believe the immediate cause of the problem is in the function you pointed me at: sqFileOpen() in platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c:
> >>
> >> if (writeFlag) {
> >> /* First try to open an existing file read/write: */
> >> setFile(f, fopen(cFileName, "r+b"));
> >> if (getFile(f) == NULL) {
> >> /* Previous call fails if file does not exist. In that case,
> >>   try opening it in write mode to create a new, empty file.
> >> */
> >> setFile(f, fopen(cFileName, "w+b"));
> >> if (getFile(f) != NULL) {
> >>    char type[4],creator[4];
> >> dir_GetMacFileTypeAndCreator(sqFileName, sqFileNameSize, type, creator);
> >> if (strncmp(type,"BINA",4) == 0 || strncmp(type,"????",4) == 0 || *(int *)type == 0 )
> >>    dir_SetMacFileTypeAndCreator(sqFileName, sqFileNameSize,"TEXT","R*ch");
> >> }
> >> }
> >>
> >> The first call to fopen() indeed fails if the file does not exist. But it also fails if the file exists but does not have both read and write "r+b" permission. So in that case the intent, as you mentioned, is to try to open in write-only but "w+b" is not the write-only mode, it is also a read and write mode, see [1]. So this fopen() attempt also fails if the file has write-only permission. A fix may be to use mode "wb" instead of "w+b", but I'm not sure if there are unintended consequences to doing this.
> >>
> >> [1] http://en.wikibooks.org/wiki/C_Programming/C_Reference/stdio.h/fopen   
> >>
> >> On May 31, 2014, at 14:45 , Douglas McPherson wrote:
> >>
> >>> Ahh, thanks. I'll try it out when back in front of my machine.
> >>>
> >>> Thanks,
> >>> Doug
> >>>
> >>> Sent from my iPhone
> >>>
> >>> On May 31, 2014, at 14:23, Eliot Miranda <[hidden email]> wrote:
> >>>
> >>>> Hi Doug,
> >>>>
> >>>>
> >>>> On Sat, May 31, 2014 at 10:00 AM, Douglas McPherson <[hidden email]> wrote:
> >>>> Is there a way to open a write-only file in Squeak? On both Mac and Linux attempting to open such a file fails.
> >>>>
> >>>> Squeak has forceNewFileNamed: & forceNewFileNamed:do:.  If you look at sqFileOpen in platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c you'll see it first attempts to open read-write and if that fails, opens write-only.  So it should work.
> >>>>
> >>>> HTH
> >>>>
> >>>> For example, if you create a write-only file, i.e. in a shell, after cd to default directory
> >>>>
> >>>> echo nada > foo
> >>>> chmod 200 foo
> >>>>
> >>>> Then from Squeak
> >>>>
> >>>> StandardFileStream fileNamed: 'foo'
> >>>>
> >>>> returns nil.
> >>>>
> >>>> If the file is given read permission (i.e. chmod 600 foo) then Squeak can open it.
> >>>>
> >>>> Anyone know a workaround?
> >>>>
> >>>> Thanks,
> >>>> Doug
> >>>>
> >>>>
> >>>> --
> >>>> best,
> >>>> Eliot
> >>>>
> >>>
> >>
> >>
> >
> >
>
>
>




Reply | Threaded
Open this post in threaded view
|

Re: [Vm-dev] [squeak-dev] opening a write-only file

douglas mcpherson

On Jun 5, 2014, at 21:03 , David T. Lewis wrote:

> On Thu, Jun 05, 2014 at 06:50:31PM +0200, Bert Freudenberg wrote:
>>
>>
>> On 04.06.2014, at 18:19, Douglas McPherson <[hidden email]> wrote:
>>
>>> Hi All,
>>>
>>> I've tested a fix for this on OS X and Linux. The fix simply adds an extra attempt to open the file after the "w+b" attempt using this code:
>>>
>>>         if (getFile(f) == NULL) {
>>>            setFile(f, fopen(cFileName, "wb"));
>>>         }
>>>
>>> If the previous attempts to open the file failed (because the file exists with write-only permission, no read permission) then the above will actually open the file write-only. Adding the extra attempt preserves existing behaviour for the success paths, so the change should be transparent to existing code.
>>>
>>> BTW, AFAICT the same issue exists in Pharo.
>>>
>>> Thoughts?
>>>
>>> Doug
>>
>> Sounds reasonable to me.
>>
>> - Bert -
>
> I have not tested it yet, but I think that this would truncate an existing file,
> so that if the write-only file exists and contains data, the data would be lost.
>
> Doug, could you check this with your patched VM?
>
> Thanks,
> Dave
>

Hi Dave,

Yes you are right, I didn't think of that. That is indeed what happens.

We could use "ab" instead of "wb" to get append behaviour if the file already exists. I think "a" is still a write-only mode. This is probably safer.

The larger issue of course is that FileStream and its subclasses have no protocol for the user to specifically request opening of a a write-only file, whether in append mode or overwrite mode. Currently all files that are opened must have at least read permission. Should we add something?  If so, any suggestions? I'm ok with the simple tweak above rather than adding new protocol, though it is really a hack.

Thanks,
Doug





>>
>>
>>>
>>>
>>> On Jun 1, 2014, at 19:44 , Douglas McPherson wrote:
>>>
>>>> It turns out #forceNewFileNamed: does not work either.
>>>>
>>>> I believe the immediate cause of the problem is in the function you pointed me at: sqFileOpen() in platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c:
>>>>
>>>> if (writeFlag) {
>>>> /* First try to open an existing file read/write: */
>>>> setFile(f, fopen(cFileName, "r+b"));
>>>> if (getFile(f) == NULL) {
>>>> /* Previous call fails if file does not exist. In that case,
>>>>   try opening it in write mode to create a new, empty file.
>>>> */
>>>> setFile(f, fopen(cFileName, "w+b"));
>>>> if (getFile(f) != NULL) {
>>>>    char type[4],creator[4];
>>>> dir_GetMacFileTypeAndCreator(sqFileName, sqFileNameSize, type, creator);
>>>> if (strncmp(type,"BINA",4) == 0 || strncmp(type,"????",4) == 0 || *(int *)type == 0 )
>>>>    dir_SetMacFileTypeAndCreator(sqFileName, sqFileNameSize,"TEXT","R*ch");
>>>> }
>>>> }
>>>>
>>>> The first call to fopen() indeed fails if the file does not exist. But it also fails if the file exists but does not have both read and write "r+b" permission. So in that case the intent, as you mentioned, is to try to open in write-only but "w+b" is not the write-only mode, it is also a read and write mode, see [1]. So this fopen() attempt also fails if the file has write-only permission. A fix may be to use mode "wb" instead of "w+b", but I'm not sure if there are unintended consequences to doing this.
>>>>
>>>> [1] http://en.wikibooks.org/wiki/C_Programming/C_Reference/stdio.h/fopen   
>>>>
>>>> On May 31, 2014, at 14:45 , Douglas McPherson wrote:
>>>>
>>>>> Ahh, thanks. I'll try it out when back in front of my machine.
>>>>>
>>>>> Thanks,
>>>>> Doug
>>>>>
>>>>> Sent from my iPhone
>>>>>
>>>>> On May 31, 2014, at 14:23, Eliot Miranda <[hidden email]> wrote:
>>>>>
>>>>>> Hi Doug,
>>>>>>
>>>>>>
>>>>>> On Sat, May 31, 2014 at 10:00 AM, Douglas McPherson <[hidden email]> wrote:
>>>>>> Is there a way to open a write-only file in Squeak? On both Mac and Linux attempting to open such a file fails.
>>>>>>
>>>>>> Squeak has forceNewFileNamed: & forceNewFileNamed:do:.  If you look at sqFileOpen in platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c you'll see it first attempts to open read-write and if that fails, opens write-only.  So it should work.
>>>>>>
>>>>>> HTH
>>>>>>
>>>>>> For example, if you create a write-only file, i.e. in a shell, after cd to default directory
>>>>>>
>>>>>> echo nada > foo
>>>>>> chmod 200 foo
>>>>>>
>>>>>> Then from Squeak
>>>>>>
>>>>>> StandardFileStream fileNamed: 'foo'
>>>>>>
>>>>>> returns nil.
>>>>>>
>>>>>> If the file is given read permission (i.e. chmod 600 foo) then Squeak can open it.
>>>>>>
>>>>>> Anyone know a workaround?
>>>>>>
>>>>>> Thanks,
>>>>>> Doug
>>>>>>
>>>>>>
>>>>>> --
>>>>>> best,
>>>>>> Eliot
>>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>>
>
>
>
>