PreviousUpNext

15.3.527  src/lib/std/src/psx/posix-io.api

## posix-io.api
#
# Api for POSIX 1003.1 primitive I/O operations

# Compiled by:
#     src/lib/std/src/standard-core.sublib




###        "We tried to avoid, you know, records.
###         We were told over and over that was
###         probably the most serious mistake
###         and was the reason the system would never
###         catch on, because we didn't have records."
###
###                           -- Ken Thompson



###        "Where will wants not,
###           a way opens."
###
###                -- Eowyn
###
###                   [J.R.R. Tolkein, "Lord of the Rings"]


stipulate
    package hu  =  host_unt_guts;                                                               # host_unt_guts                                 is from   src/lib/std/src/bind-sysword-32.pkg
    package hi  =  host_int;                                                                    # host_int                                      is from   src/lib/std/src/psx/host-int.pkg
    package pos =  file_position;                                                               # file_position                                 is from   src/lib/std/types-only/bind-position-31.pkg
    package ru  =     vector_of_one_byte_unts;                                                  #    vector_of_one_byte_unts                    is from   src/lib/std/src/vector-of-one-byte-unts.pkg
    package ti  =  tagged_int;                                                                  # tagged_int                                    is from   src/lib/std/types-only/basis-structs.pkg
    package wu  =  rw_vector_of_one_byte_unts;                                                  # rw_vector_of_one_byte_unts                    is from   src/lib/std/src/rw-vector-of-one-byte-unts.pkg
