[PATCH] Properly handle short writes in sigint handlers

Tomi Ollila tomi.ollila at iki.fi
Wed Jan 11 05:04:51 PST 2012


On Tue, 10 Jan 2012 07:13:50 -0400, David Bremner <david at tethera.net> wrote:
> On Fri, 23 Dec 2011 23:10:35 +0400, Dmitry Kurochkin <dmitry.kurochkin at 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 at 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


More information about the notmuch mailing list