Fix for bug 369036. Prevent infinite loop in pt_SolarisSendFile. r=wtchang, nelson NSPR_4_6_BRANCH
authorjulien.pierre.boogz%sun.com
Wed, 29 Aug 2007 01:29:59 +0000
branchNSPR_4_6_BRANCH
changeset 3860 e650419de5f73761ccc659bbbe4aa300c419ac8d
parent 3854 df765c5f9e128b609d3074f63d66681d03acf3e7
child 3864 b6f6ce578fb54e4ec3e88b93c70e4da14745458b
push idunknown
push userunknown
push dateunknown
reviewerswtchang, nelson
bugs369036
Fix for bug 369036. Prevent infinite loop in pt_SolarisSendFile. r=wtchang, nelson
pr/src/md/unix/unix_errors.c
pr/src/pthreads/ptio.c
--- a/pr/src/md/unix/unix_errors.c
+++ b/pr/src/md/unix/unix_errors.c
@@ -846,17 +846,31 @@ void _MD_hpux_map_sendfile_error(int err
 {
     _MD_unix_map_default_error(err);
 }
 #endif /* HPUX11 */
 
 #ifdef SOLARIS
 void _MD_solaris_map_sendfile_error(int err)
 {
-    _MD_unix_map_default_error(err) ;
+    PRErrorCode prError;
+
+    switch (err) {
+        /*
+         * Solaris defines a 0 return value for sendfile to mean end-of-file.
+         */
+        case 0:
+            prError = PR_END_OF_FILE_ERROR;
+            break;
+
+        default:
+            _MD_unix_map_default_error(err) ;
+            return;
+    }
+    PR_SetError(prError, err);
 }
 #endif /* SOLARIS */
 
 #ifdef LINUX
 void _MD_linux_map_sendfile_error(int err)
 {
     _MD_unix_map_default_error(err) ;
 }
--- a/pr/src/pthreads/ptio.c
+++ b/pr/src/pthreads/ptio.c
@@ -1066,16 +1066,25 @@ static PRBool pt_solaris_sendfile_cont(p
 
     if (count == -1) {
         if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN
                 && op->syserrno != EINTR) {
             op->result.code = -1;
             return PR_TRUE;
         }
         count = xferred;
+    } else if (count == 0) {
+        /* 
+         * We are now at EOF. The file was truncated. Solaris sendfile is
+         * supposed to return 0 and no error in this case, though some versions
+         * may return -1 and EINVAL .
+         */
+        op->result.code = -1;
+        op->syserrno = 0; /* will be treated as EOF */
+        return PR_TRUE;
     }
     PR_ASSERT(count <= op->nbytes_to_send);
     
     op->result.code += count;
     if (count < op->nbytes_to_send) {
         op->nbytes_to_send -= count;
 
         while (count >= vec->sfv_len) {
@@ -2414,16 +2423,24 @@ static PRInt32 pt_SolarisSendFile(PRFile
     PR_ASSERT((count == -1) || (count == xferred));
 
     if (count == -1) {
         syserrno = errno;
         if (syserrno == EINTR
                 || syserrno == EAGAIN || syserrno == EWOULDBLOCK) {
             count = xferred;
         }
+    } else if (count == 0) {
+        /*
+         * We are now at EOF. The file was truncated. Solaris sendfile is
+         * supposed to return 0 and no error in this case, though some versions
+         * may return -1 and EINVAL .
+         */
+        count = -1;
+        syserrno = 0;  /* will be treated as EOF */
     }
 
     if (count != -1 && count < nbytes_to_send) {
         pt_Continuation op;
         struct sendfilevec *vec = sfv_struct;
         PRInt32 rem = count;
 
         while (rem >= vec->sfv_len) {