herein

    # This api is implemented in:
    #
    #     src/lib/std/src/psx/posix-io.pkg
    #
    api Posix_Io {
        #
        eqtype File_Descriptor;
        eqtype Process_Id;

        make_pipe:                              Void -> { infd:  File_Descriptor, outfd:  File_Descriptor };            # For named pipes ("fifos") see make_named_pipe in src/lib/std/src/psx/posix-file.api
        make_pipe__without_syscall_redirection: Void -> { infd:  File_Descriptor, outfd:  File_Descriptor };            # Use this in secondary hostthreads like src/lib/std/src/hostthread/io-wait-hostthread

        dup:  File_Descriptor -> File_Descriptor;

        dup2:                               { old:  File_Descriptor, new:  File_Descriptor } -> Void;
        dup2__without_syscall_redirection:  { old:  File_Descriptor, new:  File_Descriptor } -> Void;

        close:                                  File_Descriptor -> Void;
        close__without_syscall_redirection:     File_Descriptor -> Void;                                                # Use this in secondary hostthreads like src/lib/std/src/hostthread/io-wait-hostthread

        copy_file:                              { from: String, to: String } -> Int;                                    # Strings are filenames.  Return value is total bytes copied.  Copy will have same mode as original.

        file_contents_are_identical:            (String, String) -> Bool;                                               # Returns TRUE iff the files are byte-for-byte identical.

        read_as_vector:   { file_descriptor: File_Descriptor,  max_bytes_to_read: Int } -> vector_of_one_byte_unts::Vector;
        read_into_buffer: { file_descriptor: File_Descriptor,  read_buffer: rw_vector_slice_of_one_byte_unts::Slice } -> Int;

        stdout_redirect:    Ref (Null_Or( String -> Void ));
        stderr_redirect:    Ref (Null_Or( String -> Void ));
                        
        write_string:     (File_Descriptor, String)                                  -> Int;                            # Return value is bytes_written.
        write_vector:     (File_Descriptor,    vector_slice_of_one_byte_unts::Slice) -> Int;                            # Return value is bytes_written.
        write_rw_vector:  (File_Descriptor, rw_vector_slice_of_one_byte_unts::Slice) -> Int;                            # Return value is bytes_written.



        read_as_vector__without_syscall_redirection:   { file_descriptor: File_Descriptor,  max_bytes_to_read: Int } -> vector_of_one_byte_unts::Vector;                # Use this in secondary hostthreads like src/lib/std/src/hostthread/io-wait-hostthread
        read_into_buffer__without_syscall_redirection: { file_descriptor: File_Descriptor,  read_buffer: rw_vector_slice_of_one_byte_unts::Slice } -> Int;              # Use this in secondary hostthreads like src/lib/std/src/hostthread/io-wait-hostthread

        write_vector__without_syscall_redirection:     (File_Descriptor,    vector_slice_of_one_byte_unts::Slice) -> Int;                                               # Use this in secondary hostthreads like src/lib/std/src/hostthread/io-wait-hostthread
        write_rw_vector__without_syscall_redirection:  (File_Descriptor, rw_vector_slice_of_one_byte_unts::Slice) -> Int;                                               # Use this in secondary hostthreads like src/lib/std/src/hostthread/io-wait-hostthread
            #
            # We need these four because when microthread-preemptive-scheduler.pkg is running
            # and syscall redirection is in effect write_vector and write_rw_vector
            # cannot be used from support hostthreads like that in io-wait because
            # redirection depends upon microthread support, which only works in
            # the main hostthread.



        Whence = SEEK_SET | SEEK_CUR | SEEK_END;

        package fd:     api {
                            include api Bit_Flags;              # Bit_Flags     is from   src/lib/std/src/bit-flags.api
                            #
                            cloexec:  Flags;            # == C FD_CLOEXEC       "If the FD_CLOEXEC bit is 0, the file descriptor will remain open across an execve(2), otherwise it will be closed." -- fcntl(2) manpage.
                        };

        package flags:  api {
                            include api Bit_Flags;              # Bit_Flags     is from   src/lib/std/src/bit-flags.api
                            #
                            append:    Flags;           # O_APPEND
                            nonblock:  Flags;           # O_NONBLOCK
                            sync:      Flags;

                            #  Lib7-isms(?): 
                            rsync:     Flags;
                            dsync:     Flags;
                        };

    #    include api Posix_Common;

        dupfd:  { old:  File_Descriptor, base:  File_Descriptor } -> File_Descriptor;

        getfd:   File_Descriptor -> fd::Flags;                                          # == C fcntl(arg, F_GETFD);

        setfd:                               (File_Descriptor, fd::Flags) -> Void;
        setfd__without_syscall_redirection:  (File_Descriptor, fd::Flags) -> Void;

        getfl:   File_Descriptor -> (flags::Flags, posix_file::Open_Mode);
        setfl:  (File_Descriptor,    flags::Flags) -> Void;                             # "On Linux this command can only change the O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, and O_NONBLOCK flags." -- fcntl(2)


        lseek:  (File_Descriptor, pos::Int, Whence) -> pos::Int;

        fsync:  File_Descriptor -> Void;

        Lock_Type = F_RDLCK | F_WRLCK | F_UNLCK;

        package flock:      api {
                                Flock;

                                flock
                                    :
                                    { locktype: Lock_Type,
                                      whence:   Whence,
                                      start:    pos::Int,
                                      len:      pos::Int,
                                      pid:      Null_Or( Process_Id )
                                    }
                                    ->
                                    Flock;

                                locktype:       Flock -> Lock_Type;
                                whence:         Flock -> Whence;
                                start:          Flock -> pos::Int;
                                len:            Flock -> pos::Int;
                                pid:            Flock -> Null_Or( Process_Id );
                            };

         getlk:   (File_Descriptor, flock::Flock) -> flock::Flock;
         setlk:   (File_Descriptor, flock::Flock) -> flock::Flock;
         setlkw:  (File_Descriptor, flock::Flock) -> flock::Flock;


         make_data_filereader:    { file_descriptor:    File_Descriptor,                        # "data" == "binary"
                                    filename:           String,
                                    ok_to_block:        Bool                                    # Initial value for ok_to_block stateflag. We will do nonblocking I/O whenever it is FALSE.
                                  }
                                  ->
                                  winix_base_data_file_io_driver_for_posix__premicrothread::Filereader;

         make_text_filereader:    { file_descriptor:    File_Descriptor,
                                    filename:           String,
                                    ok_to_block:        Bool                                    # Initial value for ok_to_block stateflag. We will do nonblocking I/O whenever it is FALSE.
                                  }
                                  ->
                                  winix_base_text_file_io_driver_for_posix__premicrothread::Filereader;

         make_data_filewriter:    { file_descriptor:    File_Descriptor,                        # "data" == "binary"
                                    filename:           String,
                                    append_mode:        Bool,
                                    ok_to_block:        Bool,                                   # Initial value for ok_to_block stateflag. We will do nonblocking I/O whenever it is FALSE.
                                    best_io_quantum:    Int
                                  }
                                  ->
                                  winix_base_data_file_io_driver_for_posix__premicrothread::Filewriter;

         make_text_filewriter:    { file_descriptor:    File_Descriptor,
                                    filename:           String,
                                    append_mode:        Bool,
                                    ok_to_block:        Bool,                                   # Initial value for ok_to_block stateflag. We will do nonblocking I/O whenever it is FALSE.
                                    best_io_quantum:    Int
                                  }
                                  ->
                                  winix_base_text_file_io_driver_for_posix__premicrothread::Filewriter;



        #######################################################################
        # Below stuff is intended only for one-time use during
        # booting, to switch from direct to indirect syscalls:                                  # For background see Note[1]            in   src/lib/std/src/unsafe/mythryl-callable-c-library-interface.pkg

        Sy_Int = hi::Int;
        Sy_Unt = hu::Unt;

             osval2__syscall:    String -> Sy_Int;
        set__osval2__ref:      ({ lib_name: String, fun_name: String, io_call: (String -> Sy_Int) } -> (String -> Sy_Int)) -> Void;

             make_pipe__syscall:    Void -> (Sy_Int, Sy_Int);
        set__make_pipe__ref:      ({ lib_name: String, fun_name: String, io_call: (Void -> (Sy_Int, Sy_Int)) } -> (Void -> (Sy_Int, Sy_Int))) -> Void;

             dup__syscall:    Sy_Int -> Sy_Int;
        set__dup__ref:      ({ lib_name: String, fun_name: String, io_call: (Sy_Int -> Sy_Int) } -> (Sy_Int -> Sy_Int)) -> Void;

             dup2__syscall:    (Sy_Int, Sy_Int) -> Void;
        set__dup2__ref:      ({ lib_name: String, fun_name: String, io_call: ((Sy_Int, Sy_Int) -> Void) } -> ((Sy_Int, Sy_Int) -> Void)) -> Void;

             close__syscall:    Sy_Int -> Void;
        set__close__ref:      ({ lib_name: String, fun_name: String, io_call: (Sy_Int -> Void) } -> (Sy_Int -> Void)) -> Void;

             read__syscall:    (Int, Int) -> ru::Vector;
        set__read__ref:      ({ lib_name: String, fun_name: String, io_call: ((Int, Int) -> ru::Vector) } -> ((Int, Int) -> ru::Vector)) -> Void;

             readbuf__syscall:    (Int, wu::Rw_Vector, Int, Int) -> Int;
        set__readbuf__ref:      ({ lib_name: String, fun_name: String, io_call: ((Int, wu::Rw_Vector, Int, Int) -> Int) } -> ((Int, wu::Rw_Vector, Int, Int) -> Int)) -> Void;

             write_ro_slice__syscall:   (Int,    ru::Vector, Int,   Int   ) -> Int;
        set__write_ro_slice__ref:     ({ lib_name: String, fun_name: String, io_call: ((Int,    ru::Vector, Int,   Int   ) -> Int) } -> ((Int,    ru::Vector, Int,   Int   ) -> Int)) -> Void;

             write_rw_slice__syscall:   (Int, wu::Rw_Vector, Int,   Int   ) -> Int;
        set__write_rw_slice__ref:     ({ lib_name: String, fun_name: String, io_call: ((Int, wu::Rw_Vector, Int,   Int   ) -> Int) } -> ((Int, wu::Rw_Vector, Int,   Int   ) -> Int)) -> Void;

             fcntl_d__syscall:    (Sy_Int, Sy_Int) -> Sy_Int;
        set__fcntl_d__ref:      ({ lib_name: String, fun_name: String, io_call: ((Sy_Int, Sy_Int) -> Sy_Int) } -> ((Sy_Int, Sy_Int) -> Sy_Int)) -> Void;

             fcntl_gfd__syscall:    Sy_Int          -> Sy_Unt;
        set__fcntl_gfd__ref:      ({ lib_name: String, fun_name: String, io_call: (Sy_Int          -> Sy_Unt) } -> (Sy_Int          -> Sy_Unt)) -> Void;

             fcntl_sfd__syscall:    (Sy_Int, Sy_Unt) -> Void;
        set__fcntl_sfd__ref:      ({ lib_name: String, fun_name: String, io_call: ((Sy_Int, Sy_Unt) -> Void) } -> ((Sy_Int, Sy_Unt) -> Void)) -> Void;

             fcntl_gfl__syscall:    Sy_Int          -> (Sy_Unt, Sy_Unt);
        set__fcntl_gfl__ref:      ({ lib_name: String, fun_name: String, io_call: (Sy_Int          -> (Sy_Unt, Sy_Unt)) } -> (Sy_Int          -> (Sy_Unt, Sy_Unt))) -> Void;

             fcntl_sfl__syscall:    (Sy_Int, Sy_Unt) -> Void;
        set__fcntl_sfl__ref:      ({ lib_name: String, fun_name: String, io_call: ((Sy_Int, Sy_Unt) -> Void) } -> ((Sy_Int, Sy_Unt) -> Void)) -> Void;

        Flock_Rep =   (Sy_Int, Sy_Int, ti::Int, ti::Int, Sy_Int);

             fcntl_l__syscall:    (Sy_Int, Sy_Int, Flock_Rep) -> Flock_Rep;
        set__fcntl_l__ref:      ({ lib_name: String, fun_name: String, io_call: ((Sy_Int, Sy_Int, Flock_Rep) -> Flock_Rep) } -> ((Sy_Int, Sy_Int, Flock_Rep) -> Flock_Rep)) -> Void;

             lseek__syscall:    (Sy_Int, ti::Int, Sy_Int) -> ti::Int;
        set__lseek__ref:      ({ lib_name: String, fun_name: String, io_call: ((Sy_Int, ti::Int, Sy_Int) -> ti::Int) } -> ((Sy_Int, ti::Int, Sy_Int) -> ti::Int)) -> Void;

             fsync__syscall:    Sy_Int -> Void;
        set__fsync__ref:      ({ lib_name: String, fun_name: String, io_call: (Sy_Int -> Void) } -> (Sy_Int -> Void)) -> Void;
    };                                                                                                          #  Api Posix_Io 

end;

## COPYRIGHT (c) 1995 AT&T Bell Laboratories.
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext