Libs-dev/libio: Difference between revisions
m (C example, POSIX references) |
No edit summary |
||
(13 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
Right now, libio provides API to only work with files | Right now, '''libio''' provides <abbr title="Application Programming Interface">API</abbr> to only work with files (although other communication types like pipes were also planned initially) | ||
By default, library is compiled to use OEM file names. Support for Unicode file names is also present but requires include file to be changed and library to be recompiled. | By default, library is compiled to use OEM file names. Support for Unicode file names is also present but requires include file to be changed and library to be recompiled. | ||
In most cases, libio follows POSIX function prototypes. POSIX equivalents are specified for each function, where applicable. | In most cases, '''libio''' follows [http://en.wikipedia.org/wiki/POSIX POSIX] function prototypes. POSIX equivalents are specified for each function, where applicable. | ||
=Functions (enumerating files)= | =Functions (enumerating files)= | ||
Line 13: | Line 14: | ||
Arguments: | Arguments: | ||
:<tt>_dir</tt> | :<tt>_dir</tt> → asciiz | ||
::directory path to search in | ::directory path to search in | ||
:<tt>_mask</tt> | :<tt>_mask</tt> → asciiz | ||
::file mask, with use of wildcards | ::file mask, with use of wildcards (a.k.a. shell patterns) | ||
:<tt>_attr</tt> | :<tt>_attr</tt> → dword | ||
::file attributes mask (combination of FA_* constants) | ::file attributes mask (combination of [[#File_attributes|FA_* constants]]) | ||
Result: | Result: | ||
:<tt>eax</tt> | :<tt>eax</tt> → [[#FileInfoA|FileInfo]]* | ||
::0 (error) / matched file data pointer (acts as find descriptor) | ::0 (error) / matched file data pointer (acts as find descriptor) | ||
==file_find_next== | ==file_find_next== | ||
Line 31: | Line 32: | ||
Arguments: | Arguments: | ||
:<tt>_findd</tt> | :<tt>_findd</tt> → [[#FileInfoA|FileInfo]]* | ||
::find descriptor (see [[#file_find_first|file_find_first]]) | ::find descriptor (see [[#file_find_first|file_find_first]]) | ||
Result: | Result: | ||
:<tt>eax</tt> | :<tt>eax</tt> → [[#FileInfoA|FileInfo]]* | ||
::0 (error) / matched file data pointer (acts as find descriptor) | ::0 (error) / matched file data pointer (acts as find descriptor) | ||
==file_find_close== | ==file_find_close== | ||
Line 45: | Line 46: | ||
Arguments: | Arguments: | ||
:<tt>_findd</tt> | :<tt>_findd</tt> → [[#FileInfoA|FileInfo]]* | ||
::find descriptor (see [[#file_find_first|file_find_first]]) | ::find descriptor (see [[#file_find_first|file_find_first]]) | ||
Result: | Result: | ||
:<tt>eax</tt> | :<tt>eax</tt> → dword | ||
::result of memory freeing routine | ::result of memory freeing routine | ||
Line 61: | Line 62: | ||
Arguments: | Arguments: | ||
:<tt>_name</tt> | :<tt>_name</tt> → asciiz | ||
::path to file (full or relative) | ::path to file (full or relative) | ||
Result: | Result: | ||
:<tt>eax</tt> | :<tt>ebx (attention: ebx, not eax)</tt> → dword | ||
::-1 (error) / file size (in bytes, up to 2G) | ::-1 (error) / file size (in bytes, up to 2G) | ||
Notes: | Notes: | ||
Line 78: | Line 79: | ||
Arguments: | Arguments: | ||
:<tt>_name</tt> | :<tt>_name</tt> → asciiz | ||
::path to file (full or relative) | ::path to file (full or relative) | ||
:<tt>_mode</tt> | :<tt>_mode</tt> → dword | ||
::mode to open file in (combination of [[#File_open_mode|O_* constants]]) | ::mode to open file in (combination of [[#File_open_mode|O_* constants]]) | ||
Result: | Result: | ||
:<tt>eax</tt> | :<tt>eax</tt> → InternalFileInfo* | ||
::0 (error) / file descriptor | ::0 (error) / file descriptor | ||
Notes: | Notes: | ||
Line 100: | Line 101: | ||
Arguments: | Arguments: | ||
:<tt>_filed</tt> | :<tt>_filed</tt> → InternalFileInfo* | ||
::file descriptor (see [[#file_open|file_open]]) | ::file descriptor (see [[#file_open|file_open]]) | ||
:<tt>_buf</tt> | :<tt>_buf</tt> → byte* | ||
::buffer to put read data to | ::buffer to put read data to | ||
:<tt>_buflen</tt> | :<tt>_buflen</tt> → dword | ||
::buffer size (number of bytes to be read from file) | ::buffer size (number of bytes to be read from file) | ||
Result: | Result: | ||
:<tt>eax</tt> | :<tt>eax</tt> → dword | ||
::-1 (error) / number of bytes read | ::-1 (error) / number of bytes read | ||
Notes: | Notes: | ||
Line 124: | Line 125: | ||
Arguments: | Arguments: | ||
:<tt>_filed</tt> | :<tt>_filed</tt> → InternalFileInfo* | ||
::file descriptor (see [[#file_open|file_open]]) | ::file descriptor (see [[#file_open|file_open]]) | ||
:<tt>_buf</tt> | :<tt>_buf</tt> → byte* | ||
::buffer to get write data from | ::buffer to get write data from | ||
:<tt>_buflen</tt> | :<tt>_buflen</tt> → dword | ||
::buffer size (number of bytes to be written to file) | ::buffer size (number of bytes to be written to file) | ||
Result: | Result: | ||
:<tt>eax</tt> | :<tt>eax</tt> → dword | ||
::-1 (error) / number of bytes written | ::-1 (error) / number of bytes written | ||
Notes: | Notes: | ||
Line 148: | Line 149: | ||
Arguments: | Arguments: | ||
:<tt>_filed</tt> | :<tt>_filed</tt> → InternalFileInfo* | ||
::file descriptor (see [[#file_open|file_open]]) | ::file descriptor (see [[#file_open|file_open]]) | ||
:<tt>_where</tt> | :<tt>_where</tt> → dword | ||
::position in file (in bytes) counted from specified origin | ::position in file (in bytes) counted from specified origin | ||
:<tt>_origin</tt> | :<tt>_origin</tt> → dword | ||
::origin from where to set the position (one of [[#File_seek_origin|SEEK_* constants]]) | ::origin from where to set the position (one of [[#File_seek_origin|SEEK_* constants]]) | ||
Result: | Result: | ||
:<tt>eax</tt> | :<tt>eax</tt> → dword | ||
::-1 (error) / 0 | ::-1 (error) / 0 | ||
Notes: | Notes: | ||
Line 172: | Line 173: | ||
Arguments: | Arguments: | ||
:<tt>_filed</tt> | :<tt>_filed</tt> → InternalFileInfo* | ||
::file descriptor (see [[#file_open|file_open]]) | ::file descriptor (see [[#file_open|file_open]]) | ||
Result: | Result: | ||
:<tt>eax</tt> | :<tt>eax</tt> → dword | ||
::false / true | ::false / true | ||
Notes: | Notes: | ||
Line 192: | Line 193: | ||
Arguments: | Arguments: | ||
:<tt>_filed</tt> | :<tt>_filed</tt> → InternalFileInfo* | ||
::file descriptor (see [[#file_open|file_open]]) | ::file descriptor (see [[#file_open|file_open]]) | ||
Result: | Result: | ||
:<tt>eax</tt> | :<tt>eax</tt> → dword | ||
::-1 (error) / 0 | ::-1 (error) / 0 | ||
Notes: | Notes: | ||
Line 212: | Line 213: | ||
Arguments: | Arguments: | ||
:<tt>_filed</tt> | :<tt>_filed</tt> → InternalFileInfo* | ||
::file descriptor (see [[#file_open|file_open]]) | ::file descriptor (see [[#file_open|file_open]]) | ||
Result: | Result: | ||
:<tt>eax</tt> | :<tt>eax</tt> → dword | ||
::-1 (error) / file pointer position | ::-1 (error) / file pointer position | ||
Notes: | Notes: | ||
Line 232: | Line 233: | ||
Arguments: | Arguments: | ||
:<tt>_filed</tt> | :<tt>_filed</tt> → InternalFileInfo* | ||
::file descriptor (see [[#file_open|file_open]]) | ::file descriptor (see [[#file_open|file_open]]) | ||
Result: | Result: | ||
:<tt>eax</tt> | :<tt>eax</tt> → dword | ||
::-1 (error) / | ::-1 (error) / 0 | ||
Notes: | Notes: | ||
Line 244: | Line 245: | ||
POSIX equivalent: | POSIX equivalent: | ||
:<tt>int result = fclose(_filed);</tt> | :<tt>int result = fclose(_filed);</tt> | ||
==file_err== | |||
Not yet implemented. | |||
It was planned to give an extended information about errors that occur. | |||
=Constants= | =Constants= | ||
==File open mode== | ==File open mode== | ||
<source> | |||
O_BINARY = 00000000b | |||
O_READ = 00000001b | |||
O_WRITE = 00000010b | |||
O_CREATE = 00000100b | |||
O_SHARE = 00001000b | |||
O_TEXT = 00010000b | |||
</source> | |||
Detailed description: | Detailed description: | ||
Line 270: | Line 277: | ||
==File seek origin== | ==File seek origin== | ||
<source> | |||
SEEK_SET = 0 | |||
SEEK_CUR = 1 | |||
SEEK_END = 2 | |||
</source> | |||
Detailed description: | Detailed description: | ||
Line 283: | Line 292: | ||
==File attributes== | ==File attributes== | ||
<source> | |||
FA_READONLY = 00000001b | |||
FA_HIDDEN = 00000010b | |||
FA_SYSTEM = 00000100b | |||
FA_LABEL = 00001000b | |||
FA_FOLDER = 00010000b | |||
FA_ARCHIVED = 00100000b | |||
FA_ANY = 00111111b | |||
</source> | |||
Detailed description: | |||
:<tt>FA_READONLY</tt> | |||
::file is read-only (write forbidden) | |||
:<tt>FA_HIDDEN</tt> | |||
::file or directory is hidden (should generally not be visible by user) | |||
:<tt>FA_SYSTEM</tt> | |||
::file or directory contains valuable operating system data | |||
:<tt>FA_LABEL</tt> | |||
::not a file, name holds disk label | |||
:<tt>FA_FOLDER</tt> | |||
::not a file, but directory | |||
:<tt>FA_ARCHIVED</tt> | |||
::file is archived (deprecated, system-specific use) | |||
:<tt>FA_ANY</tt> | |||
::any of above attributes (used when specifying mask) | |||
=Structures= | =Structures= | ||
Line 296: | Line 323: | ||
Date and time as returned by underlying system calls. | Date and time as returned by underlying system calls. | ||
<source> | |||
struct FileDateTime | |||
union | |||
time dd ? | |||
struct | |||
sec db ? | |||
min db ? | |||
hour db ? | |||
ends | |||
ends | |||
union | |||
date dd ? | |||
struct | |||
day db ? | |||
month db ? | |||
year dw ? | |||
ends | |||
ends | |||
ends | |||
</source> | |||
==FileInfoBlock== | ==FileInfoBlock== | ||
File information block used by underlying system calls to identify function to be called and its basic arguments. Should generally not be used by programs. | File information block used by underlying system calls to identify function to be called and its basic arguments. Should generally not be used by programs. | ||
<source> | |||
struct FileInfoBlock | |||
Function dd ? | |||
Position dd ? | |||
Flags dd ? | |||
Count dd ? | |||
Buffer dd ? | |||
db ? | |||
FileName dd ? | |||
ends | |||
</source> | |||
==FileInfoHeader== | ==FileInfoHeader== | ||
File information header as returned by underlying call to [[SysFn70|70.1]] system function. Should generally not be used by programs. | File information header as returned by underlying call to [[SysFn70|70.1]] system function. Should generally not be used by programs. | ||
<source> | |||
struct FileInfoHeader | |||
Version dd ? | |||
FilesRead dd ? | |||
FilesCount dd ? | |||
rd 5 | |||
ends | |||
</source> | |||
==FileInfoA== | ==FileInfoA== | ||
OEM version of FileInfo structure. | OEM version of FileInfo structure. | ||
<source> | |||
struct FileInfoA | |||
Attributes dd ? | |||
Flags dd ? | |||
DateCreate FileDateTime | |||
DateAccess FileDateTime | |||
DateModify FileDateTime | |||
union | |||
FileSize dq ? | |||
struct | |||
FileSizeLow dd ? | |||
FileSizeHigh dd ? | |||
ends | |||
ends | |||
FileName rb 264 | |||
ends | |||
</source> | |||
==FileInfoW== | ==FileInfoW== | ||
Unicode version of FileInfo structure. | Unicode version of FileInfo structure. | ||
<source> | |||
struct FileInfoW | |||
Attributes dd ? | |||
Flags dd ? | |||
DateCreate FileDateTime | |||
DateAccess FileDateTime | |||
DateModify FileDateTime | |||
union | |||
FileSize dq ? | |||
struct | |||
FileSizeLow dd ? | |||
FileSizeHigh dd ? | |||
ends | |||
ends | |||
FileName rw 260 | |||
ends | |||
</source> | |||
=Usage examples= | =Usage examples= | ||
Small piece of code illustrating file opening, reading 256 bytes, seeking to the beginning, writing same data back and closing file descriptor. Note that we could succeessfully read less than 256 bytes, so we remember the exact number. | Small piece of code illustrating file opening, reading 256 bytes, seeking to the beginning, writing same data back and closing file descriptor. Note that we could succeessfully read less than 256 bytes, so we remember the exact number. Note also that we use "invoke" here since the call is indirect. | ||
<source> | <source line> | ||
include 'libio/libio.inc' | include 'libio/libio.inc' | ||
; ... | ; ... | ||
invoke file_open, filename, O_READ + O_WRITE | |||
or eax, eax | or eax, eax | ||
jz .error | jz .error | ||
Line 390: | Line 427: | ||
mov [fdesc], eax | mov [fdesc], eax | ||
invoke file_read, eax, buffer, 256 | |||
mov [bytes_read], eax | mov [bytes_read], eax | ||
inc eax | inc eax | ||
jz .close | jz .close | ||
invoke file_seek, [fdesc], 0, SEEK_SET | |||
inc eax | inc eax | ||
jz .close | jz .close | ||
invoke file_write, [fdesc], buffer, [bytes_read] | |||
.close: | .close: | ||
invoke file_close, [fdesc] | |||
.error: | .error: | ||
Line 416: | Line 453: | ||
Same code written in C could look like (just for the reference): | Same code written in C could look like (just for the reference): | ||
<source lang=" | <source lang="c" line> | ||
FILE *f = file_open("/hd0/1/a.dat", O_READ | O_WRITE); | FILE *f = file_open("/hd0/1/a.dat", O_READ | O_WRITE); | ||
if (f) | if (f) | ||
Line 440: | Line 477: | ||
[[Category:Coding]][[Category:Manuals]] | [[Category:Coding]][[Category:Manuals]] | ||
[[Category:Libraries]] |
Latest revision as of 17:33, 5 January 2022
Right now, libio provides API to only work with files (although other communication types like pipes were also planned initially)
By default, library is compiled to use OEM file names. Support for Unicode file names is also present but requires include file to be changed and library to be recompiled.
In most cases, libio follows POSIX function prototypes. POSIX equivalents are specified for each function, where applicable.
Functions (enumerating files)
file_find_first
Find first file with matching attributes and mask in specified directory.
Prototype:
- proc file.find_first _dir, _mask, _attr
Arguments:
- _dir → asciiz
- directory path to search in
- _mask → asciiz
- file mask, with use of wildcards (a.k.a. shell patterns)
- _attr → dword
- file attributes mask (combination of FA_* constants)
Result:
- eax → FileInfo*
- 0 (error) / matched file data pointer (acts as find descriptor)
file_find_next
Find next file matching criteria.
Prototype:
- proc file.find_next _findd
Arguments:
- _findd → FileInfo*
- find descriptor (see file_find_first)
Result:
- eax → FileInfo*
- 0 (error) / matched file data pointer (acts as find descriptor)
file_find_close
Close find descriptor and free memory.
Prototype:
- proc file.find_close _findd
Arguments:
- _findd → FileInfo*
- find descriptor (see file_find_first)
Result:
- eax → dword
- result of memory freeing routine
Functions (working with specific file)
file_size
Get file size.
Prototype:
- proc file.size _name
Arguments:
- _name → asciiz
- path to file (full or relative)
Result:
- ebx (attention: ebx, not eax) → dword
- -1 (error) / file size (in bytes, up to 2G)
Notes:
- call file_err to obtain extended error information
file_open
Open file.
Prototype:
- proc file.open _name, _mode
Arguments:
- _name → asciiz
- path to file (full or relative)
- _mode → dword
- mode to open file in (combination of O_* constants)
Result:
- eax → InternalFileInfo*
- 0 (error) / file descriptor
Notes:
- call file_err to obtain extended error information
POSIX equivalent:
- FILE *result = fopen(_name, _mode);
file_read
Read data from file.
Prototype:
- proc file.read _filed, _buf, _buflen
Arguments:
- _filed → InternalFileInfo*
- file descriptor (see file_open)
- _buf → byte*
- buffer to put read data to
- _buflen → dword
- buffer size (number of bytes to be read from file)
Result:
- eax → dword
- -1 (error) / number of bytes read
Notes:
- call file_err to obtain extended error information
POSIX equivalent:
- size_t result = fread(_buf, _buflen, 1, _filed);
file_write
Write data to file.
Prototype:
- proc file.write _filed, _buf, _buflen
Arguments:
- _filed → InternalFileInfo*
- file descriptor (see file_open)
- _buf → byte*
- buffer to get write data from
- _buflen → dword
- buffer size (number of bytes to be written to file)
Result:
- eax → dword
- -1 (error) / number of bytes written
Notes:
- call file_err to obtain extended error information
POSIX equivalent:
- size_t result = fwrite(_buf, _buflen, 1, _filed);
file_seek
Set file pointer position.
Prototype:
- proc file.seek _filed, _where, _origin
Arguments:
- _filed → InternalFileInfo*
- file descriptor (see file_open)
- _where → dword
- position in file (in bytes) counted from specified origin
- _origin → dword
- origin from where to set the position (one of SEEK_* constants)
Result:
- eax → dword
- -1 (error) / 0
Notes:
- call file_err to obtain extended error information
POSIX equivalent:
- int result = fseek(_filed, _where, _origin);
file_iseof
Determine if file pointer is at the end of file.
Prototype:
- proc file.eof? _filed
Arguments:
- _filed → InternalFileInfo*
- file descriptor (see file_open)
Result:
- eax → dword
- false / true
Notes:
- call file_err to obtain extended error information
POSIX equivalent:
- int result = feof(_filed);
file_truncate (file_seteof)
Truncate file size to current file pointer position:
Prototype:
- proc file.truncate _filed
Arguments:
- _filed → InternalFileInfo*
- file descriptor (see file_open)
Result:
- eax → dword
- -1 (error) / 0
Notes:
- call file_err to obtain extended error information
POSIX equivalent:
- int result = ftruncate(fileno(_filed), ftell(_filed));
file_tell
Get current file pointer position.
Prototype:
- proc file.tell _filed
Arguments:
- _filed → InternalFileInfo*
- file descriptor (see file_open)
Result:
- eax → dword
- -1 (error) / file pointer position
Notes:
- call file_err to obtain extended error information
POSIX equivalent:
- long result = ftell(_filed);
file_close
Close file.
Prototype:
- proc file.close _filed
Arguments:
- _filed → InternalFileInfo*
- file descriptor (see file_open)
Result:
- eax → dword
- -1 (error) / 0
Notes:
- call file_err to obtain extended error information
POSIX equivalent:
- int result = fclose(_filed);
file_err
Not yet implemented. It was planned to give an extended information about errors that occur.
Constants
File open mode
O_BINARY = 00000000b
O_READ = 00000001b
O_WRITE = 00000010b
O_CREATE = 00000100b
O_SHARE = 00001000b
O_TEXT = 00010000b
Detailed description:
- O_BINARY
- don't change read/written data in any way (default)
- O_READ
- open file for reading
- O_WRITE
- open file for writing
- O_CREATE
- create file if it doesn't exist, open otherwise
- O_SHARE
- allow simultaneous access by using different file descriptors (not implemented)
- O_TEXT
- replace newline chars with LF (overrides O_BINARY, not implemented)
File seek origin
SEEK_SET = 0
SEEK_CUR = 1
SEEK_END = 2
Detailed description:
- SEEK_SET
- from beginning of file
- SEEK_CUR
- from current pointer position
- SEEK_END
- from end of file
File attributes
FA_READONLY = 00000001b
FA_HIDDEN = 00000010b
FA_SYSTEM = 00000100b
FA_LABEL = 00001000b
FA_FOLDER = 00010000b
FA_ARCHIVED = 00100000b
FA_ANY = 00111111b
Detailed description:
- FA_READONLY
- file is read-only (write forbidden)
- FA_HIDDEN
- file or directory is hidden (should generally not be visible by user)
- FA_SYSTEM
- file or directory contains valuable operating system data
- FA_LABEL
- not a file, name holds disk label
- FA_FOLDER
- not a file, but directory
- FA_ARCHIVED
- file is archived (deprecated, system-specific use)
- FA_ANY
- any of above attributes (used when specifying mask)
Structures
FileDateTime
Date and time as returned by underlying system calls.
struct FileDateTime
union
time dd ?
struct
sec db ?
min db ?
hour db ?
ends
ends
union
date dd ?
struct
day db ?
month db ?
year dw ?
ends
ends
ends
FileInfoBlock
File information block used by underlying system calls to identify function to be called and its basic arguments. Should generally not be used by programs.
struct FileInfoBlock
Function dd ?
Position dd ?
Flags dd ?
Count dd ?
Buffer dd ?
db ?
FileName dd ?
ends
FileInfoHeader
File information header as returned by underlying call to 70.1 system function. Should generally not be used by programs.
struct FileInfoHeader
Version dd ?
FilesRead dd ?
FilesCount dd ?
rd 5
ends
FileInfoA
OEM version of FileInfo structure.
struct FileInfoA
Attributes dd ?
Flags dd ?
DateCreate FileDateTime
DateAccess FileDateTime
DateModify FileDateTime
union
FileSize dq ?
struct
FileSizeLow dd ?
FileSizeHigh dd ?
ends
ends
FileName rb 264
ends
FileInfoW
Unicode version of FileInfo structure.
struct FileInfoW
Attributes dd ?
Flags dd ?
DateCreate FileDateTime
DateAccess FileDateTime
DateModify FileDateTime
union
FileSize dq ?
struct
FileSizeLow dd ?
FileSizeHigh dd ?
ends
ends
FileName rw 260
ends
Usage examples
Small piece of code illustrating file opening, reading 256 bytes, seeking to the beginning, writing same data back and closing file descriptor. Note that we could succeessfully read less than 256 bytes, so we remember the exact number. Note also that we use "invoke" here since the call is indirect.
include 'libio/libio.inc'
; ...
invoke file_open, filename, O_READ + O_WRITE
or eax, eax
jz .error
mov [fdesc], eax
invoke file_read, eax, buffer, 256
mov [bytes_read], eax
inc eax
jz .close
invoke file_seek, [fdesc], 0, SEEK_SET
inc eax
jz .close
invoke file_write, [fdesc], buffer, [bytes_read]
.close:
invoke file_close, [fdesc]
.error:
; ...
filename db '/hd0/1/a.dat', 0
fdesc dd ?
bytes_read dd ?
buffer db 256 dup(?)
Same code written in C could look like (just for the reference):
FILE *f = file_open("/hd0/1/a.dat", O_READ | O_WRITE);
if (f)
{
do
{
char buffer[256];
size_t bytes_read = file_read(f, buffer, sizeof(buffer));
if (bytes_read == -1)
{
break;
}
if (file_seek(f, 0, SEEK_SET) == -1)
{
break;
}
file_write(f, buffer, bytes_read);
}
while (0);
file_close(f);
}