diff --git a/sys/dev/rndpseudo.c b/sys/dev/rndpseudo.c index 07f505677ca4..d4d1fa3031ee 100644 --- a/sys/dev/rndpseudo.c +++ b/sys/dev/rndpseudo.c @@ -1,4 +1,4 @@ -/* $NetBSD: rndpseudo.c,v 1.16 2013/07/21 22:30:19 riastradh Exp $ */ +/* $NetBSD: rndpseudo.c,v 1.17 2013/09/25 03:14:55 riastradh Exp $ */ /*- * Copyright (c) 1997-2013 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.16 2013/07/21 22:30:19 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.17 2013/09/25 03:14:55 riastradh Exp $"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -389,18 +389,32 @@ rnd_read(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred, goto out; /* - * Do at most one iteration for /dev/random and return - * a short read without hanging further. Hanging - * breaks applications worse than short reads. Reads - * can't be zero unless nonblocking from /dev/random; - * in that case, ask caller to retry, instead of just - * returning zero bytes, which means EOF. + * For /dev/urandom: Reads always succeed in full, no + * matter how many iterations that takes. (XXX But + * this means the computation can't be interrupted, + * wihch seems suboptimal.) + * + * For /dev/random, nonblocking: Reads succeed with as + * many bytes as a single request can return without + * blocking, or fail with EAGAIN if a request would + * block. (There is no sense in trying multiple + * requests because if the first one didn't fill the + * buffer, the second one would almost certainly + * block.) + * + * For /dev/random, blocking: Reads succeed with as + * many bytes as a single request -- which may block -- + * can return if uninterrupted, or fail with EINTR if + * the request is interrupted. */ - KASSERT((0 < n_read) || (ctx->rc_hard && - ISSET(fp->f_flag, FNONBLOCK))); + KASSERT((0 < n_read) || ctx->rc_hard); if (ctx->rc_hard) { - if (n_read == 0) + if (0 < n_read) + error = 0; + else if (ISSET(fp->f_flag, FNONBLOCK)) error = EAGAIN; + else + error = EINTR; goto out; } }