Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2017-08

BlockWrite() version 2.6.4

7 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Brian

Can anyone familiar with FPC 2.6.4 comment on the specifics of how BlockWrite() functions under Linux. Specifically does BlockWrite() call the Linux kernel or call fWrite()?

Does BlockWrite() call fFlush or does it rely on the kernel when to flush and actually write to the disk?

In which file can the source code specific to BlockWrite() version 2.6.4 be found ?

Thanks
Brian

View this message in context: http://free-pascal-general.1045716.n5.nabble.com/BlockWrite-version-2-6-4-tp5729418.html Sent from the Free Pascal - General mailing list .
Michael Van Canneyt
to Brian
Brian wrote
Can anyone familiar with FPC 2.6.4 comment on the specifics of how BlockWrite() functions under Linux. Specifically does BlockWrite() call the Linux kernel or call fWrite()?

Normally, it calls the linux kernel.

Does BlockWrite() call fFlush or does it rely on the kernel when to flush and actually write to the disk?

It relies on the kernel.

In which file can the source code specific to BlockWrite() version 2.6.4 be found ?

Headers are in rtl/inc/systemh.inc
actual routines are in rtl/inc/file.inc

Michael.

Karoly Balogh (Charlie/SGR
to Michael Van Canneyt

Hi,

Michael Van Canneyt wrote 5 lines
> In which file can the source code specific to BlockWrite() version 2.6.4 be > found ? Headers are in rtl/inc/systemh.inc actual routines are in rtl/inc/file.inc

Just an addition, BlockWrite() actually calls the internal RTL function Do_Write(), which is the write function implemented for all platforms in a platform specific way in the RTL. On Un*x, it calls FpWrite, which calls the kernel syscall directly.

Do_Write for all Unix (including Linux) is implemented in rtl/unix/sysfile.inc

FpWrite is implemented for Linux in:
rtl/linux/ossysc.inc

But this later function is just a direct call to the syscall. That's the entire code path then, more or less.

Charlie

Marco van de Voort
to Brian

In our previous episode, Brian said:

I notice the Do_Write() uses repeat .. until where fpWrite() does a direct call. What was the reasoning for the repeat..until in Do_Write() ?

Syscalls that block for hardware can return EINTR (ESysIntr) on some *nixes when a signal arrives while waiting for data.

Some *nixes restart the syscall after the signal was delivered, but afaik Linux does not. So the loop is just to restart the syscall if needed.

source:
Function Do_Write(Handle:thandle;Addr:Pointer;Len:Longint):longint;
var j : cint;
Begin
  repeat
    Do_Write:=Fpwrite(Handle,addr,len);
    j:=geterrno;
  until (do_write-1) or ((jESysEINTR) and (jESysEAgain));
  If Do_Write<0 Then
   Begin
    Errno2InOutRes;
    Do_Write:=0;
   End
  else
   InOutRes:=0;
End;

see also:
https://www.gnu.org/software/libc/manual/html_node/Interrupted-Primitives.html

Karoly Balogh (Charlie/SGR
to Brian: Thanks Charlie. I notice the Do_Write() uses repeat .. until where fpWrite() does a…

Hi,

Brian wrote 6 lines
Thanks Charlie. I notice the Do_Write() uses repeat .. until where fpWrite() does a direct call. What was the reasoning for the repeat..until in Do_Write() ?

Because FpWrite() is just the direct Unix OS call, so the RTL doesn't add extra behavior there. While Do_Write() which integrates this OS call into the FPC RTL has to do some error handling. In this case, if the system reports EAGAIN or EINTR errors, the write call will be attempted again, without returning an error to the program calling BlockWrite().

There are several reasons why an Unix write() might return EAGAIN or EINTR. These are documented in the Unix manpage for write:

https://linux.die.net/man/2/write

The RTL just tries to handle these recoverable error cases in the Do_Write() function, until the write() fails irrecoverably or it succeeds. Hence the repeat...until.

Charlie