21.03.2013 Views

Problem - Kevin Tafuro

Problem - Kevin Tafuro

Problem - Kevin Tafuro

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

a pointer to data. Instead, they return –1 on failure, and otherwise return the number<br />

of bytes read.<br />

When using standard C runtime functions, we recommend using read( ). If you are<br />

reading from /dev/urandom, read( ) will successfully return unless a signal is delivered<br />

during the call (in which case the call should be made again), the operating system<br />

is misconfigured, or there is some other catastrophic error. Therefore, if read( )<br />

is unsuccessful, retry when the value of errno is EINTR, and fail unconditionally otherwise.<br />

You should also check that the return value is equal to the number of bytes you<br />

requested to read, because some implementations may limit the amount of data you<br />

can read at once from this device. If you get a short read, merely continue to read<br />

until you collect enough data.<br />

When using /dev/random, things are the same if you are performing regular blocking<br />

reads. Of course, if not enough entropy is available, the call will hang until the<br />

requested data is available or until a signal interrupts the call.<br />

If you don’t like that behavior, you can make the file descriptor nonblocking, meaning<br />

that the function will return an error and set errno to EAGAIN if there isn’t enough<br />

data to complete the entire read. Note that if some (but not all) of the requested data<br />

is ready, it will be returned instead of giving an error. In that case, the return value of<br />

read( ) will be smaller than the requested amount.<br />

Given an integer file descriptor, the following code makes the associated descriptor<br />

nonblocking:<br />

#include <br />

#include <br />

#include <br />

void spc_make_fd_nonblocking(int fd) {<br />

int flags;<br />

flags = fcntl(fd, F_GETFL); /* Get flags associated with the descriptor. */<br />

if (flags = = -1) {<br />

perror("spc_make_fd_nonblocking failed on F_GETFL");<br />

exit(-1);<br />

}<br />

flags |= O_NONBLOCK;<br />

/* Now the flags will be the same as before, except with O_NONBLOCK set.<br />

*/<br />

if (fcntl(fd, F_SETFL, flags) = = -1) {<br />

perror("spc_make_fd_nonblocking failed on F_SETFL");<br />

exit(-1);<br />

}<br />

}<br />

Here, we will demonstrate how to use /dev/random and /dev/urandom properly by<br />

binding them to the API we developed in Recipe 11.2. We will implement spc_<br />

entropy( ) by reading from /dev/random in nonblocking mode. We will implement<br />

Using the Standard Unix Randomness Infrastructure | 577<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!