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