STIOC_READ_POSITION_EX
This IOCTL returns tape position with support for the short, long, and extended formats. The definitions and data structures that are used for this IOCTL follow. See the READ_POSITION section of your tape drive’s SCSI documentation for details on the short_data_format, long_data_format, and extended_data_format structures.
#define RP_SHORT_FORM (0x00)
#define RP_LONG_FORM (0x06)
#define RP_EXTENDED_FORM (0x08)
struct short_data_format {
#if defined __LITTLE_ENDIAN
unchar bpew : 1;
unchar perr : 1;
unchar lolu : 1;
unchar rsvd : 1;
unchar bycu : 1;
unchar locu : 1;
unchar eop : 1;
unchar bop : 1;
#elif defined __BIG_ENDIAN
unchar bop : 1;
unchar eop : 1;
unchar locu : 1;
unchar bycu : 1;unchar rsvd : 1;
unchar lolu : 1;
unchar perr : 1;
unchar bpew : 1;
#else
error
#endif
unchar active_partition;
char reserved[2];
unchar first_logical_obj_position[4];
unchar last_logical_obj_position[4];
unchar num_buffer_logical_obj[4];
unchar num_buffer_bytes[4];
char reserved1;
};
struct long_data_format {
#if defined __LITTLE_ENDIAN
unchar bpew : 1;
unchar rsvd2 : 1;
unchar lonu : 1;
unchar mpu : 1;
unchar rsvd1 : 2;
unchar eop : 1;
unchar bop : 1;
#elif defined __BIG_ENDIAN
unchar bop : 1;
unchar eop : 1;
unchar rsvd1 : 2;
unchar mpu : 1;
unchar lonu : 1;
unchar rsvd2 : 1;
unchar bpew : 1;
#else
error
#endif
char reserved[6];
unchar active_partition;
unchar logical_obj_number[8];
unchar logical_file_id[8];
unchar obsolete[8];
};
struct extended_data_format {
#if defined __LITTLE_ENDIAN
unchar bpew : 1;
unchar perr : 1;
unchar lolu : 1;
unchar rsvd : 1;
unchar bycu : 1;
unchar locu : 1;
unchar eop : 1;
unchar bop : 1;
#elif defined __BIG_ENDIAN
unchar bop : 1;
unchar eop : 1;
unchar locu : 1;
unchar bycu : 1;
unchar rsvd : 1;
unchar lolu : 1;
unchar perr : 1;
unchar bpew : 1;
#else
error
#endif
unchar active_partition;
unchar additional_length[2];
unchar num_buffer_logical_obj[4];
unchar first_logical_obj_position[8];
unchar last_logical_obj_position[8];
unchar num_buffer_bytes[8];
unchar reserved;
};
struct read_tape_position {
unchar data_format;
union {
struct short_data_format rp_short;
struct long_data_format rp_long;
struct extended_data_format rp_extended;
} rp_data;
};
data_format
is the format in which
you want to receive your data, as defined here. It can take the value RP_SHORT_FORM
, RP_LONG_FORM
,
or RP_EXTENDED_FORM
. When the IOCTL finishes, data
is returned to the corresponding structure within the rp_data union.An example of the use of the STIOC_READ_POSITION_EX IOCTL
is
int stioc_read_position_ex(void)
{
int rc = 0;
char* input = NULL;
struct read_tape_position rp = {0};
printf("Note: only supported on LTO 5 and higher drives\n");
input = malloc(DEF_BUF_SIZE / 16);
if(!input) {
rc = ENOMEM;
goto EXIT_LABEL;
} /* if */
memset(input, '\0', DEF_BUF_SIZE / 16);
while(input[0] == '\0' || atoi(input) < 0 || atoi(input) > 3) {
printf("0) Cancel\n");
printf("1) Short Form\n");
printf("2) Long Form\n");
printf("3) Extended Form\n");
printf("\nPlease select: ");
fgets(input, DEF_BUF_SIZE / 16, stdin);
if(!atoi(input)) {
rc = 0;
goto EXIT_LABEL;
} /* if */
} /* while */
memset(&rp, '\0', sizeof(struct read_tape_position));
switch(atoi(input)) {
case 1:
rp.data_format = RP_SHORT_FORM;
break;
case 2:
rp.data_format = RP_LONG_FORM;
break;
case 3:
rp.data_format = RP_EXTENDED_FORM;
break;
default:
rc = EINVAL;
goto EXIT_LABEL;
} /* switch */
rc = ioctl(fd, STIOC_READ_POSITION_EX, &rp);
if(rc) {
printf("Cannot get position: %d\n", rc = errno);
goto EXIT_LABEL;
} /* if */
print_read_position_ex(&rp);
EXIT_LABEL:
if(input) free(input);
return rc;
} /* stioc_read_position_ex() */