diff options
Diffstat (limited to 'entropy.c')
-rw-r--r-- | entropy.c | 41 |
1 files changed, 29 insertions, 12 deletions
@@ -38,7 +38,7 @@ | |||
38 | #include "pathnames.h" | 38 | #include "pathnames.h" |
39 | #include "log.h" | 39 | #include "log.h" |
40 | 40 | ||
41 | RCSID("$Id: entropy.c,v 1.26 2001/02/05 12:42:17 stevesk Exp $"); | 41 | RCSID("$Id: entropy.c,v 1.27 2001/02/18 01:44:29 djm Exp $"); |
42 | 42 | ||
43 | #ifndef offsetof | 43 | #ifndef offsetof |
44 | # define offsetof(type, member) ((size_t) &((type *)0)->member) | 44 | # define offsetof(type, member) ((size_t) &((type *)0)->member) |
@@ -71,7 +71,8 @@ int get_random_bytes(unsigned char *buf, int len) | |||
71 | int fd; | 71 | int fd; |
72 | char msg[2]; | 72 | char msg[2]; |
73 | struct sockaddr_un addr; | 73 | struct sockaddr_un addr; |
74 | int addr_len; | 74 | int addr_len, rval, errors; |
75 | struct sigaction nsa, osa; | ||
75 | 76 | ||
76 | /* Sanity checks */ | 77 | /* Sanity checks */ |
77 | if (sizeof(EGD_SOCKET) > sizeof(addr.sun_path)) | 78 | if (sizeof(EGD_SOCKET) > sizeof(addr.sun_path)) |
@@ -84,17 +85,22 @@ int get_random_bytes(unsigned char *buf, int len) | |||
84 | strlcpy(addr.sun_path, EGD_SOCKET, sizeof(addr.sun_path)); | 85 | strlcpy(addr.sun_path, EGD_SOCKET, sizeof(addr.sun_path)); |
85 | addr_len = offsetof(struct sockaddr_un, sun_path) + sizeof(EGD_SOCKET); | 86 | addr_len = offsetof(struct sockaddr_un, sun_path) + sizeof(EGD_SOCKET); |
86 | 87 | ||
88 | memset(&nsa, 0, sizeof(nsa)); | ||
89 | nsa.sa_handler = SIG_IGN; | ||
90 | (void) sigaction(SIGPIPE, &nsa, &osa); | ||
91 | |||
92 | errors = rval = 0; | ||
93 | reopen: | ||
87 | fd = socket(AF_UNIX, SOCK_STREAM, 0); | 94 | fd = socket(AF_UNIX, SOCK_STREAM, 0); |
88 | if (fd == -1) { | 95 | if (fd == -1) { |
89 | error("Couldn't create AF_UNIX socket: %s", strerror(errno)); | 96 | error("Couldn't create AF_UNIX socket: %s", strerror(errno)); |
90 | return(0); | 97 | goto done; |
91 | } | 98 | } |
92 | 99 | ||
93 | if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) { | 100 | if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) { |
94 | error("Couldn't connect to EGD socket \"%s\": %s", | 101 | error("Couldn't connect to EGD socket \"%s\": %s", |
95 | addr.sun_path, strerror(errno)); | 102 | addr.sun_path, strerror(errno)); |
96 | close(fd); | 103 | goto done; |
97 | return(0); | ||
98 | } | 104 | } |
99 | 105 | ||
100 | /* Send blocking read request to EGD */ | 106 | /* Send blocking read request to EGD */ |
@@ -102,22 +108,33 @@ int get_random_bytes(unsigned char *buf, int len) | |||
102 | msg[1] = len; | 108 | msg[1] = len; |
103 | 109 | ||
104 | if (atomicio(write, fd, msg, sizeof(msg)) != sizeof(msg)) { | 110 | if (atomicio(write, fd, msg, sizeof(msg)) != sizeof(msg)) { |
111 | if (errno == EPIPE && errors < 10) { | ||
112 | close(fd); | ||
113 | errors++; | ||
114 | goto reopen; | ||
115 | } | ||
105 | error("Couldn't write to EGD socket \"%s\": %s", | 116 | error("Couldn't write to EGD socket \"%s\": %s", |
106 | EGD_SOCKET, strerror(errno)); | 117 | EGD_SOCKET, strerror(errno)); |
107 | close(fd); | 118 | goto done; |
108 | return(0); | ||
109 | } | 119 | } |
110 | 120 | ||
111 | if (atomicio(read, fd, buf, len) != len) { | 121 | if (atomicio(read, fd, buf, len) != len) { |
122 | if (errno == EPIPE && errors < 10) { | ||
123 | close(fd); | ||
124 | errors++; | ||
125 | goto reopen; | ||
126 | } | ||
112 | error("Couldn't read from EGD socket \"%s\": %s", | 127 | error("Couldn't read from EGD socket \"%s\": %s", |
113 | EGD_SOCKET, strerror(errno)); | 128 | EGD_SOCKET, strerror(errno)); |
114 | close(fd); | 129 | goto done; |
115 | return(0); | ||
116 | } | 130 | } |
117 | 131 | ||
118 | close(fd); | 132 | rval = 1; |
119 | 133 | done: | |
120 | return(1); | 134 | (void) sigaction(SIGPIPE, &osa, NULL); |
135 | if (fd != -1) | ||
136 | close(fd); | ||
137 | return(rval); | ||
121 | } | 138 | } |
122 | #else /* !EGD_SOCKET */ | 139 | #else /* !EGD_SOCKET */ |
123 | #ifdef RANDOM_POOL | 140 | #ifdef RANDOM_POOL |