Fuzion Logo
fuzion-lang.dev — The Fuzion Language Portal
JavaScript seems to be disabled. Functionality is limited.

io/file/stat.fz


# This file is part of the Fuzion language implementation.
#
# The Fuzion language implementation is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, version 3 of the License.
#
# The Fuzion language implementation is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License along with The
# Fuzion language implementation.  If not, see <https://www.gnu.org/licenses/>.


# -----------------------------------------------------------------------
#
#  Tokiwa Software GmbH, Germany
#
#  Source code of Fuzion standard library feature stat
#
#  Author: Wael Youssfi (wael.youssfi@tokiwa.software)
#
# -----------------------------------------------------------------------

# meta_data will be a feature storing the metadata of file/dir
#
private:public meta_data(
          public path path,
          # the size of the file/dir
          public size i64,
          # the time of last access to the path
          # (or some other timestamp when filesystem mounted with noatime)
          public atime i64,
          # the time of last modification of the file/dir
          public mtime i64,
          # the time of creation of the path
          public ctime i64,
          # boolean to check if the pathname is a regular file
          public is_regular bool,
          # boolean to check if the pathname is a directory
          public is_dir bool,
          # is the path a symlink
          public is_link bool,
          # owner of the path
          public uid i64,
          # group of the path
          public gid i64
          )
    pre debug: path.is_absolute
  is

  public redef as_string String =>
    """
      path              : $path
      size in bytes     : $size
      access time       : {universe.time.date_time.from_seconds meta_data.this.atime.as_u64}
      modification time : {universe.time.date_time.from_seconds meta_data.this.mtime.as_u64}
      creation time     : {universe.time.date_time.from_seconds meta_data.this.ctime.as_u64}
      is regular file   : $is_regular
      is directory      : $is_dir
      is link           : $is_link
      user id           : $uid
      group id          : $gid"""

# stat -- effect providing operations to retrieve file stats
#
public stat(ps Stat_Handler) : effect is

  # returns stats of the file/dir passed in the pathname
  # in success it will return a meta_data outcome storing stats regarding the file/dir
  # in case of failure an error will be returned
  # this feature resolves symbolic links
  #
  public stats(
        # the (relative or absolute) file name, using platform specific path separators
        path path) outcome meta_data =>
    replace
    # will contain: [size, time of last modification in seconds, regular file? 1 : 0, dir? 1 : 0]
    res := fuzion.sys.internal_array_init i64 9
    if ps.stats (fuzion.sys.c_string path.as_platform_string) res.data = 0
      path.as_absolute.bind p->
        meta_data p res[0] res[1] res[2] res[3] (res[4] = 1) (res[5] = 1) (res[6] = 1) res[7] res[8]
    else
      error "stat error {res[0]} for {path}"

  # returns stats of the file/dir passed in the pathname
  # in success it will return a meta_data outcome storing stats regarding the file/dir
  # in case of failure an error will be returned
  # this feature does not resolve symbolic links and returns stats of the link itself
  #
  public lstats(
         # the (relative or absolute) file name, using platform specific path separators
         path path) outcome meta_data => # NYI: UNDER DEVELOPMENT: : not sure whether to use meta_data or introduce a new feature for lstats metadata
    replace
    # will contain: [size, time of last modification in seconds, regular file? 1 : 0, dir? 1 : 0]
    res := fuzion.sys.internal_array_init i64 9
    if ps.lstats (fuzion.sys.c_string path.as_platform_string) res.data = 0
      path.as_absolute.bind p->
        meta_data p res[0] res[1] res[2] res[3] (res[4] = 1) (res[5] = 1) (res[6] = 1) res[7] res[8]
    else
      error "lstat error {res[0]} for {path}"



# install default effect io.file.stat
#
install_default =>
  (stat default_stat_handler).default



# the default file stat provided
#
default_stat_handler : Stat_Handler is
  redef stats(path Array u8, meta_data_arr Array i64) =>
    fzE_stat path meta_data_arr

  redef lstats(path Array u8, meta_data_arr Array i64) =>
    fzE_lstat path meta_data_arr



# shorthand for accessing the stat effect in current environment
#
public stat stat ! stat =>
  install_default
  stat.env


# shorthand for accessing and using stats/lstats provided by the stat effect in current environment
# in success it will return a meta_data outcome storing stats regarding the file/dir
# in case of failure an error will be returned
# resolve flag is used to indicate whether to resolve sym links or not
# NYI: lstats behaves the same as stats in the interpreter
#
public stat(
     # the (relative or absolute) file name, using platform specific path separators
     path path,
     # a boolean resolve flag to resolve symbolic links or not
     resolve bool) outcome meta_data ! stat =>
  install_default
  if resolve
    stat.env.stats path
  else
    stat.env.lstats path


# reference to the stats that could be provided
#
private:public Stat_Handler ref is
  stats(path Array u8, meta_data_arr Array i64) i32 => abstract
  lstats(path Array u8, meta_data_arr Array i64) i32 => abstract

last changed: 2026-04-02