summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-05-23 07:47:55 +0200
committerChristian Brabandt <cb@256bit.org>2024-05-23 07:47:55 +0200
commit701ad50a9efcf0adfe6d787b606c4e4dbd31f26d (patch)
treea9f93efb26cf90fe4ea9cbb79d1059d07bd345b2
parentf2d74e3b63e8ba4ed620ae41119929b327c7cfbf (diff)
patch 9.1.0433: Wrong yanking with exclusive selection and ve=allv9.1.0433
Problem: Wrong yanking with exclusive selection and virtualedit=all, and integer overflow when using getregion() on it. Solution: Set coladd when decreasing column and 'virtualedit' is active. Add more tests for getregion() with 'virtualedit' (zeertzjq). closes: #14830 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
-rw-r--r--src/evalfunc.c29
-rw-r--r--src/normal.c47
-rw-r--r--src/proto/normal.pro1
-rw-r--r--src/testdir/test_visual.vim193
-rw-r--r--src/version.c2
5 files changed, 228 insertions, 44 deletions
diff --git a/src/evalfunc.c b/src/evalfunc.c
index b65df5dd90..f70b032ad2 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -5594,31 +5594,12 @@ getregionpos(
if (*region_type == MCHAR)
{
- // handle 'selection' == "exclusive"
+ // Handle 'selection' == "exclusive".
if (is_select_exclusive && !EQUAL_POS(*p1, *p2))
- {
- if (p2->coladd > 0)
- p2->coladd--;
- else if (p2->col > 0)
- {
- p2->col--;
-
- mb_adjustpos(curbuf, p2);
- }
- else if (p2->lnum > 1)
- {
- p2->lnum--;
- p2->col = ml_get_len(p2->lnum);
- if (p2->col > 0)
- {
- p2->col--;
-
- mb_adjustpos(curbuf, p2);
- }
- }
- }
- // if fp2 is on NUL (empty line) inclusive becomes false
- if (*ml_get_pos(p2) == NUL && !virtual_op)
+ // When backing up to previous line, inclusive becomes false.
+ *inclusive = !unadjust_for_sel_inner(p2);
+ // If p2 is on NUL (end of line), inclusive becomes false.
+ if (*inclusive && !virtual_op && *ml_get_pos(p2) == NUL)
*inclusive = FALSE;
}
else if (*region_type == MBLOCK)
diff --git a/src/normal.c b/src/normal.c
index 38c6bad80f..b55d941fcc 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -6696,29 +6696,40 @@ adjust_for_sel(cmdarg_T *cap)
int
unadjust_for_sel(void)
{
- pos_T *pp;
-
if (*p_sel == 'e' && !EQUAL_POS(VIsual, curwin->w_cursor))
+ return unadjust_for_sel_inner(LT_POS(VIsual, curwin->w_cursor)
+ ? &curwin->w_cursor : &VIsual);
+ return FALSE;
+}
+
+/*
+ * Move position "*pp" back one character for 'selection' == "exclusive".
+ * Returns TRUE when backed up to the previous line.
+ */
+ int
+unadjust_for_sel_inner(pos_T *pp)
+{
+ colnr_T cs, ce;
+
+ if (pp->coladd > 0)
+ --pp->coladd;
+ else if (pp->col > 0)
{
- if (LT_POS(VIsual, curwin->w_cursor))
- pp = &curwin->w_cursor;
- else
- pp = &VIsual;
- if (pp->coladd > 0)
- --pp->coladd;
- else
- if (pp->col > 0)
- {
- --pp->col;
- mb_adjustpos(curbuf, pp);
- }
- else if (pp->lnum > 1)
+ --pp->col;
+ mb_adjustpos(curbuf, pp);
+ if (virtual_active())
{
- --pp->lnum;
- pp->col = ml_get_len(pp->lnum);
- return TRUE;
+ getvcol(curwin, pp, &cs, NULL, &ce);
+ pp->coladd = ce - cs;
}
}
+ else if (pp->lnum > 1)
+ {
+ --pp->lnum;
+ pp->col = ml_get_len(pp->lnum);
+ return TRUE;
+ }
+
return FALSE;
}
diff --git a/src/proto/normal.pro b/src/proto/normal.pro
index 6dcbe414fc..36a26ec480 100644
--- a/src/proto/normal.pro
+++ b/src/proto/normal.pro
@@ -31,5 +31,6 @@ int get_visual_text(cmdarg_T *cap, char_u **pp, int *lenp);
void start_selection(void);
void may_start_select(int c);
int unadjust_for_sel(void);
+int unadjust_for_sel_inner(pos_T *pp);
void set_cursor_for_append_to_line(void);
/* vim: set ft=c : */
diff --git a/src/testdir/test_visual.vim b/src/testdir/test_visual.vim
index 621be298d6..febf67855c 100644
--- a/src/testdir/test_visual.vim
+++ b/src/testdir/test_visual.vim
@@ -1631,6 +1631,22 @@ func Test_visual_substitute_visual()
bwipe!
endfunc
+func Test_virtualedit_exclusive_selection()
+ new
+ set virtualedit=all selection=exclusive
+
+ call setline(1, "a\tb")
+ normal! 0v8ly
+ call assert_equal("a\t", getreg('"'))
+ normal! 0v6ly
+ call assert_equal('a ', getreg('"'))
+ normal! 06lv2ly
+ call assert_equal(' ', getreg('"'))
+
+ set virtualedit& selection&
+ bwipe!
+endfunc
+
func Test_visual_getregion()
let lines =<< trim END
new
@@ -2012,38 +2028,114 @@ func Test_visual_getregion()
#" Exclusive selection 2
new
call setline(1, ["a\tc", "x\tz", '', ''])
+
call cursor(1, 1)
call feedkeys("\<Esc>v2l", 'xt')
call assert_equal(["a\t"],
\ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
+
call cursor(1, 1)
call feedkeys("\<Esc>v$G", 'xt')
call assert_equal(["a\tc", "x\tz", ''],
\ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
+
call cursor(1, 1)
call feedkeys("\<Esc>v$j", 'xt')
call assert_equal(["a\tc", "x\tz"],
\ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
+
call cursor(1, 1)
call feedkeys("\<Esc>\<C-v>$j", 'xt')
call assert_equal(["a\tc", "x\tz"],
\ getregion(getpos('v'), getpos('.'),
\ {'exclusive': v:true, 'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'exclusive': v:true, 'type': "\<C-v>" }))
+
call cursor(1, 1)
call feedkeys("\<Esc>\<C-v>$G", 'xt')
call assert_equal(["a", "x", '', ''],
\ getregion(getpos('v'), getpos('.'),
\ {'exclusive': v:true, 'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
+ \ [[bufnr('%'), 4, 0, 0], [bufnr('%'), 4, 0, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'exclusive': v:true, 'type': "\<C-v>" }))
+
call cursor(1, 1)
call feedkeys("\<Esc>wv2j", 'xt')
call assert_equal(["c", "x\tz"],
\ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
- #" virtualedit
+ #" 'virtualedit' with exclusive selection
set selection=exclusive
set virtualedit=all
call cursor(1, 1)
+ call feedkeys("\<Esc>vj", 'xt')
+ call assert_equal(["a\tc"],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>v8l", 'xt')
+ call assert_equal(["a\t"],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>v6l", 'xt')
+ call assert_equal(['a '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 5]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>6lv2l", 'xt')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 2, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
call feedkeys("\<Esc>lv2l", 'xt')
call assert_equal([' '],
\ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
@@ -2102,9 +2194,106 @@ func Test_visual_getregion()
\ ],
\ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
- set virtualedit&
+ #" 'virtualedit' with inclusive selection
set selection&
+ call cursor(1, 1)
+ call feedkeys("\<Esc>vj", 'xt')
+ call assert_equal(["a\tc", 'x'],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>v8l", 'xt')
+ call assert_equal(["a\tc"],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>v6l", 'xt')
+ call assert_equal(['a '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 6]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>6lv2l", 'xt')
+ call assert_equal([' c'],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>lv2l", 'xt')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>2lv2l", 'xt')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call feedkeys('j', 'xt')
+ call assert_equal([' c', 'x '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 4]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>6l\<C-v>2lj", 'xt')
+ call assert_equal([' c', ' z'],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>l\<C-v>2l2j", 'xt')
+ call assert_equal([' ', ' ', ' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
+ \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 3]],
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 3]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>2l\<C-v>2l2j", 'xt')
+ call assert_equal([' ', ' ', ' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
+ \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 4]],
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 3]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+
+ set virtualedit&
bwipe!
END
call v9.CheckLegacyAndVim9Success(lines)
diff --git a/src/version.c b/src/version.c
index b37dbcf857..c4bccb447e 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 433,
+/**/
432,
/**/
431,
'>734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915
/*
 * Copyright (c) 2000 Damien Miller.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "includes.h"

#include <openssl/rand.h>
#include <openssl/sha.h>
#include <openssl/crypto.h>

/* SunOS 4.4.4 needs this */
#ifdef HAVE_FLOATINGPOINT_H
# include <floatingpoint.h>
#endif /* HAVE_FLOATINGPOINT_H */

#include "ssh.h"
#include "misc.h"
#include "xmalloc.h"
#include "atomicio.h"
#include "pathnames.h"
#include "log.h"

RCSID("$Id: entropy.c,v 1.37 2001/06/27 13:36:08 djm Exp $");

#ifndef offsetof
# define offsetof(type, member) ((size_t) &((type *)0)->member)
#endif

/* Number of times to pass through command list gathering entropy */
#define NUM_ENTROPY_RUNS	1

/* Scale entropy estimates back by this amount on subsequent runs */
#define SCALE_PER_RUN		10.0

/* Minimum number of commands to be considered valid */
#define MIN_ENTROPY_SOURCES 16

#define WHITESPACE " \t\n"

#ifndef RUSAGE_SELF
# define RUSAGE_SELF 0
#endif
#ifndef RUSAGE_CHILDREN
# define RUSAGE_CHILDREN 0
#endif

#if defined(_POSIX_SAVED_IDS) && !defined(BROKEN_SAVED_UIDS)
# define SAVED_IDS_WORK_WITH_SETEUID
#endif

static void
check_openssl_version(void) 
{
	if (SSLeay() != OPENSSL_VERSION_NUMBER)
		fatal("OpenSSL version mismatch. Built against %lx, you "
		    "have %lx", OPENSSL_VERSION_NUMBER, SSLeay());
}

#if defined(PRNGD_SOCKET) || defined(PRNGD_PORT)
# define USE_PRNGD
#endif

#if defined(USE_PRNGD) || defined(RANDOM_POOL)

#ifdef USE_PRNGD
/* Collect entropy from PRNGD/EGD */
int
get_random_bytes(unsigned char *buf, int len)
{
	int fd;
	char msg[2];
#ifdef PRNGD_PORT
	struct sockaddr_in addr;
#else
	struct sockaddr_un addr;
#endif
	int addr_len, rval, errors;
	mysig_t old_sigpipe;

	memset(&addr, '\0', sizeof(addr));

#ifdef PRNGD_PORT
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	addr.sin_port = htons(PRNGD_PORT);
	addr_len = sizeof(struct sockaddr_in);
#else /* use IP socket PRNGD_SOCKET instead */
	/* Sanity checks */
	if (sizeof(PRNGD_SOCKET) > sizeof(addr.sun_path))
		fatal("Random pool path is too long");
	if (len > 255)
		fatal("Too many bytes to read from PRNGD");

	addr.sun_family = AF_UNIX;
	strlcpy(addr.sun_path, PRNGD_SOCKET, sizeof(addr.sun_path));
	addr_len = offsetof(struct sockaddr_un, sun_path) +
	    sizeof(PRNGD_SOCKET);
#endif

	old_sigpipe = mysignal(SIGPIPE, SIG_IGN);

	errors = rval = 0;
reopen:
#ifdef PRNGD_PORT
	fd = socket(addr.sin_family, SOCK_STREAM, 0);
	if (fd == -1) {
		error("Couldn't create AF_INET socket: %s", strerror(errno));
		goto done;
	}
#else
	fd = socket(addr.sun_family, SOCK_STREAM, 0);
	if (fd == -1) {
		error("Couldn't create AF_UNIX socket: %s", strerror(errno));
		goto done;
	}
#endif

	if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) {
#ifdef PRNGD_PORT
		error("Couldn't connect to PRNGD port %d: %s",
		    PRNGD_PORT, strerror(errno));
#else
		error("Couldn't connect to PRNGD socket \"%s\": %s",
		    addr.sun_path, strerror(errno));
#endif
		goto done;
	}

	/* Send blocking read request to PRNGD */
	msg[0] = 0x02;
	msg[1] = len;

	if (atomicio(write, fd, msg, sizeof(msg)) != sizeof(msg)) {
		if (errno == EPIPE && errors < 10) {
			close(fd);
			errors++;
			goto reopen;
		}
		error("Couldn't write to PRNGD socket: %s",
		    strerror(errno));
		goto done;
	}

	if (atomicio(read, fd, buf, len) != len) {
		if (errno == EPIPE && errors < 10) {
			close(fd);
			errors++;
			goto reopen;
		}
		error("Couldn't read from PRNGD socket: %s",
		    strerror(errno));
		goto done;
	}

	rval = 1;
done:
	mysignal(SIGPIPE, old_sigpipe);
	if (fd != -1)
		close(fd);
	return(rval);
}
#else /* !USE_PRNGD */
#ifdef RANDOM_POOL
/* Collect entropy from /dev/urandom or pipe */
static int
get_random_bytes(unsigned char *buf, int len)
{
	int random_pool;

	random_pool = open(RANDOM_POOL, O_RDONLY);
	if (