[squeak-dev] FileDirectory fails

K K Subbu kksubbu.ml at gmail.com
Mon Jun 15 09:34:15 UTC 2020

On 15/06/20 3:08 am, Jakob Reschke wrote:
> Am So., 14. Juni 2020 um 20:21 Uhr schrieb K K Subbu <kksubbu.ml at gmail.com>:
>> On 14/06/20 7:27 pm, Jakob Reschke wrote:
>>> In my understanding and in most of the libraries I have seen, a path is
>>> a sequence of parts that mostly make up the directories and the last
>>> element is the name of either a file or a directory. You may represent
>>> the whole thing in a single string with a separator between the
>>> elements.
>> This hierarchical name space breaks down these days because of links and
>> bind mounts. On unix, names are just links to a file object. There can
>> be multiple links (within or even external to a filesystem). Therefore,
>> the interpretation '..' differs from system to system.
> So some of the path parts in the middle could actually be links,
> reparse points, or whatever. But should our VM or Squeak even care,
> unless we use a primitive for something like readlink? The OS resolves
> such things for us.

Precisely, path resolution should be in the OS.

>>> An agreement between image and plugin never to pass relative paths
>>> between each other could make sense to me. But I still don't see the
>>> value of distinguishing relative paths and incomplete paths, or how
>>> ./foo/bar would be any more or less ambiguous for further processing
>>> than just foo/bar. In both cases you need to know the startpoint (.) on
>>> both sides (image, plugin), or one side will not know what it is talking
>>> about.
>> If I pass "startup.st" as a document name to the VM,
>> primitiveFileOpen("startup.st", ...) has the option of resolving paths
>> by looking up a set of directories whereas if the path is given as
>> ./startup.st primitiveFileOpen("./startup.st", ...) has to look in CWD
>> only.
> Wait a minute, is that what you think it should be like, or is it how
> it is at the moment? The primitive could do anything of course, but in
> my opinion it must not use this "option", see further down. Also the
> primitive should ideally not get to see the path with ./ still in it.

The startup document path comes from the command line, so it is 
OS-specific. Therefore, it's path resolution will also be OS-specific.

>> Currently, FileDirectory forces "startup.st" to mean
>> imagePath/startup.st only, even if the vm is not started from the image
>> directory.
> As far as I understood, this is because the VM actually changes the
> CWD to the image's parent directory during startup. If it would not do
> that, this could behave differently, for example resolving startup.st
> relative to the invoking process's CWD (which is inherited).
This is a myth. I have no idea how this myth originated. Does the 
Windows port do it? The unix port doesn't change its working directory. 
You can check the process properties at /proc/$pid/environ to verify 
this. The image can also be saved in any directory. The VM does not 
switch its CWD to track the new path.
$ pwd
$ /opt/share/bin/sqlinux.68019/bin/squeak 
share/squeak/beeper.st &
[2] 15159
$ tr '\0' '\n' </proc/15159/environ | grep PWD

> I think we should not make ./startup.st and startup.st mean different
> things in Squeak because it would be highly confusing to everyone who
> has ever used a shell.

Any beginner who has tried to compile and run test.c will understand the 
difference anymore ;-). It was often used to prank unix beginners :-).

XDG has a whole specification to supply default paths for desktop, 
documents, pictures etc.

>> e.g. Suppose app/ contains startup.st bin/ and shared/. Then this will fail:
>>      app$ bin/squeak shared/squeak.image startup.st
> ...which is unexpected for the uninitiated user/developer as we saw in
> Christoph's question. I don't think that it is good behavior, it
> should work, not fail.
The document path is an argument. It could come from anywhere not 
necessarily from someone typing it on the command line. Insisting that 
it always be /.../startup.st or $IMAGEDIR/startup.st is burdensome. In 
fact, I burnt my fingers while testing the above code. It was loading an 
leftover startup.st in the image directory, not the one I specified on 
the command line.

>> The FileDirectory should just be a tuple (container, entry) and move all
>>    platform-specific stuff into FilePlugin.
> Sorry, I still fail to see how this representation would change
> anything about the situation or how it is related at all to the
> primitive interface. Could you explain what this representation
> implies in practice?

The FileDirectory just encapsulates a native store. A native store is 
modeled as a pair - an entry (which can be streamed) and an array of 
entries (container) accessed by entriesDo:. An entry can also be an 
array (returns true to isDirectory). That's it. This is the same pattern 
followed for reifications of other native resources.

I used the words entry and container so that these are not confused with 
OS objects like file, directory etc. These are not terms used in Squeak.

An analogy is how Display is modeled by DisplayScreen and plugins map 
this into the host's display implementation. Squeak doesn't pull in X11 
display server, framebuffer or Win32 GUI classes into the image.

I am not saying this is how it should be. It is just a proposal inspired 
by Squeak's design principles of simplicity and generality. They are 
open to debate, discussion and disposal.

>>> Subbu, you write about a platform-specific set of paths to look up. Do
>>> you mean resolving against environment variables such as $PATH?
>> Yes. Plugins can use env variables to guide path resolution.
> In my opinion, a FilePlugin implementation must not do this. Neither
> Linux open(2) nor Win32 OpenFile use a search path. Why should the
> VM/plugin introduce such intransparent behavior for basic file access

Because Squeak is a virtual machine, not a shell, and depends on the 
host for storage, display and other i/o services without pulling in 
implementations into the image.

>> The unix vm
>> already uses env variables like SQUEAK_VM, SQUEAK_IMAGE, SQUEAK_USERDIR
>> to avoid hard-coded paths in the image. This means Squeak applications
>> could place a startup document in, say, $HOME/.squeak/startup.st or
>> /etc/squeak/startup.st and have the image open it with just 'startup.st'
>> without hard-coding the full path.
> Is this already the case and applies to FileStream readOnlyFileNamed:?

No. But lazy binding of pathnames in executables is a long standing unix 
convention. Lazy binding is essential part of live programming. Stephen 
Kell talks about "Liberating the Smalltalk lurking in C and Unix" at 
https://youtu.be/LwicN2u6Dro (41 mins!).

>  From my image:
> FSLocator home asReference "=> C:\Users\Jakob"
> FSLocator home resolve: './foo' "=> {home}\foo (this is portable, as

This is essentially a command shell function. Pharo has become a command 
shell on the host, handling file globbing, tracking process properties 
(HOME, PWD etc.). It is a totally different topic.

Regards .. Subbu

More information about the Squeak-dev mailing list