When retrying a write() after an EINTR error on unix, be sure to also
rerun the previous lseek(). Ticket [e59bdf6116036a] FossilOrigin-Name: 21452f3ae6b5882b03c7cc41e661c7b8144cc3df
This commit is contained in:
+12
-10
@@ -3039,17 +3039,19 @@ static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
|
||||
#elif defined(USE_PREAD64)
|
||||
do{ got = osPwrite64(id->h, pBuf, cnt, offset);}while( got<0 && errno==EINTR);
|
||||
#else
|
||||
newOffset = lseek(id->h, offset, SEEK_SET);
|
||||
SimulateIOError( newOffset-- );
|
||||
if( newOffset!=offset ){
|
||||
if( newOffset == -1 ){
|
||||
((unixFile*)id)->lastErrno = errno;
|
||||
}else{
|
||||
((unixFile*)id)->lastErrno = 0;
|
||||
do{
|
||||
newOffset = lseek(id->h, offset, SEEK_SET);
|
||||
SimulateIOError( newOffset-- );
|
||||
if( newOffset!=offset ){
|
||||
if( newOffset == -1 ){
|
||||
((unixFile*)id)->lastErrno = errno;
|
||||
}else{
|
||||
((unixFile*)id)->lastErrno = 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
do{ got = osWrite(id->h, pBuf, cnt); }while( got<0 && errno==EINTR );
|
||||
got = osWrite(id->h, pBuf, cnt);
|
||||
}while( got<0 && errno==EINTR );
|
||||
#endif
|
||||
TIMER_END;
|
||||
if( got<0 ){
|
||||
|
||||
+1
-1
@@ -325,6 +325,7 @@ static int ts_pread64(int fd, void *aBuf, size_t nBuf, off_t off){
|
||||
*/
|
||||
static int ts_write(int fd, const void *aBuf, size_t nBuf){
|
||||
if( tsIsFailErrno("write") ){
|
||||
if( tsErrno("write")==EINTR ) orig_write(fd, aBuf, nBuf/2);
|
||||
return -1;
|
||||
}
|
||||
return orig_write(fd, aBuf, nBuf);
|
||||
@@ -671,4 +672,3 @@ int SqlitetestSyscall_Init(Tcl_Interp *interp){
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user