[PATCH] : libc_r/uthread/uthread_write.c

Dan Langille dan at langille.org
Wed Sep 17 07:32:28 PDT 2003


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 <unistd.h>
 #include <pthread.h>
 #include "pthread_private.h"
-#include <syslog.h>
 
 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/



More information about the freebsd-hackers mailing list