Forced role 3 on drives which stem from open file descriptors without O_RDWR

This commit is contained in:
Thomas Schmitt 2011-02-09 11:43:10 +00:00
parent 478bcdc1e2
commit 2c37215969
3 changed files with 84 additions and 32 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2011.01.18.162859"
#define Cdrskin_timestamP "2011.02.09.114311"

View File

@ -24,6 +24,7 @@
#include <ctype.h>
#include <pthread.h>
#include <errno.h>
#include <fcntl.h>
#include "libburn.h"
#include "init.h"
#include "drive.h"
@ -1355,11 +1356,50 @@ int burn_drive__fd_from_special_adr(char *adr)
}
static int burn_drive__is_rdwr(char *fname, int *stat_ret,
struct stat *stbuf_ret,
off_t *read_size_ret, int flag)
{
int fd, is_rdwr, ret, getfl_ret, st_ret;
struct stat stbuf;
off_t read_size;
memset(&stbuf, 0, sizeof(stbuf));
fd = burn_drive__fd_from_special_adr(fname);
if (fd >= 0)
st_ret = fstat(fd, &stbuf);
else
st_ret = stat(fname, &stbuf);
if (st_ret != -1) {
is_rdwr = burn_os_is_2k_seekrw(fname, 0);
if (S_ISREG(stbuf.st_mode))
read_size = stbuf.st_size;
else if (is_rdwr) {
ret = burn_os_stdio_capacity(fname, &read_size);
if (ret <= 0)
read_size = (off_t) 0x7ffffff0 * (off_t) 2048;
}
}
if (is_rdwr && fd >= 0) {
getfl_ret = fcntl(fd, F_GETFL);
if (getfl_ret == -1 || (getfl_ret & O_RDWR) != O_RDWR)
is_rdwr = 0;
}
if (stat_ret != NULL)
*stat_ret = st_ret;
if (stbuf_ret != NULL)
memcpy(stbuf_ret, &stbuf, sizeof(stbuf));
if (read_size_ret != NULL)
*read_size_ret = read_size;
return is_rdwr;
}
/* ts A70903 : Implements adquiration of pseudo drives */
int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
{
int ret = -1, fd = -1, role = 0;
int is_block_dev = 0;
int ret = -1, role = 0;
int is_rdwr = 0, stat_ret;
/* divided by 512 it needs to fit into a signed long integer */
off_t size = ((off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048);
off_t read_size = -1;
@ -1369,25 +1409,9 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
static int allow_role_3 = 1;
if (fname[0] != 0) {
memset(&stbuf, 0, sizeof(stbuf));
fd = burn_drive__fd_from_special_adr(fname);
if (fd >= 0)
ret = fstat(fd, &stbuf);
else
ret = stat(fname, &stbuf);
if (ret != -1) {
is_block_dev = burn_os_is_2k_seekrw(fname, 0);
if (S_ISREG(stbuf.st_mode))
read_size = stbuf.st_size;
else if (is_block_dev) {
ret = burn_os_stdio_capacity(fname,
&read_size);
if (ret <= 0)
read_size = (off_t) 0x7ffffff0 *
(off_t) 2048;
}
}
if (ret == -1 || is_block_dev || S_ISREG(stbuf.st_mode)) {
is_rdwr = burn_drive__is_rdwr(fname, &stat_ret, &stbuf,
&read_size, 0);
if (stat_ret == -1 || is_rdwr) {
ret = burn_os_stdio_capacity(fname, &size);
if (ret == -1) {
libdax_msgs_submit(libdax_messenger, -1,
@ -2643,26 +2667,49 @@ int burn_drive_equals_adr(struct burn_drive *d1, char *adr2_in, int role2)
char adr1[BURN_DRIVE_ADR_LEN], *adr2 = adr2_in;
char conv_adr1[BURN_DRIVE_ADR_LEN], conv_adr2[BURN_DRIVE_ADR_LEN];
char *npt1, *dpt1, *npt2, *dpt2;
int role1, stat_ret1, stat_ret2, conv_ret2;
int role1, stat_ret1, stat_ret2, conv_ret2, exact_role_matters = 0, fd;
int ret;
role1 = burn_drive_get_drive_role(d1);
burn_drive_d_get_adr(d1, adr1);
stat_ret1 = stat(adr1, &stbuf1);
/* If one of the candidate paths depicts an open file descriptor then
its read-write capability decides about its role and the difference
between roles 2 and 3 does matter.
*/
fd = burn_drive__fd_from_special_adr(d1->devname);
if (fd != -1)
exact_role_matters = 1;
if (strncmp(adr2, "stdio:", 6) == 0) {
adr2+= 6;
role2 = (!!adr2[0]) * 2;
if (adr2[0] == 0) {
role2 = 0;
} else {
fd = burn_drive__fd_from_special_adr(adr2);
if (fd != -1)
exact_role_matters = 1;
ret = burn_drive__is_rdwr(adr2, NULL, NULL, NULL, 0);
if (ret == 1)
role2 = 2;
else
role2 = 3;
}
}
if (strlen(adr2) >= BURN_DRIVE_ADR_LEN)
return -1;
stat_ret2 = stat(adr2, &stbuf2);
conv_ret2 = burn_drive_convert_fs_adr(adr2, conv_adr2);
/* roles 2 and 3 have the same name space and object interpretation */
if (role1 == 3)
role1 = 2;
if (role2 == 3)
role2 = 2;
if (!exact_role_matters) {
/* roles 2 and 3 have the same name space and object
interpretation */
if (role1 == 3)
role1 = 2;
if (role2 == 3)
role2 = 2;
}
if (strcmp(adr1, adr2) == 0 && role1 == role2)
return(1); /* equal role and address */
@ -2680,6 +2727,8 @@ int burn_drive_equals_adr(struct burn_drive *d1, char *adr2_in, int role2)
else if (role1 != 1 && role2 != 1) {
/* pseudo-drive meets file object */
if (role1 != role2)
return 0;
if (stat_ret1 == -1 || stat_ret2 == -1) {
if (stat_ret1 != -1 || stat_ret2 != -1)
return 0; /* one adress existing, one not */

View File

@ -2034,6 +2034,7 @@ int burn_stdio_open_write(struct burn_drive *d, off_t start_byte,
int fd = -1;
int mode = O_RDWR | O_CREAT | O_LARGEFILE;
char msg[160];
off_t lseek_res;
if (d->devname[0] == 0) /* null drives should not come here */
return -1;
@ -2053,10 +2054,11 @@ int burn_stdio_open_write(struct burn_drive *d, off_t start_byte,
}
if (start_byte < 0)
start_byte = 0;
if (d->drive_role == 2)
if (lseek(fd, start_byte, SEEK_SET)==-1) {
if (d->drive_role == 2) {
lseek_res = lseek(fd, start_byte, SEEK_SET);
if (lseek_res == -1) {
sprintf(msg, "Cannot address start byte %.f",
(double) start_byte);
(double) start_byte);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020147,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
@ -2065,6 +2067,7 @@ int burn_stdio_open_write(struct burn_drive *d, off_t start_byte,
d->cancel = 1;
fd = -1;
}
}
d->nwa = start_byte / sector_size;
return fd;
}