Implement ECMA-119 burn_source and writer thread handling.
At this time, nglibisofs is able to output an image!! Note that communication between writer and read thread is done via a pipe. That will be replaced by a ring buffer in the near future.
This commit is contained in:
parent
2ab23693db
commit
35ef22cdd7
@ -455,7 +455,6 @@ int write_path_tables(Ecma119Image *t)
|
|||||||
Ecma119Node *dir = pathlist[i];
|
Ecma119Node *dir = pathlist[i];
|
||||||
for (j = 0; j < dir->info.dir.nchildren; j++) {
|
for (j = 0; j < dir->info.dir.nchildren; j++) {
|
||||||
Ecma119Node *child = dir->info.dir.children[j];
|
Ecma119Node *child = dir->info.dir.children[j];
|
||||||
//iso_msg_debug(t->image, " bbbbbbbbbb %d %s", j, dir->node->name);
|
|
||||||
if (child->type == ECMA119_DIR) {
|
if (child->type == ECMA119_DIR) {
|
||||||
pathlist[cur++] = child;
|
pathlist[cur++] = child;
|
||||||
}
|
}
|
||||||
@ -541,13 +540,14 @@ int ecma119_writer_create(Ecma119Image *target)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void write_function(Ecma119Image *target)
|
void *write_function(void *arg)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
size_t i;
|
size_t i;
|
||||||
uint8_t buf[BLOCK_SIZE];
|
uint8_t buf[BLOCK_SIZE];
|
||||||
IsoImageWriter *writer;
|
IsoImageWriter *writer;
|
||||||
|
|
||||||
|
Ecma119Image *target = (Ecma119Image*)arg;
|
||||||
iso_msg_debug(target->image, "Starting image writing...");
|
iso_msg_debug(target->image, "Starting image writing...");
|
||||||
|
|
||||||
/* Write System Area, 16 blocks of zeros (ECMA-119, 6.2.1) */
|
/* Write System Area, 16 blocks of zeros (ECMA-119, 6.2.1) */
|
||||||
@ -593,12 +593,14 @@ void write_function(Ecma119Image *target)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
close(target->wrfd);
|
||||||
|
pthread_exit(NULL);
|
||||||
|
|
||||||
write_error:;
|
write_error:;
|
||||||
iso_msg_fatal(target->image, LIBISO_WRITE_ERROR,
|
iso_msg_fatal(target->image, LIBISO_WRITE_ERROR,
|
||||||
"Image write error, code %d", res);
|
"Image write error, code %d", res);
|
||||||
return;
|
close(target->wrfd);
|
||||||
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -686,8 +688,35 @@ int ecma119_image_new(IsoImage *src, Ecma119WriteOpts *opts,
|
|||||||
target->total_size = (target->curblock - target->ms_block) * BLOCK_SIZE;
|
target->total_size = (target->curblock - target->ms_block) * BLOCK_SIZE;
|
||||||
target->vol_space_size = target->curblock - target->ms_block;
|
target->vol_space_size = target->curblock - target->ms_block;
|
||||||
|
|
||||||
/* 4. Start writting thread */
|
/* 4. Create and start writting thread */
|
||||||
//write_function(target);
|
|
||||||
|
/* TODO for now, a pipe to comunicate both threads
|
||||||
|
* TODO replace it with a ring buffer */
|
||||||
|
ret = pipe(&(target->rdfd));
|
||||||
|
if (ret < 0) {
|
||||||
|
ret = ISO_ERROR;
|
||||||
|
goto target_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ensure the thread is created joinable */
|
||||||
|
pthread_attr_init(&(target->th_attr));
|
||||||
|
pthread_attr_setdetachstate(&(target->th_attr), PTHREAD_CREATE_JOINABLE);
|
||||||
|
|
||||||
|
ret = pthread_create(&(target->wthread), NULL, write_function,
|
||||||
|
(void *) target);
|
||||||
|
if (ret != 0) {
|
||||||
|
iso_msg_fatal(target->image, LIBISO_THREAD_ERROR,
|
||||||
|
"Cannot create writer thread");
|
||||||
|
ret = ISO_THREAD_ERROR;
|
||||||
|
goto target_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Notice that once we reach this point, target belongs to the writer
|
||||||
|
* thread and should not be modified until the writer thread finished.
|
||||||
|
* There're however, specific fields in target that can be accessed, or
|
||||||
|
* even modified by the read thread (look inside bs_* functions)
|
||||||
|
*/
|
||||||
|
|
||||||
*img = target;
|
*img = target;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
@ -700,29 +729,62 @@ target_cleanup:;
|
|||||||
static int
|
static int
|
||||||
bs_read(struct burn_source *bs, unsigned char *buf, int size)
|
bs_read(struct burn_source *bs, unsigned char *buf, int size)
|
||||||
{
|
{
|
||||||
// TODO to implement
|
ssize_t ret;
|
||||||
|
int bytes_read = 0;
|
||||||
|
Ecma119Image *t = (Ecma119Image*)bs->data;
|
||||||
|
|
||||||
|
/* make safe against partial buffer returns */
|
||||||
|
while (bytes_read < size) {
|
||||||
|
ret = read(t->rdfd, buf + bytes_read, size - bytes_read);
|
||||||
|
if (ret == 0) {
|
||||||
|
/* EOF */
|
||||||
return 0;
|
return 0;
|
||||||
|
} else if (ret < 0) {
|
||||||
|
/* error */
|
||||||
|
iso_msg_fatal(t->image, LIBISO_READ_ERROR, "Error reading pipe");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
bytes_read += ret;
|
||||||
|
}
|
||||||
|
return bytes_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
static off_t
|
static off_t
|
||||||
bs_get_size(struct burn_source *bs)
|
bs_get_size(struct burn_source *bs)
|
||||||
{
|
{
|
||||||
Ecma119Image *image = (Ecma119Image*)bs->data;
|
Ecma119Image *target = (Ecma119Image*)bs->data;
|
||||||
return image->total_size;
|
return target->total_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bs_free_data(struct burn_source *bs)
|
bs_free_data(struct burn_source *bs)
|
||||||
{
|
{
|
||||||
ecma119_image_free((Ecma119Image*)bs->data);
|
Ecma119Image *target = (Ecma119Image*)bs->data;
|
||||||
|
|
||||||
|
/* TODO ugly, forces a SIG_PIPE if writing not finished,
|
||||||
|
* but I will replace the pipe anyway, so... */
|
||||||
|
close(target->rdfd);
|
||||||
|
|
||||||
|
/* wait until writer thread finishes */
|
||||||
|
pthread_join(target->wthread, NULL);
|
||||||
|
|
||||||
|
iso_msg_debug(target->image, "Writer thread joined");
|
||||||
|
|
||||||
|
/* now we can safety free target */
|
||||||
|
ecma119_image_free(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int bs_set_size(struct burn_source *bs, off_t size)
|
int bs_set_size(struct burn_source *bs, off_t size)
|
||||||
{
|
{
|
||||||
//TODO to implement!!
|
Ecma119Image *target = (Ecma119Image*)bs->data;
|
||||||
// struct ecma119_write_target *t = (struct ecma119_write_target*)bs->data;
|
|
||||||
// t->total_size = size;
|
/*
|
||||||
|
* just set the value to be returned by get_size. This is not used at
|
||||||
|
* all by libisofs, it is here just for helping libburn to correctly pad
|
||||||
|
* the image if needed.
|
||||||
|
*/
|
||||||
|
target->total_size = size;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -754,6 +816,8 @@ int iso_image_create(IsoImage *image, Ecma119WriteOpts *opts,
|
|||||||
source->set_size = bs_set_size;
|
source->set_size = bs_set_size;
|
||||||
source->free_data = bs_free_data;
|
source->free_data = bs_free_data;
|
||||||
source->data = target;
|
source->data = target;
|
||||||
|
|
||||||
|
*burn_src = source;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#define BLOCK_SIZE 2048
|
#define BLOCK_SIZE 2048
|
||||||
|
|
||||||
@ -79,8 +80,12 @@ struct ecma119_image {
|
|||||||
IsoRBTree *files;
|
IsoRBTree *files;
|
||||||
|
|
||||||
/* file descriptors for read and writing image */
|
/* file descriptors for read and writing image */
|
||||||
int wrfd; /* write to here */
|
|
||||||
int rdfd; /* read from here */
|
int rdfd; /* read from here */
|
||||||
|
int wrfd; /* write to here */
|
||||||
|
|
||||||
|
/* writer thread descriptor */
|
||||||
|
pthread_t wthread;
|
||||||
|
pthread_attr_t th_attr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BP(a,b) [(b) - (a) + 1]
|
#define BP(a,b) [(b) - (a) + 1]
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#define ISO_WRONG_ARG_VALUE -6
|
#define ISO_WRONG_ARG_VALUE -6
|
||||||
|
|
||||||
#define ISO_WRITE_ERROR -10
|
#define ISO_WRITE_ERROR -10
|
||||||
|
#define ISO_THREAD_ERROR -11
|
||||||
|
|
||||||
#define ISO_NODE_ALREADY_ADDED -50
|
#define ISO_NODE_ALREADY_ADDED -50
|
||||||
#define ISO_NODE_NAME_NOT_UNIQUE -51
|
#define ISO_NODE_NAME_NOT_UNIQUE -51
|
||||||
|
@ -386,6 +386,8 @@ Range "vreixo" : 0x00030000 to 0x0003ffff
|
|||||||
0x00030100 (NOTE,MEDIUM) = File cannot be added to image (ignored)
|
0x00030100 (NOTE,MEDIUM) = File cannot be added to image (ignored)
|
||||||
0x00030101 (NOTE,MEDIUM) = File cannot be writing to image (ignored)
|
0x00030101 (NOTE,MEDIUM) = File cannot be writing to image (ignored)
|
||||||
0x00030102 (FATAL,HIGH) = Write error
|
0x00030102 (FATAL,HIGH) = Write error
|
||||||
|
0x00030103 (FATAL,HIGH) = Read error
|
||||||
|
0x00030110 (FATAL,HIGH) = Cannot create writer thread
|
||||||
|
|
||||||
General:
|
General:
|
||||||
0x00031001 (SORRY,HIGH) = Cannot read file (ignored)
|
0x00031001 (SORRY,HIGH) = Cannot read file (ignored)
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
struct burn_source;
|
||||||
|
|
||||||
typedef struct Iso_Image IsoImage;
|
typedef struct Iso_Image IsoImage;
|
||||||
|
|
||||||
typedef struct Iso_Node IsoNode;
|
typedef struct Iso_Node IsoNode;
|
||||||
@ -153,6 +155,9 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
int iso_image_new(const char *name, IsoImage **image);
|
int iso_image_new(const char *name, IsoImage **image);
|
||||||
|
|
||||||
|
int iso_image_create(IsoImage *image, Ecma119WriteOpts *opts,
|
||||||
|
struct burn_source **burn_src);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increments the reference counting of the given image.
|
* Increments the reference counting of the given image.
|
||||||
*/
|
*/
|
||||||
|
@ -19,8 +19,12 @@
|
|||||||
#define LIBISO_FILE_IGNORED 0x00030100
|
#define LIBISO_FILE_IGNORED 0x00030100
|
||||||
/** File cannot be writing to image (ignored) */
|
/** File cannot be writing to image (ignored) */
|
||||||
#define LIBISO_FILE_CANT_WRITE 0x00030101
|
#define LIBISO_FILE_CANT_WRITE 0x00030101
|
||||||
|
/** Read error */
|
||||||
|
#define LIBISO_READ_ERROR 0x00030102
|
||||||
/** Write error */
|
/** Write error */
|
||||||
#define LIBISO_WRITE_ERROR 0x00030102
|
#define LIBISO_WRITE_ERROR 0x00030103
|
||||||
|
/** Cannot create writer thread */
|
||||||
|
#define LIBISO_THREAD_ERROR 0x00030110
|
||||||
|
|
||||||
|
|
||||||
/** Can't read file (ignored) */
|
/** Can't read file (ignored) */
|
||||||
|
Loading…
Reference in New Issue
Block a user