<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Jun 6, 2014 at 9:33 AM, Douglas McPherson <span dir="ltr">&lt;<a href="mailto:djm1329@san.rr.com" target="_blank">djm1329@san.rr.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class=""><br>
<br>
On Jun 5, 2014, at 21:03 , David T. Lewis wrote:<br>
<br>
&gt; On Thu, Jun 05, 2014 at 06:50:31PM +0200, Bert Freudenberg wrote:<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; On 04.06.2014, at 18:19, Douglas McPherson &lt;<a href="mailto:djm1329@san.rr.com">djm1329@san.rr.com</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt;&gt; Hi All,<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; I&#39;ve tested a fix for this on OS X and Linux. The fix simply adds an extra attempt to open the file after the &quot;w+b&quot; attempt using this code:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;         if (getFile(f) == NULL) {<br>
&gt;&gt;&gt;            setFile(f, fopen(cFileName, &quot;wb&quot;));<br>
&gt;&gt;&gt;         }<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; 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.<br>

&gt;&gt;&gt;<br>
&gt;&gt;&gt; BTW, AFAICT the same issue exists in Pharo.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Thoughts?<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Doug<br>
&gt;&gt;<br>
&gt;&gt; Sounds reasonable to me.<br>
&gt;&gt;<br>
&gt;&gt; - Bert -<br>
&gt;<br>
&gt; I have not tested it yet, but I think that this would truncate an existing file,<br>
&gt; so that if the write-only file exists and contains data, the data would be lost.<br>
&gt;<br>
&gt; Doug, could you check this with your patched VM?<br>
&gt;<br>
&gt; Thanks,<br>
&gt; Dave<br>
&gt;<br>
<br>
</div>Hi Dave,<br>
<br>
Yes you are right, I didn&#39;t think of that. That is indeed what happens.<br>
<br>
We could use &quot;ab&quot; instead of &quot;wb&quot; to get append behaviour if the file already exists. I think &quot;a&quot; is still a write-only mode. This is probably safer.<br></blockquote><div><br></div><div>OK.  Then I propose to commit the following:</div>
<div><br></div><div>--- platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c (revision 2888)</div><div>+++ platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c (working copy)</div><div>@@ -245,6 +245,9 @@</div>
<div>                           try opening it in write mode to create a new, empty file.</div><div>                        */</div><div>                        setFile(f, fopen(cFileName, &quot;w+b&quot;));</div><div>+                       /* and if w+b fails, try ab (not wb which deletes read-only files) */</div>
<div>+                       if (getFile(f) == NULL)</div><div>+                               setFile(f, fopen(cFileName, &quot;ab&quot;));</div><div>                        if (getFile(f) != NULL) {</div><div>                            char type[4],creator[4];</div>
<div>                                dir_GetMacFileTypeAndCreator(sqFileName, sqFileNameSize, type, creator); </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<br>
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&#39;m ok with the simple tweak above rather than adding new protocol, though it is really a hack.<br>
</blockquote><div><br></div><div>IMO, some time we should replace the FilePlugin.  The directory interface sucks.   Buffering sucks.  We should go the VW route of having proper buffered files above the raw system calls (ReadFile &amp; WriteFile in win32/64, read &amp; write in unix et al).</div>
<div><br></div><div>Once we have ephemerons then closing buffered files through finalization is easier, cuz one can flush the buffer on the about-to-be-collcted file.  That means one can have a registry of open files and easily flush them before quit (ephemerons are fancy Associations).</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
Thanks,<br>
Doug<br>
<div class=""><div class="h5"><br>
<br>
<br>
<br>
<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; On Jun 1, 2014, at 19:44 , Douglas McPherson wrote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; It turns out #forceNewFileNamed: does not work either.<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; I believe the immediate cause of the problem is in the function you pointed me at: sqFileOpen() in platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c:<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;    if (writeFlag) {<br>
&gt;&gt;&gt;&gt;            /* First try to open an existing file read/write: */<br>
&gt;&gt;&gt;&gt;            setFile(f, fopen(cFileName, &quot;r+b&quot;));<br>
&gt;&gt;&gt;&gt;            if (getFile(f) == NULL) {<br>
&gt;&gt;&gt;&gt;                    /* Previous call fails if file does not exist. In that case,<br>
&gt;&gt;&gt;&gt;                       try opening it in write mode to create a new, empty file.<br>
&gt;&gt;&gt;&gt;                    */<br>
&gt;&gt;&gt;&gt;                    setFile(f, fopen(cFileName, &quot;w+b&quot;));<br>
&gt;&gt;&gt;&gt;                    if (getFile(f) != NULL) {<br>
&gt;&gt;&gt;&gt;                        char type[4],creator[4];<br>
&gt;&gt;&gt;&gt;                            dir_GetMacFileTypeAndCreator(sqFileName, sqFileNameSize, type, creator);<br>
&gt;&gt;&gt;&gt;                            if (strncmp(type,&quot;BINA&quot;,4) == 0 || strncmp(type,&quot;????&quot;,4) == 0 || *(int *)type == 0 )<br>
&gt;&gt;&gt;&gt;                                dir_SetMacFileTypeAndCreator(sqFileName, sqFileNameSize,&quot;TEXT&quot;,&quot;R*ch&quot;);<br>
&gt;&gt;&gt;&gt;                    }<br>
&gt;&gt;&gt;&gt;            }<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; 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 &quot;r+b&quot; permission. So in that case the intent, as you mentioned, is to try to open in write-only but &quot;w+b&quot; 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 &quot;wb&quot; instead of &quot;w+b&quot;, but I&#39;m not sure if there are unintended consequences to doing this.<br>

&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; [1] <a href="http://en.wikibooks.org/wiki/C_Programming/C_Reference/stdio.h/fopen" target="_blank">http://en.wikibooks.org/wiki/C_Programming/C_Reference/stdio.h/fopen</a><br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; On May 31, 2014, at 14:45 , Douglas McPherson wrote:<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; Ahh, thanks. I&#39;ll try it out when back in front of my machine.<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; Thanks,<br>
&gt;&gt;&gt;&gt;&gt; Doug<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; Sent from my iPhone<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; On May 31, 2014, at 14:23, Eliot Miranda &lt;<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>&gt; wrote:<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt; Hi Doug,<br>
&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt; On Sat, May 31, 2014 at 10:00 AM, Douglas McPherson &lt;<a href="mailto:djm1329@san.rr.com">djm1329@san.rr.com</a>&gt; wrote:<br>
&gt;&gt;&gt;&gt;&gt;&gt; Is there a way to open a write-only file in Squeak? On both Mac and Linux attempting to open such a file fails.<br>
&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt; Squeak has forceNewFileNamed: &amp; forceNewFileNamed:do:.  If you look at sqFileOpen in platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c you&#39;ll see it first attempts to open read-write and if that fails, opens write-only.  So it should work.<br>

&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt; HTH<br>
&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt; For example, if you create a write-only file, i.e. in a shell, after cd to default directory<br>
&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt; echo nada &gt; foo<br>
&gt;&gt;&gt;&gt;&gt;&gt; chmod 200 foo<br>
&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt; Then from Squeak<br>
&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt; StandardFileStream fileNamed: &#39;foo&#39;<br>
&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt; returns nil.<br>
&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt; If the file is given read permission (i.e. chmod 600 foo) then Squeak can open it.<br>
&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt; Anyone know a workaround?<br>
&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt; Thanks,<br>
&gt;&gt;&gt;&gt;&gt;&gt; Doug<br>
&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt; --<br>
&gt;&gt;&gt;&gt;&gt;&gt; best,<br>
&gt;&gt;&gt;&gt;&gt;&gt; Eliot<br>
&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>best,<div>Eliot</div>
</div></div>