Monday, September 29, 2008

enumerateDirectory recursively

I've just checked in a revision to org.icongarden.fileSystem.enumerateDirectory which takes one or two parameters. The first argument is the same as before, and the second optional argument is a boolean indicating whether the caller wishes the method to descend into child directories. If so, then each returned object whose property type has the value "directory" will have an additional property children whose value is an array of zero or more objects with the same set of properties as its parent.

debut enumerateDirectory and some housekeeping

I've just checked in the method org.icongarden.fileSystem.enumerateDirectory. Like its sibling setWorkingDirectory, it takes a single parameter which must be an array of pathname components as returned by its sibling getWorkingDirectory. It returns an array of directory entry names objects whose properties name, type, and inode describe each directory entry. If I end up supporting Windows, inode won't be present. type has one of the following values:
  • (unknown to extension)
  • (unknown to system)
  • regular file
  • directory
  • named pipe
  • socket
  • character device
  • block device
  • symbolic link
On Windows, not all of these will be possibilities.

I've retired org.icongarden.workingDirectory, and org.icongarden.fileSystem will have a much broader scope. I always intended to have a org.icongarden.fileSystem; I don't know why I got distracted with org.icongarden.workingDirectory.

I also tweaked the way exceptions are thrown in C++ so it's easier to "demand" that conditions be true in a way which causes a JavaScript exception if they're not. Making this super-convenient is key to actually doing it often enough to be useful to JavaScript programmers.

getWorkingDirectory and setWorkingDirectory

I did end up exposing the working directory as an array of strings as planned. However, I found the syntax for exposing that array directly to be ugly and awkward and confusing and cumbersome, so I opted for a pair of methods, org.icongarden.fileSystem.getWorkingDirectory and org.icongarden.fileSystem.setWorkingDirectory. If the first array element is empty, it means the array represents an absolute ("full") path; I expect to use this convention elsewhere within this particular extension. getWorkingDirectory always returns an absolute path, but you can pass a relative path to setWorkingDirectory and it will figure out the right thing to do. Neither of these functions handles duplicate slashes or "..", since they are unneeded; these conventions result from storing paths as strings (which is wrong, in my view). I'll probably end up having to deal with these cases eventually anyway for the sake of compatibility.

Sunday, September 28, 2008

fork on Win32

I got some questions in a chat room the other day which prompted me to realize I'm using fork in a way that's completely within specification but uncommon. I decided I had better understand fork on Windows before going too much farther. And it looks as if I'm screwed.

Most people call fork as a means to an end. They want to start another process or they want some concurrency. I call fork as an end in itself; I want precisely what it does, no more and no less. I want a clone of the current process, including the address space, so I can drop privileges and run to completion as a regular (non-root) user.

It turns out Windows doesn't support fork. At all.

If you're one of those people who call fork as a means to an end, you have alternatives. If you were just going to call exec after fork, then replace both calls with CreateProcess. If you just wanted some concurrency, then call CreateThread instead.

But I'm not one of those people. I actually want fork to fork. So I'm screwed.

The question now is what to do about it. Do I abandon support for Windows? Or do I re-architect into separate processes? I am frankly leaning toward ditching Windows support, since I would never in a million years use it myself, and since fork is super-cheap on Linux, which is key support for being able to claim Counterpart is fast.

Update: It seems silly to kick Windows to the curb just because I'll have to write some different engine code that will be slower. The valuable code is the extensions. At worst, the Windows implementation can be a regular CGI program, and someone who cares enough will come along and figure out how to make it fast. That someone might even be me.

rethought workingDirectory

Overnight, I rethought how workingDirectory should work. One of my big-picture goals here is to expose things in a way which will make sense to JavaScript programmers rather than C++ programmers. To that end, I think the current working directory should be exposed as an array of pathname components rather than a set of functions. This will not only eliminate the need to understand platform differences but will also provide a single point of interface. I will need to figure out how to convince V8 to watch for changes to this array after I expose it, but I suspect that's mostly a matter of research rather than development. The enumerate functionality shouldn't be strongly associated with working directories. I think I'll probably go back to fleshing out org.icongarden.fileSystem.

Saturday, September 27, 2008

debut org.icongarden.workingDirectory

I haven't had much time to work on Counterpart lately, but I did get a few hours this afternoon to throw at it, and I've checked in the beginning of the org.icongarden.workingDirectory extension. For now, it has two methods:
  • get returns a string containing a native path to the current working directory.
  • enumerate returns an array containing the names of the directory entries contained by the current working directory. In the near feature, this array will contain objects instead of strings, and each object will describe various other aspects of the corresponding directory entry, such as its type and its modification date.
Both these methods trust the environment variable PWD if it's present, which is normally the case because Counterpart sets it just before calling user scripts. However, if it's not set, these methods will figure out what it ought to be and set it before returning so they will run faster in the future. Once I finish enumerate, I plan to add two more methods.
  • descend changes the working directory to the child of the current working directory specified in its single parameter.
  • ascend changes the working directory to the parent of the current working directory.
This should be enough for the kinds of server-side scripts I have written in the past. The super-simple API is designed to insulate the client programmer from having to know too much about how file systems on specific platforms are organized.

These methods are implemented in C++. I may eventually build a script-based front end to them which knows how to explore file systems and/or represent paths (without separator characters, of course).

logo

project logo
Above is the logo for the project. I posted it here in hopes of being able to refer to it from the project site, but it appears that does not work; perhaps blogspot denies hot-linking. In any case, it's now archived here in case I get run over by a truck.