From owner-freebsd-hackers@FreeBSD.ORG Wed Sep 17 07:32:27 2003 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id C06B416A4B3 for ; Wed, 17 Sep 2003 07:32:27 -0700 (PDT) Received: from bast.unixathome.org (bast.unixathome.org [66.11.174.150]) by mx1.FreeBSD.org (Postfix) with ESMTP id 06D4443FE1 for ; Wed, 17 Sep 2003 07:32:26 -0700 (PDT) (envelope-from dan@langille.org) Received: from wocker (wocker.unixathome.org [192.168.0.99]) by bast.unixathome.org (Postfix) with ESMTP id C9E5F3D28; Wed, 17 Sep 2003 10:32:14 -0400 (EDT) From: "Dan Langille" To: Daniel Eischen Date: Wed, 17 Sep 2003 10:32:04 -0400 MIME-Version: 1.0 Message-ID: <3F683824.14446.AB8FEDA@localhost> Priority: normal References: <3F67714D.32262.7B04653@localhost> In-reply-to: X-mailer: Pegasus Mail for Windows (v4.02a) Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Content-description: Mail message body cc: hackers@freebsd.org Subject: Re: [PATCH] : libc_r/uthread/uthread_write.c X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Sep 2003 14:32:28 -0000 On 16 Sep 2003 at 20:49, Daniel Eischen wrote: > On Tue, 16 Sep 2003, Dan Langille wrote: > > > I've had preliminary success with this patch. More testing needs > > to be done, but in the meantime, I would appreciate reviews and > > comments. The patched code is available from > > http://beta.freebsddiary.org/tmp/uthread_write.c and the patch > > appears below. > > > > In short, the logic has been changed to ensure that if __sys_write > > returns zero, this value is returned by _write. > > I think this is not quite correct. Since libc_r is looping > and some data may have been read, then the partial byte count > should be returned, not zero. It is possible the partial byte > count could also be zero in some cases, so it would result > in zero being returned in those instances. I see what you mean. Please have a look at http://beta.freebsddiary.org/tmp/uthread_write.c2 The patch appears at the end of this message. This version will return the partial byte count (which has always been zero in testing) but exit the loop if the return code is zero. > I think the problem lies with the SCSI tape device. It should > either return 0 or -1 with errno=ENOSPC on a write that detects > an EOT, not partial byte count. You are referring to sa(4)? > If you are using libkse or > libthr, you will get a partial byte count and not zero because > the tape driver returns the (partial) bytes written. So exiting > the loop in libc_r and returning 0 would only seem to correct > the "problem" for libc_r. The problem found when running under pthreads on 4.8-stable [i.e. EOT is not returned to the application code] is not found with libkse on 5.1-current. --- uthread_write.c Wed Sep 17 06:23:43 2003 +++ uthread_write.c.org Tue Sep 16 12:14:22 2003 @@ -39,7 +39,6 @@ #include #include #include "pthread_private.h" -#include ssize_t _write(int fd, const void *buf, size_t nbytes) @@ -71,10 +70,6 @@ /* Check if file operations are to block */ blocking = ((_thread_fd_getflags(fd) & O_NONBLOCK) == 0); - setlogmask (LOG_UPTO (LOG_NOTICE)); - openlog("uthread_write.c", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1); - syslog (LOG_NOTICE, "uthread_write.c : blocking = '%d'", blocking); - /* * Loop while no error occurs and until the expected number * of bytes are written if performing a blocking write: @@ -98,7 +93,7 @@ * write: */ if (blocking && ((n < 0 && (errno == EWOULDBLOCK || - errno == EAGAIN)) || (n > 0 && num < nbytes))) { + errno == EAGAIN)) || (n >= 0 && num < nbytes))) { curthread->data.fd.fd = fd; _thread_kern_set_timeout(NULL); @@ -136,16 +131,11 @@ * If there was an error, return partial success * (if any bytes were written) or else the error: */ - } else if (n <= 0) { + } else if (n < 0) { if (num > 0) ret = num; else ret = n; - - if (n == 0) { - syslog (LOG_NOTICE, "zero has been returned in uthread_write.c; num = '%d'", num); - break; - } /* Check if the write has completed: */ } else if (num >= nbytes) -- Dan Langille : http://www.langille.org/