Transput RFC - early version based on POSIX

Jose E. Marchesi jemarch@gnu.org
Thu May 21 21:39:35 GMT 2026


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
>
>> -- 
>> Chris Hermansen · clhermansen "at" gmail "dot" com
>>
>> C'est ma façon de parler.
>
> pietro


More information about the Algol68 mailing list