Transput RFC - early version based on POSIX
Jose E. Marchesi
jemarch@gnu.org
Thu May 28 08:15:37 GMT 2026
Hi Chris.
> Wow, I'm feeling so much better having the text for van Vliet's part 2 now
> (see my other email today).
>
> On Thu, May 21, 2026 at 2:42 PM Jose E. Marchesi <jemarch@gnu.org> wrote:
>
>>
>> The fstat interface involves a struct stat, which in principle would not
>> be a problem to interact directly using the Algol 68 FFI, because our
>> structs are like C structs ABI wise.
>>
>> However, it looks like:
>>
>> struct stat {
>> dev_t st_dev; /* ID of device containing file */
>> ino_t st_ino; /* Inode number */
>> mode_t st_mode; /* File type and mode */
>> nlink_t st_nlink; /* Number of hard links */
>> uid_t st_uid; /* User ID of owner */
>> gid_t st_gid; /* Group ID of owner */
>> dev_t st_rdev; /* Device ID (if special file) */
>> off_t st_size; /* Total size, in bytes */
>> blksize_t st_blksize; /* Block size for filesystem I/O */
>> blkcnt_t st_blocks; /* Number of 512 B blocks allocated */
>>
>> /* Since POSIX.1-2008, this structure supports nanosecond
>> precision for the following timestamp fields.
>> For the details before POSIX.1-2008, see VERSIONS. */
>>
>> struct timespec st_atim; /* Time of last access */
>> struct timespec st_mtim; /* Time of last modification */
>> struct timespec st_ctim; /* Time of last status change */
>>
>> #define st_atime st_atim.tv_sec /* Backward compatibility */
>> #define st_mtine st_mtim.tv_sec
>> #define st_ctime st_ctim.tv_sec
>> };
>>
>> And there are plenty of fields there that have different sizes depending
>> on target, system, etc. Even the signedness of some of these types may
>> no be fully defined by POSIX.
>>
>> So, in this case, we will need an intermediate C wrapper in ga68-posix.c
>> with definite types, something like:
>>
>> struct _ga68_stat
>> {
>> int st_uid;
>> int st_gid;
>> /* ... other fields we want. */
>> };
>>
>> Then the getter that translates from struct stat to struct _ga68_stat:
>>
>> int _ga68_fstat (struct _ga68_stat *stat)
>> {
>> /* Call fstat, translate from struct stat to struct _gat6*_stat */
>> }
>>
>> And then you can FFI this wrapper in libga68/posix.a68, something like:
>>
>> mode Stat = struct (int uid, gid, ...);
>>
>> pub fstat = (ref Stat stat): nest C "_ga68_fstat";
>>
>>
>> That should work. Of course tests shall be added to
>> libga68/configure.ac to check for the availability of stat, etc.
>>
>> > On Thu, May 21, 2026, at 1:39 PM, chris hermansen wrote:
>> >> Good morning everyone,
>> >>
>> >> Jose, thanks for the comments you provided. One more question below:
>> >> On Thu, May 21, 2026 at 2:16 AM Jose E. Marchesi <jemarch@gnu.org>
>> wrote:
>> >>>
>> >>> Hello Chris.
>> >>>
>> >>> > Good afternoon everyone,
>> >>> >
>> >>> > After monkeying around far too long trying to pull out bits of van
>> >>> > Vliet's transput so I could implement it piece by piece, I have
>> given up on
>> >>> > that approach (way too many dependencies between things in there)
>> and am
>> >>> > gritting my teeth and starting back at the beginning.
>> >>> >
>> >>> > To facilitate getting as much as possible working, I'd like to put
>> van
>> >>> > Vliet's code and ideas on top of Algol 68 POSIX for now, forgetting
>> about
>> >>> > reading and writing binary for the first go-around.
>> >>> >
>> >>> > Does that make sense?
>> >>>
>> >>> To me, it makes 100% sense. In my experience, once you get something
>> >>> working it becomes easier to reason about it. There is a lot to learn
>> >>> in the process too.
>> >>>
>> >>> > Assuming it's not too crazy an idea, the first bump on the road I've
>> >>> > encountered is dealing with system file status. As far as I can
>> tell, the
>> >>> > only pathway in Algol 68 POSIX for this type of thing is to call
>> fopen() or
>> >>> > fcreate() with various flags as documented here:
>> >>> >
>> >>> > https://gcc.gnu.org/onlinedocs/ga68/POSIX-files.html
>> >>> >
>> >>> > and then, based on what works and what doesn't, I can resolve many
>> of van
>> >>> > Vliet's "possibles":
>> >>> > - get_possible(f) { true if fopen(filename, bits file o rdonly)
>> returns ≥ 0
>> >>> > }
>> >>> > - put_possible(f) { true if fopen(filename, bits file o wronly)
>> returns ≥ 0
>> >>> > }
>> >>> > - bin_possible(f) { always false for now }
>> >>> > - compressible(f) { always true - indicates variable length lines }
>> >>> > - reset_possible(f) { always true for now }
>> >>> > - set_possible(f) { always true for now because lseek() }
>> >>> > - backspace_possible(f) { always true for now because lseek() }
>> >>> > - reidf_possible(f) { always false for now because Algol 68 transput
>> >>> > doesn't provide rename() }
>> >>> >
>> >>> > Does this sound like an acceptable start?
>> >>>
>> >>> I think it would be better to call to the system's fstat, a wrapper for
>> >>> which needs to be added to the POSIX prelude.
>> >>
>> >> Are you suggesting here that (gasp) I add this in and create a patch?
>> >>
>> >> Am I too old a dog to learn a new trick?
>> >
>> > Since Jose added support for writing libga68 preludes in Algol 68 this
>> became much easier.
>> > If it's an easy mapping from C you just need to add it to
>> libga68/posix.a68.
>> > If not, you need a add a C wrapper in libga68/ga68-posix.c and then in
>> libga68/posix.a68.
>> >
>> > Don't forget to add docs in gcc/algol68/ga68.texi and tests in
>> gcc/testsuite/algol68/compile
>> > or gcc/testsuite/algol68/execute
>>
>> Not ready to create a patch yet!
>
> But reading van Vliet (as opposed to studying his code) I see this comment
> on p. 21 of
>
> ALGOL 68 TRANSPUT PART II: AN IMPLEMENTATION MODEL
>
> "The access properties of a book opened via such a channel are obtained by
> the intersection of the properties of the book and the channel. For
> example, reading is possible if both the book and the channel allow reading"
>
> So fstat - not to start a big argument, but I think it's wrong because it
> uses a file descriptor, meaning (says me) the file has to be open first.
Oh ok.
> Therefore, I think I want to implement Algol 68 open as:
>
> 1. figure out what the Channel wants - read? write? both? binary? not
> binary? etc?
> 2. translate the Channel 'wants' into a POSIX "mode"
Yep.
> 3. use the POSIX routine access(idf, mode) to see if I can do what the
> Channel wants to the operating system file
Yep.
> 4. assuming all is good, then use POSIX routine fopen(idf, mode) to open
> the file
Yep.
> 5. put the file descriptor and other stuff in the File structure and maybe
> some stuff in the Book structure
Makes sense.
> One of the things I don't believe to be necessary in the whole Algol 68
> transput, so long as we are basing it on POSIX anyway, is all the Buffer
> stuff that van Vliet sets up; instead we can use his procedures write_char,
> write_bin_char, read_char, read_bin_char (that are copied from the Channel
> to the File when it is successfully opened) to call POSIX fputc(),
> something for binary, fgetc(), something for binary.
The POSIX f* functions are buffered themselves, so it makes sense to me,
to not replicate the buffering at the Transput level.
> Here I say "something" because for now I'm ignoring binary but I'm pretty
> sure I will need some other pair of POSIX functions to handle the stuff van
> Vliet refers to as BINCHAR.
>
> Maybe we can even replace his procedure components of File with the POSIX
> routines.
>
> Hoping for more comments here!
More information about the Algol68
mailing list