Re: [PATCH] Properly handle short writes in sigint handlers

Subject: Re: [PATCH] Properly handle short writes in sigint handlers

Date: Wed, 11 Jan 2012 15:04:51 +0200

To: David Bremner, Dmitry Kurochkin, Austin Clements, notmuch@notmuchmail.org

Cc:

From: Tomi Ollila


On Tue, 10 Jan 2012 07:13:50 -0400, David Bremner <david@tethera.net> wrote:
> On Fri, 23 Dec 2011 23:10:35 +0400, Dmitry Kurochkin <dmitry.kurochkin@gmail.com> wrote:
> > Hi Austin.
> > 
> > I think we should put the write loop into a separate function and reuse
> > it.
> 
> I could go either way on this, unless there is somewhere else the code
> is actually needed at the moment.
> 
> > 
> > Also, does it make sense to add a retry counter to prevent infinite loop
> > if write keeps returning 0?
> 
> I wonder about this too. Is this possibility ignorable Austin?

In this particular case the consensus was to just ignore the short
write (in rare cases that may happen)... And we could use the
first patch: id:"1324503532-5799-1-git-send-email-dme@dme.org"

For other cases we might try to find a good implementation of 
"writefully()". OpenSSH atomicio.[ch] looks like a good place to start...

... writefully () from that code could look something like:

/* 2-clause license ("Simplified BSD License" or "FreeBSD License") */
size_t writefully(int fd, const void * data, size_t n)
{
	const char *s = (const char *)data;
	size_t pos = 0;
	ssize_t res;

	while (n > pos) {
		res = write(fd, s + pos, n - pos);
		switch (res) {
		case -1:
			if (errno == EINTR)
				continue;
			if (errno == EAGAIN || errno == EWOULDBLOCK) {
                        	struct pollfd pfd;
                                pfd.fd = fd;
                                pfd.events = POLLOUT;
				(void)poll(&pfd, 1, -1);
				continue;
			}
			return 0;
		case 0:
			errno = EPIPE;
			return pos;
		default:
			pos += (size_t)res;
		}
	}
        return pos;
}

> 
> d

Tomi

Thread: