Makistos
6/26/2017 - 10:07 AM

A proper way of using ioctl() and errno. #linux #c #errno #ioctl

A proper way of using ioctl() and errno. #linux #c #errno #ioctl

static unsigned char commit_ioctl()
{
	int block_dev = -1;
	int error_code = 0;
	int retval = 0;
	unsigned retry_count = 0;

	errno = 0; /* Clear errno - successfull function calls might leave old value. */
	block_dev = open(block_dev_name, O_RDWR);
	/* Need to save errno as it might be reset by library calls. */
	error_code = errno; 

	if (block_dev == -1) {
		LOGE("Failed to open %s with: %s.", block_dev_name, strerror(error_code));
	} else {
		for(retry_count=0;retry_count<IOCTL_RETRY_MAX;retry_count++) {
			retval = ioctl(block_dev, BLKCOMMAND);
			error_code = errno;
			if (retval !=  -1 || error_code != EAGAIN) {
				break;
			}
			usleep(IOCTL_DELAY);
		}
		if (retval == -1) {
			LOGE("Ioctl failed on %s with: %s (retry_count %d)",
					block_dev_name, strerror(error_code), retry_count);
		} else {
			/* In case we got an EAGAIN but then ioctl() worked,
			 * we need to reset return value. */
			error_code = 0;
			LOGI("Ioctl operation succeeded.");
		}
		close(block_dev);
	}
	return error_code;
}