Transput RFC - early version based on POSIX
chris hermansen
clhermansen@gmail.com
Mon Jun 1 19:32:33 GMT 2026
Thanks, Jose.
I have "just one more little question" below...
On Thu, May 28, 2026 at 1:15 AM Jose E. Marchesi <jemarch@gnu.org> wrote:
>
> 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!
>
Following on with the idea of using POSIX:
int access(const char *path, int amode);
to determine whether my Channel access requirements are congruent with the
operating system file access permissions, I looked in gcc/libga68/posix.a68
to find:
pub proc(string,bits)int fopen = nest C "_libga68_posixfopen",
and then in gcc/libga68/ga68-posix.c to find:
int
_libga68_posixfopen (const uint32_t *pathname, size_t len, size_t stride,
unsigned int flags)
{
int fd;
int openflags = 0;
size_t u8len;
char *filepath = _libga68_u32_to_u8 (pathname, len, stride, &u8len);
/* Default mode: try read-write initially.
If that fails, then try read-only.
If that fails, then try write-only. */
if (flags == _libga68_file_o_default)
{
openflags = O_RDWR;
if ((fd = _libga68_open (filepath, openflags)) < 0)
{
openflags = O_RDONLY;
if ((fd = _libga68_open (filepath, openflags)) < 0)
{
openflags = O_WRONLY;
fd = _libga68_open (filepath, openflags);
_libga68_free_internal (filepath);
return fd;
}
}
_libga68_free_internal (filepath);
return fd;
}
if (flags & _libga68_file_o_rdonly)
openflags |= O_RDONLY;
if (flags & _libga68_file_o_wronly)
openflags |= O_WRONLY;
if (flags & _libga68_file_o_rdwr)
openflags |= O_RDWR;
if (flags & _libga68_file_o_trunc)
openflags |= O_TRUNC;
fd = _libga68_open (filepath, openflags);
_libga68_free_internal (filepath);
return fd;
}
But the declaration of _libga68_posixfopen does not seem to match the Algol
68 procedure that is the caller.
I hope one of you can enlighten me about this...
--
Chris Hermansen · clhermansen "at" gmail "dot" com
C'est ma façon de parler.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/algol68/attachments/20260601/097f03f5/attachment-0001.htm>
More information about the Algol68
mailing list