@@ -124,6 +124,7 @@ static jrd_file* setup_file(Database*, const PathName&, const int, const bool, c
124124static void lockDatabaseFile (int & desc, const bool shareMode, const bool temporary,
125125 const char * fileName, ISC_STATUS operation);
126126static bool unix_error (const TEXT*, const jrd_file*, ISC_STATUS, FbStatusVector* = NULL );
127+ static bool block_size_error (const jrd_file*, off_t , FbStatusVector* = NULL );
127128#if !(defined HAVE_PREAD && defined HAVE_PWRITE)
128129static SLONG pread (int , SCHAR*, SLONG, SLONG);
129130static SLONG pwrite (int , SCHAR*, SLONG, SLONG);
@@ -550,14 +551,12 @@ void PIO_header(thread_db* tdbb, UCHAR* address, int length)
550551
551552 for (i = 0 ; i < IO_RETRY; i++)
552553 {
553- if ((bytes = pread (file->fil_desc , address, length, 0 )) < 0 )
554- {
555- if (SYSCALL_INTERRUPTED (errno))
556- continue ;
557- unix_error (" read" , file, isc_io_read_err);
558- }
559- else
554+ if ((bytes = pread (file->fil_desc , address, length, 0 )) == length)
560555 break ;
556+ if (bytes < 0 && !SYSCALL_INTERRUPTED (errno))
557+ unix_error (" read" , file, isc_io_read_err);
558+ if (bytes >= 0 )
559+ block_size_error (file, bytes);
561560 }
562561
563562 if (i == IO_RETRY)
@@ -768,6 +767,8 @@ bool PIO_read(thread_db* tdbb, jrd_file* file, BufferDesc* bdb, Ods::pag* page,
768767 break ;
769768 if (bytes < 0 && !SYSCALL_INTERRUPTED (errno))
770769 return unix_error (" read" , file, isc_io_read_err, status_vector);
770+ if (bytes >= 0 )
771+ return block_size_error (file, offset + bytes, status_vector);
771772 }
772773
773774 if (i == IO_RETRY)
@@ -1037,16 +1038,47 @@ static bool unix_error(const TEXT* string,
10371038 Arg::Gds (operation) << Arg::Unix (errno);
10381039
10391040 if (!status_vector)
1040- {
10411041 ERR_post (err);
1042- }
10431042
10441043 ERR_build_status (status_vector, err);
10451044 iscLogStatus (NULL , status_vector);
10461045
10471046 return false ;
10481047}
10491048
1049+
1050+ static bool block_size_error (const jrd_file* file, off_t offset, FbStatusVector* status_vector)
1051+ {
1052+ /* *************************************
1053+ *
1054+ * b l o c k _ s i z e _ e r r o r
1055+ *
1056+ **************************************
1057+ *
1058+ * Functional description
1059+ * DB block read incomplete, that may be
1060+ * due to signal caught or unexpected EOF.
1061+ *
1062+ **************************************/
1063+ struct stat st;
1064+ if (fstat (file->fil_desc , &st) < 0 )
1065+ return unix_error (" fstat" , file, isc_io_access_err, status_vector);
1066+
1067+ if (offset < st.st_size ) // we might read more but were interupted
1068+ return true ;
1069+
1070+ Arg::Gds err (isc_io_error);
1071+ err << " read" << file->fil_string << Arg::Gds (isc_random) << " File size is less than expected" ;
1072+
1073+ if (!status_vector)
1074+ ERR_post (err);
1075+
1076+ ERR_build_status (status_vector, err);
1077+ iscLogStatus (NULL , status_vector);
1078+ return false ;
1079+ }
1080+
1081+
10501082#if !(defined HAVE_PREAD && defined HAVE_PWRITE)
10511083
10521084/* pread() and pwrite() behave like read() and write() except that they
0 commit comments