Define code style formatter for eclipse and apply it to source.
This commit is contained in:
parent
1ecb735e7c
commit
4c9d83f051
@ -313,6 +313,7 @@
|
||||
</profile>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
|
||||
</cconfiguration>
|
||||
<cconfiguration id="converted.config.2029700129.1058518760.974771800">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="converted.config.2029700129.1058518760.974771800" moduleId="org.eclipse.cdt.core.settings" name="test">
|
||||
@ -624,6 +625,7 @@
|
||||
</profile>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
@ -1,4 +1,4 @@
|
||||
#Fri Dec 28 17:36:33 CET 2007
|
||||
#Fri Dec 28 21:07:56 CET 2007
|
||||
eclipse.preferences.version=1
|
||||
indexer/filesToParseUpFront=
|
||||
indexer/indexAllFiles=true
|
||||
|
@ -22,7 +22,8 @@
|
||||
* the libisofs ring buffer as intermediate memory
|
||||
*/
|
||||
|
||||
struct th_data {
|
||||
struct th_data
|
||||
{
|
||||
IsoRingBuffer *rbuf;
|
||||
char *path;
|
||||
};
|
||||
@ -37,34 +38,34 @@ void *write_function(void *arg)
|
||||
int res;
|
||||
unsigned char tmp[WRITE_CHUNK];
|
||||
struct th_data *data = (struct th_data *) arg;
|
||||
|
||||
|
||||
int fd = open(data->path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Writer thread error: Can't open file");
|
||||
iso_ring_buffer_writer_close(data->rbuf);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
|
||||
res = 1;
|
||||
while ( (bytes = read(fd, tmp, WRITE_CHUNK)) > 0 ) {
|
||||
while ( (bytes = read(fd, tmp, WRITE_CHUNK)) > 0) {
|
||||
res = iso_ring_buffer_write(data->rbuf, tmp, bytes);
|
||||
if (res <= 0) {
|
||||
break;
|
||||
}
|
||||
/* To test premature reader exit >>>>>>>>>>>
|
||||
iso_ring_buffer_writer_close(data->rbuf);
|
||||
pthread_exit(NULL);
|
||||
<<<<<<<<<<<<<<<<<<<<<<<<< */
|
||||
// if (rand() > 2000000000) {
|
||||
// fprintf(stderr, "Writer sleeping\n");
|
||||
// sleep(1);
|
||||
// }
|
||||
iso_ring_buffer_writer_close(data->rbuf);
|
||||
pthread_exit(NULL);
|
||||
<<<<<<<<<<<<<<<<<<<<<<<<< */
|
||||
// if (rand() > 2000000000) {
|
||||
// fprintf(stderr, "Writer sleeping\n");
|
||||
// sleep(1);
|
||||
// }
|
||||
}
|
||||
fprintf(stderr, "Writer finish: %d\n", res);
|
||||
|
||||
|
||||
close(fd);
|
||||
iso_ring_buffer_writer_close(data->rbuf);
|
||||
pthread_exit(NULL);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
static
|
||||
@ -73,22 +74,22 @@ void *read_function(void *arg)
|
||||
unsigned char tmp[READ_CHUNK];
|
||||
int res = 1;
|
||||
struct th_data *data = (struct th_data *) arg;
|
||||
|
||||
while ( (res = iso_ring_buffer_read(data->rbuf, tmp, READ_CHUNK)) > 0 ) {
|
||||
|
||||
while ( (res = iso_ring_buffer_read(data->rbuf, tmp, READ_CHUNK)) > 0) {
|
||||
write(1, tmp, READ_CHUNK);
|
||||
/* To test premature reader exit >>>>>>>>>>>
|
||||
iso_ring_buffer_reader_close(data->rbuf);
|
||||
pthread_exit(NULL);
|
||||
<<<<<<<<<<<<<<<<<<<<<<<<< */
|
||||
// if (rand() > 2000000000) {
|
||||
// fprintf(stderr, "Reader sleeping\n");
|
||||
// sleep(1);
|
||||
// }
|
||||
iso_ring_buffer_reader_close(data->rbuf);
|
||||
pthread_exit(NULL);
|
||||
<<<<<<<<<<<<<<<<<<<<<<<<< */
|
||||
// if (rand() > 2000000000) {
|
||||
// fprintf(stderr, "Reader sleeping\n");
|
||||
// sleep(1);
|
||||
// }
|
||||
}
|
||||
fprintf(stderr, "Reader finish: %d\n", res);
|
||||
|
||||
|
||||
iso_ring_buffer_reader_close(data->rbuf);
|
||||
|
||||
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
@ -103,24 +104,24 @@ int main(int argc, char **argv)
|
||||
fprintf(stderr, "Usage: catbuffer /path/to/file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
res = iso_ring_buffer_new(&data.rbuf);
|
||||
if (res < 0) {
|
||||
fprintf(stderr, "Can't create buffer\n");
|
||||
return 1;
|
||||
}
|
||||
data.path = argv[1];
|
||||
|
||||
|
||||
res = pthread_create(&writer, NULL, write_function, (void *) &data);
|
||||
res = pthread_create(&reader, NULL, read_function, (void *) &data);
|
||||
|
||||
|
||||
pthread_join(writer, NULL);
|
||||
pthread_join(reader, NULL);
|
||||
|
||||
|
||||
fprintf(stderr, "Buffer was %d times full and %d times empty.\n",
|
||||
iso_ring_buffer_get_times_full(data.rbuf),
|
||||
iso_ring_buffer_get_times_empty(data.rbuf));
|
||||
|
||||
iso_ring_buffer_get_times_full(data.rbuf),
|
||||
iso_ring_buffer_get_times_empty(data.rbuf));
|
||||
|
||||
free(data.rbuf);
|
||||
return 0;
|
||||
}
|
||||
|
91
doc/devel/codestyle.xml
Normal file
91
doc/devel/codestyle.xml
Normal file
@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<profiles version="1">
|
||||
<profile kind="CodeFormatterProfile" name="nglibisofs" version="1">
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.continuation_indentation" value="2"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.lineSplit" value="80"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.alignment_for_conditional_expression" value="16"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.indent_access_specifier_compare_to_type_header" value="false"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_access_specifier" value="true"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_namespace_header" value="false"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.tabulation.size" value="4"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.indent_statements_compare_to_body" value="true"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.indent_statements_compare_to_block" value="true"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.indent_empty_lines" value="false"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.tabulation.char" value="space"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_method_declaration" value="next_line"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_block_in_case" value="next_line_shifted"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.compact_else_if" value="true"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation" value="18"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.alignment_for_parameters_in_method_declaration" value="18"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.indentation.size" value="4"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_namespace_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_namespace_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_block" value="end_of_line"/>
|
||||
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_type_declaration" value="next_line"/>
|
||||
</profile>
|
||||
</profiles>
|
63
src/buffer.c
63
src/buffer.c
@ -14,7 +14,7 @@
|
||||
* there's enought space/data at the beginning
|
||||
* - pre-buffer for writes < BLOCK_SIZE
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
#include "buffer.h"
|
||||
#include "error.h"
|
||||
@ -28,26 +28,27 @@
|
||||
# define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
struct iso_ring_buffer {
|
||||
struct iso_ring_buffer
|
||||
{
|
||||
uint8_t buf[BLOCK_SIZE * BUFFER_SIZE];
|
||||
|
||||
|
||||
/*
|
||||
* Number of bytes available.
|
||||
*/
|
||||
size_t size;
|
||||
|
||||
|
||||
/* position for reading and writing, offset from buf */
|
||||
size_t rpos;
|
||||
size_t wpos;
|
||||
|
||||
|
||||
/* flags to report if read or writer threads ends execution */
|
||||
unsigned int rend:1;
|
||||
unsigned int wend:1;
|
||||
|
||||
unsigned int rend :1;
|
||||
unsigned int wend :1;
|
||||
|
||||
/* just for statistical purposes */
|
||||
unsigned int times_full;
|
||||
unsigned int times_empty;
|
||||
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t empty;
|
||||
pthread_cond_t full;
|
||||
@ -64,30 +65,30 @@ struct iso_ring_buffer {
|
||||
int iso_ring_buffer_new(IsoRingBuffer **rbuf)
|
||||
{
|
||||
IsoRingBuffer *buffer;
|
||||
|
||||
|
||||
if (rbuf == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
|
||||
buffer = malloc(sizeof(IsoRingBuffer));
|
||||
if (buffer == NULL) {
|
||||
return ISO_MEM_ERROR;
|
||||
}
|
||||
|
||||
|
||||
buffer->size = 0;
|
||||
buffer->wpos = 0;
|
||||
buffer->rpos = 0;
|
||||
|
||||
|
||||
buffer->times_full = 0;
|
||||
buffer->times_empty = 0;
|
||||
|
||||
|
||||
buffer->rend = buffer->wend = 0;
|
||||
|
||||
|
||||
/* init mutex and waiting queues */
|
||||
pthread_mutex_init(&buffer->mutex, NULL);
|
||||
pthread_cond_init(&buffer->empty, NULL);
|
||||
pthread_cond_init(&buffer->full, NULL);
|
||||
|
||||
|
||||
*rbuf = buffer;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
@ -118,15 +119,15 @@ int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
|
||||
{
|
||||
size_t len;
|
||||
int bytes_write = 0;
|
||||
|
||||
|
||||
if (buf == NULL || data == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
|
||||
while (bytes_write < count) {
|
||||
|
||||
|
||||
pthread_mutex_lock(&buf->mutex);
|
||||
|
||||
|
||||
while (buf->size == BUFFER_CAPACITY) {
|
||||
|
||||
/*
|
||||
@ -134,7 +135,7 @@ int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
|
||||
* Thus, the while(buf->size == BUFFER_CAPACITY) is used here
|
||||
* only to propertly detect the reader has been cancelled
|
||||
*/
|
||||
|
||||
|
||||
if (buf->rend) {
|
||||
/* the read procces has been finished */
|
||||
pthread_mutex_unlock(&buf->mutex);
|
||||
@ -144,7 +145,7 @@ int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
|
||||
/* wait until space available */
|
||||
pthread_cond_wait(&buf->full, &buf->mutex);
|
||||
}
|
||||
|
||||
|
||||
len = MIN(count - bytes_write, BUFFER_CAPACITY - buf->size);
|
||||
if (buf->wpos + len > BUFFER_CAPACITY) {
|
||||
len = BUFFER_CAPACITY - buf->wpos;
|
||||
@ -153,7 +154,7 @@ int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
|
||||
buf->wpos = (buf->wpos + len) % (BUFFER_CAPACITY);
|
||||
bytes_write += len;
|
||||
buf->size += len;
|
||||
|
||||
|
||||
/* wake up reader */
|
||||
pthread_cond_signal(&buf->empty);
|
||||
pthread_mutex_unlock(&buf->mutex);
|
||||
@ -174,14 +175,14 @@ int iso_ring_buffer_read(IsoRingBuffer *buf, uint8_t *dest, size_t count)
|
||||
{
|
||||
size_t len;
|
||||
int bytes_read = 0;
|
||||
|
||||
|
||||
if (buf == NULL || dest == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
|
||||
while (bytes_read < count) {
|
||||
pthread_mutex_lock(&buf->mutex);
|
||||
|
||||
|
||||
while (buf->size == 0) {
|
||||
/*
|
||||
* Note. There's only a reader, so we have no race conditions.
|
||||
@ -189,7 +190,7 @@ int iso_ring_buffer_read(IsoRingBuffer *buf, uint8_t *dest, size_t count)
|
||||
* a reader detects the EOF propertly if the writer has been
|
||||
* canceled while the reader was waiting
|
||||
*/
|
||||
|
||||
|
||||
if (buf->wend) {
|
||||
/* the writer procces has been finished */
|
||||
pthread_mutex_unlock(&buf->mutex);
|
||||
@ -199,7 +200,7 @@ int iso_ring_buffer_read(IsoRingBuffer *buf, uint8_t *dest, size_t count)
|
||||
/* wait until data available */
|
||||
pthread_cond_wait(&buf->empty, &buf->mutex);
|
||||
}
|
||||
|
||||
|
||||
len = MIN(count - bytes_read, buf->size);
|
||||
if (buf->rpos + len > BUFFER_CAPACITY) {
|
||||
len = BUFFER_CAPACITY - buf->rpos;
|
||||
@ -208,7 +209,7 @@ int iso_ring_buffer_read(IsoRingBuffer *buf, uint8_t *dest, size_t count)
|
||||
buf->rpos = (buf->rpos + len) % (BUFFER_CAPACITY);
|
||||
bytes_read += len;
|
||||
buf->size -= len;
|
||||
|
||||
|
||||
/* wake up the writer */
|
||||
pthread_cond_signal(&buf->full);
|
||||
pthread_mutex_unlock(&buf->mutex);
|
||||
@ -220,7 +221,7 @@ void iso_ring_buffer_writer_close(IsoRingBuffer *buf)
|
||||
{
|
||||
pthread_mutex_lock(&buf->mutex);
|
||||
buf->wend = 1;
|
||||
|
||||
|
||||
/* ensure no reader is waiting */
|
||||
pthread_cond_signal(&buf->empty);
|
||||
pthread_mutex_unlock(&buf->mutex);
|
||||
@ -230,7 +231,7 @@ void iso_ring_buffer_reader_close(IsoRingBuffer *buf)
|
||||
{
|
||||
pthread_mutex_lock(&buf->mutex);
|
||||
buf->rend = 1;
|
||||
|
||||
|
||||
/* ensure no writer is waiting */
|
||||
pthread_cond_signal(&buf->full);
|
||||
pthread_mutex_unlock(&buf->mutex);
|
||||
|
@ -31,29 +31,29 @@ void iso_node_builder_unref(IsoNodeBuilder *builder)
|
||||
}
|
||||
|
||||
static
|
||||
int default_create_file(IsoNodeBuilder *builder, IsoImage *image,
|
||||
int default_create_file(IsoNodeBuilder *builder, IsoImage *image,
|
||||
IsoFileSource *src, IsoFile **file)
|
||||
{
|
||||
int res;
|
||||
struct stat info;
|
||||
IsoStream *stream;
|
||||
IsoFile *node;
|
||||
|
||||
|
||||
if (builder == NULL || src == NULL || file == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
|
||||
res = iso_file_source_stat(src, &info);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* this will fail if src is a dir, is not accessible... */
|
||||
res = iso_file_source_stream_new(src, &stream);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
node = malloc(sizeof(IsoFile));
|
||||
if (node == NULL) {
|
||||
/* the stream has taken our ref to src, so we need to add one */
|
||||
@ -61,7 +61,7 @@ int default_create_file(IsoNodeBuilder *builder, IsoImage *image,
|
||||
iso_stream_unref(stream);
|
||||
return ISO_MEM_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/* fill node fields */
|
||||
node->node.refcount = 1;
|
||||
node->node.type = LIBISO_FILE;
|
||||
@ -78,26 +78,26 @@ int default_create_file(IsoNodeBuilder *builder, IsoImage *image,
|
||||
node->sort_weight = 0;
|
||||
node->stream = stream;
|
||||
node->msblock = 0;
|
||||
|
||||
|
||||
*file = node;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
IsoFileSource *src, IsoNode **node)
|
||||
{
|
||||
int result;
|
||||
struct stat info;
|
||||
IsoNode *new;
|
||||
char *name;
|
||||
|
||||
|
||||
if (builder == NULL || src == NULL || node == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
|
||||
name = iso_file_source_get_name(src);
|
||||
|
||||
|
||||
/* get info about source */
|
||||
if (image->recOpts->follow_symlinks) {
|
||||
result = iso_file_source_stat(src, &info);
|
||||
@ -107,7 +107,7 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
new = NULL;
|
||||
switch (info.st_mode & S_IFMT) {
|
||||
case S_IFREG:
|
||||
@ -148,7 +148,7 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
/* source is a symbolic link */
|
||||
char dest[PATH_MAX];
|
||||
IsoSymlink *link;
|
||||
|
||||
|
||||
result = iso_file_source_readlink(src, dest, PATH_MAX);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
@ -179,7 +179,7 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* fill fields */
|
||||
new->refcount = 1;
|
||||
new->name = strdup(name);
|
||||
@ -189,12 +189,12 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
new->atime = info.st_atime;
|
||||
new->mtime = info.st_mtime;
|
||||
new->ctime = info.st_ctime;
|
||||
|
||||
|
||||
new->hidden = 0;
|
||||
|
||||
|
||||
new->parent = NULL;
|
||||
new->next = NULL;
|
||||
|
||||
|
||||
*node = new;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
@ -208,23 +208,23 @@ void default_free(IsoNodeBuilder *builder)
|
||||
int iso_node_basic_builder_new(IsoNodeBuilder **builder)
|
||||
{
|
||||
IsoNodeBuilder *b;
|
||||
|
||||
|
||||
if (builder == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
|
||||
b = malloc(sizeof(IsoNodeBuilder));
|
||||
if (b == NULL) {
|
||||
return ISO_MEM_ERROR;
|
||||
}
|
||||
|
||||
|
||||
b->refcount = 1;
|
||||
b->create_file_data = NULL;
|
||||
b->create_node_data = NULL;
|
||||
b->create_file = default_create_file;
|
||||
b->create_node = default_create_node;
|
||||
b->free = default_free;
|
||||
|
||||
|
||||
*builder = b;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
@ -40,9 +40,9 @@ struct Iso_Node_Builder
|
||||
* @return
|
||||
* 1 on success, < 0 on error
|
||||
*/
|
||||
int (*create_file)(IsoNodeBuilder *builder, IsoImage *image,
|
||||
int (*create_file)(IsoNodeBuilder *builder, IsoImage *image,
|
||||
IsoFileSource *src, IsoFile **file);
|
||||
|
||||
|
||||
/**
|
||||
* Create a new IsoNode from a IsoFileSource. The type of the node to be
|
||||
* created is determined from the type of the file source. Name,
|
||||
@ -53,15 +53,15 @@ struct Iso_Node_Builder
|
||||
* @return
|
||||
* 1 on success, < 0 on error
|
||||
*/
|
||||
int (*create_node)(IsoNodeBuilder *builder, IsoImage *image,
|
||||
int (*create_node)(IsoNodeBuilder *builder, IsoImage *image,
|
||||
IsoFileSource *src, IsoNode **node);
|
||||
|
||||
|
||||
/**
|
||||
* Free implementation specific data. Should never be called by user.
|
||||
* Use iso_node_builder_unref() instead.
|
||||
*/
|
||||
void (*free)(IsoNodeBuilder *builder);
|
||||
|
||||
|
||||
int refcount;
|
||||
void *create_file_data;
|
||||
void *create_node_data;
|
||||
|
248
src/ecma119.c
248
src/ecma119.c
@ -30,12 +30,12 @@ static
|
||||
void ecma119_image_free(Ecma119Image *t)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
|
||||
ecma119_node_free(t->root);
|
||||
iso_image_unref(t->image);
|
||||
iso_rbtree_destroy(t->files, iso_file_src_free);
|
||||
iso_ring_buffer_free(t->buffer);
|
||||
|
||||
|
||||
for (i = 0; i < t->nwriters; ++i) {
|
||||
IsoImageWriter *writer = t->writers[i];
|
||||
writer->free_data(writer);
|
||||
@ -73,7 +73,8 @@ size_t calc_dirent_len(Ecma119Image *t, Ecma119Node *n)
|
||||
if (need_version_number(t, n)) {
|
||||
ret += 2; /* take into account version numbers */
|
||||
}
|
||||
if (ret % 2) ret++;
|
||||
if (ret % 2)
|
||||
ret++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -90,12 +91,12 @@ size_t calc_dirent_len(Ecma119Image *t, Ecma119Node *n)
|
||||
* The size needed for all dir entries of the given dir, without
|
||||
* taking into account the continuation areas.
|
||||
*/
|
||||
static
|
||||
static
|
||||
size_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
|
||||
{
|
||||
size_t i, len;
|
||||
size_t ce_len = 0;
|
||||
|
||||
|
||||
/* size of "." and ".." entries */
|
||||
len = 34 + 34;
|
||||
if (t->rockridge) {
|
||||
@ -104,14 +105,13 @@ size_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
|
||||
len += rrip_calc_len(t, dir, 2, 255 - 34, &ce_len);
|
||||
*ce += ce_len;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < dir->info.dir.nchildren; ++i) {
|
||||
size_t remaining;
|
||||
Ecma119Node *child = dir->info.dir.children[i];
|
||||
size_t dirent_len = calc_dirent_len(t, child);
|
||||
if (t->rockridge) {
|
||||
dirent_len += rrip_calc_len(t, child, 0, 255 - dirent_len,
|
||||
&ce_len);
|
||||
dirent_len += rrip_calc_len(t, child, 0, 255 - dirent_len, &ce_len);
|
||||
*ce += ce_len;
|
||||
}
|
||||
remaining = BLOCK_SIZE - (len % BLOCK_SIZE);
|
||||
@ -127,7 +127,7 @@ size_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
|
||||
return len;
|
||||
}
|
||||
|
||||
static
|
||||
static
|
||||
void calc_dir_pos(Ecma119Image *t, Ecma119Node *dir)
|
||||
{
|
||||
size_t i, len;
|
||||
@ -156,12 +156,12 @@ uint32_t calc_path_table_size(Ecma119Node *dir)
|
||||
{
|
||||
uint32_t size;
|
||||
size_t i;
|
||||
|
||||
|
||||
/* size of path table for this entry */
|
||||
size = 8;
|
||||
size += dir->iso_name ? strlen(dir->iso_name) : 1;
|
||||
size += (size % 2);
|
||||
|
||||
|
||||
/* and recurse */
|
||||
for (i = 0; i < dir->info.dir.nchildren; i++) {
|
||||
Ecma119Node *child = dir->info.dir.children[i];
|
||||
@ -177,29 +177,29 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
{
|
||||
Ecma119Image *target;
|
||||
uint32_t path_table_size;
|
||||
|
||||
|
||||
if (writer == NULL) {
|
||||
return ISO_MEM_ERROR;
|
||||
}
|
||||
|
||||
|
||||
target = writer->target;
|
||||
|
||||
|
||||
/* compute position of directories */
|
||||
iso_msg_debug(target->image, "Computing position of dir structure");
|
||||
target->ndirs = 0;
|
||||
calc_dir_pos(target, target->root);
|
||||
|
||||
|
||||
/* compute length of pathlist */
|
||||
iso_msg_debug(target->image, "Computing length of pathlist");
|
||||
path_table_size = calc_path_table_size(target->root);
|
||||
|
||||
|
||||
/* compute location for path tables */
|
||||
target->l_path_table_pos = target->curblock;
|
||||
target->curblock += div_up(path_table_size, BLOCK_SIZE);
|
||||
target->m_path_table_pos = target->curblock;
|
||||
target->curblock += div_up(path_table_size, BLOCK_SIZE);
|
||||
target->path_table_size = path_table_size;
|
||||
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
@ -216,28 +216,28 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
* root directory record in the PVD (ECMA-119, 8.4.18) (in order to
|
||||
* distinguish it from the "." entry in the root directory)
|
||||
*/
|
||||
static
|
||||
static
|
||||
void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
||||
uint8_t *buf, size_t len_fi, struct susp_info *info)
|
||||
uint8_t *buf, size_t len_fi, struct susp_info *info)
|
||||
{
|
||||
uint32_t len;
|
||||
uint32_t block;
|
||||
uint8_t len_dr; /*< size of dir entry without SUSP fields */
|
||||
uint8_t *name = (file_id >= 0) ? (uint8_t*)&file_id :
|
||||
(uint8_t*)node->iso_name;
|
||||
|
||||
uint8_t *name = (file_id >= 0) ? (uint8_t*)&file_id
|
||||
: (uint8_t*)node->iso_name;
|
||||
|
||||
struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf;
|
||||
|
||||
|
||||
len_dr = 33 + len_fi + (len_fi % 2 ? 0 : 1);
|
||||
|
||||
|
||||
memcpy(rec->file_id, name, len_fi);
|
||||
|
||||
|
||||
if (need_version_number(t, node)) {
|
||||
len_dr += 2;
|
||||
rec->file_id[len_fi++] = ';';
|
||||
rec->file_id[len_fi++] = '1';
|
||||
}
|
||||
|
||||
|
||||
if (node->type == ECMA119_DIR) {
|
||||
/* use the cached length */
|
||||
len = node->info.dir.len;
|
||||
@ -253,7 +253,7 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
||||
len = 0;
|
||||
block = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* For ".." entry we need to write the parent info!
|
||||
*/
|
||||
@ -267,7 +267,7 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
||||
rec->flags[0] = (node->type == ECMA119_DIR) ? 2 : 0;
|
||||
iso_bb(rec->vol_seq_number, 1, 2);
|
||||
rec->len_fi[0] = len_fi;
|
||||
|
||||
|
||||
/* and finally write the SUSP fields */
|
||||
if (info != NULL) {
|
||||
rrip_write_susp_fields(t, info, buf + len_dr);
|
||||
@ -283,33 +283,33 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
IsoImage *image;
|
||||
Ecma119Image *t;
|
||||
struct ecma119_pri_vol_desc vol;
|
||||
|
||||
|
||||
char *vol_id, *pub_id, *data_id, *volset_id;
|
||||
char *system_id, *application_id, *copyright_file_id;
|
||||
char *abstract_file_id, *biblio_file_id;
|
||||
|
||||
|
||||
if (writer == NULL) {
|
||||
return ISO_MEM_ERROR;
|
||||
}
|
||||
|
||||
|
||||
t = writer->target;
|
||||
image = t->image;
|
||||
|
||||
|
||||
iso_msg_debug(image, "Write Primary Volume Descriptor");
|
||||
|
||||
|
||||
memset(&vol, 0, sizeof(struct ecma119_pri_vol_desc));
|
||||
|
||||
str2d_char(t->input_charset, image->volume_id, &vol_id);
|
||||
str2a_char(t->input_charset, image->publisher_id, &pub_id);
|
||||
str2a_char(t->input_charset, image->data_preparer_id, &data_id);
|
||||
str2d_char(t->input_charset, image->volset_id, &volset_id);
|
||||
|
||||
|
||||
str2a_char(t->input_charset, image->system_id, &system_id);
|
||||
str2a_char(t->input_charset, image->application_id, &application_id);
|
||||
str2d_char(t->input_charset, image->copyright_file_id, ©right_file_id);
|
||||
str2d_char(t->input_charset, image->abstract_file_id, &abstract_file_id);
|
||||
str2d_char(t->input_charset, image->biblio_file_id, &biblio_file_id);
|
||||
|
||||
|
||||
vol.vol_desc_type[0] = 1;
|
||||
memcpy(vol.std_identifier, "CD001", 5);
|
||||
vol.vol_desc_version[0] = 1;
|
||||
@ -318,7 +318,7 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
} else {
|
||||
/* put linux by default? */
|
||||
memcpy(vol.system_id, "LINUX", 5);
|
||||
}
|
||||
}
|
||||
if (vol_id) {
|
||||
strncpy((char*)vol.volume_id, vol_id, 32);
|
||||
}
|
||||
@ -338,7 +338,7 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
strncpy((char*)vol.publisher_id, pub_id, 128);
|
||||
if (data_id)
|
||||
strncpy((char*)vol.data_prep_id, data_id, 128);
|
||||
|
||||
|
||||
if (application_id)
|
||||
strncpy((char*)vol.application_id, application_id, 128);
|
||||
if (copyright_file_id)
|
||||
@ -362,12 +362,12 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
free(copyright_file_id);
|
||||
free(abstract_file_id);
|
||||
free(biblio_file_id);
|
||||
|
||||
|
||||
/* Finally write the Volume Descriptor */
|
||||
return iso_write(t, &vol, sizeof(struct ecma119_pri_vol_desc));
|
||||
}
|
||||
|
||||
static
|
||||
static
|
||||
int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
||||
{
|
||||
int ret;
|
||||
@ -375,13 +375,13 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
||||
size_t i;
|
||||
size_t fi_len, len;
|
||||
struct susp_info info;
|
||||
|
||||
|
||||
/* buf will point to current write position on buffer */
|
||||
uint8_t *buf = buffer;
|
||||
|
||||
|
||||
/* initialize buffer with 0s */
|
||||
memset(buffer, 0, BLOCK_SIZE);
|
||||
|
||||
|
||||
/*
|
||||
* set susp_info to 0's, this way code for both plain ECMA-119 and
|
||||
* RR is very similar
|
||||
@ -416,14 +416,14 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
||||
|
||||
for (i = 0; i < dir->info.dir.nchildren; i++) {
|
||||
Ecma119Node *child = dir->info.dir.children[i];
|
||||
|
||||
|
||||
/* compute len of directory entry */
|
||||
fi_len = strlen(child->iso_name);
|
||||
len = fi_len + 33 + (fi_len % 2 ? 0 : 1);
|
||||
if (need_version_number(t, child)) {
|
||||
len += 2;
|
||||
}
|
||||
|
||||
|
||||
/* get the SUSP fields if rockridge is enabled */
|
||||
if (t->rockridge) {
|
||||
ret = rrip_get_susp_fields(t, child, 0, 255 - len, &info);
|
||||
@ -432,8 +432,8 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
||||
}
|
||||
len += info.suf_len;
|
||||
}
|
||||
|
||||
if ( (buf + len - buffer) > BLOCK_SIZE ) {
|
||||
|
||||
if ( (buf + len - buffer) > BLOCK_SIZE) {
|
||||
/* dir doesn't fit in current block */
|
||||
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||
if (ret < 0) {
|
||||
@ -446,33 +446,33 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
||||
write_one_dir_record(t, child, -1, buf, fi_len, &info);
|
||||
buf += len;
|
||||
}
|
||||
|
||||
|
||||
/* write the last block */
|
||||
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* write the Continuation Area if needed */
|
||||
if (info.ce_len > 0) {
|
||||
ret = rrip_write_ce_fields(t, &info);
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
static
|
||||
int write_dirs(Ecma119Image *t, Ecma119Node *root)
|
||||
{
|
||||
int ret;
|
||||
size_t i;
|
||||
|
||||
|
||||
/* write all directory entries for this dir */
|
||||
ret = write_one_dir(t, root);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* recurse */
|
||||
for (i = 0; i < root->info.dir.nchildren; i++) {
|
||||
Ecma119Node *child = root->info.dir.children[i];
|
||||
@ -486,7 +486,7 @@ int write_dirs(Ecma119Image *t, Ecma119Node *root)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
static
|
||||
int write_path_table(Ecma119Image *t, Ecma119Node **pathlist, int l_type)
|
||||
{
|
||||
size_t i, len;
|
||||
@ -496,8 +496,8 @@ int write_path_table(Ecma119Image *t, Ecma119Node **pathlist, int l_type)
|
||||
Ecma119Node *dir;
|
||||
uint32_t path_table_size;
|
||||
int parent = 0;
|
||||
int ret = ISO_SUCCESS;
|
||||
|
||||
int ret= ISO_SUCCESS;
|
||||
|
||||
path_table_size = 0;
|
||||
write_int = l_type ? iso_lsb : iso_msb;
|
||||
|
||||
@ -527,7 +527,7 @@ int write_path_table(Ecma119Image *t, Ecma119Node **pathlist, int l_type)
|
||||
}
|
||||
path_table_size += len;
|
||||
}
|
||||
|
||||
|
||||
/* we need to fill the last block with zeros */
|
||||
path_table_size %= BLOCK_SIZE;
|
||||
if (path_table_size) {
|
||||
@ -539,15 +539,15 @@ int write_path_table(Ecma119Image *t, Ecma119Node **pathlist, int l_type)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
static
|
||||
int write_path_tables(Ecma119Image *t)
|
||||
{
|
||||
int ret;
|
||||
size_t i, j, cur;
|
||||
Ecma119Node **pathlist;
|
||||
|
||||
|
||||
iso_msg_debug(t->image, "Writing ISO Path tables");
|
||||
|
||||
|
||||
/* allocate temporal pathlist */
|
||||
pathlist = malloc(sizeof(void*) * t->ndirs);
|
||||
if (pathlist == NULL) {
|
||||
@ -565,17 +565,17 @@ int write_path_tables(Ecma119Image *t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Write L Path Table */
|
||||
ret = write_path_table(t, pathlist, 1);
|
||||
if (ret < 0) {
|
||||
goto write_path_tables_exit;
|
||||
}
|
||||
|
||||
|
||||
/* Write L Path Table */
|
||||
ret = write_path_table(t, pathlist, 0);
|
||||
|
||||
write_path_tables_exit:;
|
||||
|
||||
write_path_tables_exit: ;
|
||||
free(pathlist);
|
||||
return ret;
|
||||
}
|
||||
@ -589,21 +589,21 @@ int ecma119_writer_write_data(IsoImageWriter *writer)
|
||||
{
|
||||
int ret;
|
||||
Ecma119Image *t;
|
||||
|
||||
|
||||
if (writer == NULL) {
|
||||
return ISO_MEM_ERROR;
|
||||
}
|
||||
t = writer->target;
|
||||
|
||||
|
||||
/* first of all, we write the directory structure */
|
||||
ret = write_dirs(t, t->root);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* and write the path tables */
|
||||
ret = write_path_tables(t);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -618,28 +618,28 @@ int ecma119_writer_create(Ecma119Image *target)
|
||||
{
|
||||
int ret;
|
||||
IsoImageWriter *writer;
|
||||
|
||||
|
||||
writer = malloc(sizeof(IsoImageWriter));
|
||||
if (writer == NULL) {
|
||||
return ISO_MEM_ERROR;
|
||||
}
|
||||
|
||||
|
||||
writer->compute_data_blocks = ecma119_writer_compute_data_blocks;
|
||||
writer->write_vol_desc = ecma119_writer_write_vol_desc;
|
||||
writer->write_data = ecma119_writer_write_data;
|
||||
writer->free_data = ecma119_writer_free_data;
|
||||
writer->data = NULL;
|
||||
writer->target = target;
|
||||
|
||||
|
||||
/* add this writer to image */
|
||||
target->writers[target->nwriters++] = writer;
|
||||
|
||||
|
||||
iso_msg_debug(target->image, "Creating low level ECMA-119 tree...");
|
||||
ret = ecma119_tree_create(target);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* we need the volume descriptor */
|
||||
target->curblock++;
|
||||
return ISO_SUCCESS;
|
||||
@ -652,10 +652,10 @@ void *write_function(void *arg)
|
||||
size_t i;
|
||||
uint8_t buf[BLOCK_SIZE];
|
||||
IsoImageWriter *writer;
|
||||
|
||||
|
||||
Ecma119Image *target = (Ecma119Image*)arg;
|
||||
iso_msg_debug(target->image, "Starting image writing...");
|
||||
|
||||
|
||||
/* Write System Area, 16 blocks of zeros (ECMA-119, 6.2.1) */
|
||||
memset(buf, 0, BLOCK_SIZE);
|
||||
for (i = 0; i < 16; ++i) {
|
||||
@ -664,7 +664,7 @@ void *write_function(void *arg)
|
||||
goto write_error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* write volume descriptors, one per writer */
|
||||
iso_msg_debug(target->image, "Write volume descriptors");
|
||||
for (i = 0; i < target->nwriters; ++i) {
|
||||
@ -674,22 +674,22 @@ void *write_function(void *arg)
|
||||
goto write_error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* write Volume Descriptor Set Terminator (ECMA-119, 8.3) */
|
||||
{
|
||||
struct ecma119_vol_desc_terminator *vol;
|
||||
vol = (struct ecma119_vol_desc_terminator *) buf;
|
||||
|
||||
|
||||
vol->vol_desc_type[0] = 255;
|
||||
memcpy(vol->std_identifier, "CD001", 5);
|
||||
vol->vol_desc_version[0] = 1;
|
||||
|
||||
|
||||
res = iso_write(target, buf, BLOCK_SIZE);
|
||||
if (res < 0) {
|
||||
goto write_error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* write data for each writer */
|
||||
for (i = 0; i < target->nwriters; ++i) {
|
||||
writer = target->writers[i];
|
||||
@ -698,40 +698,39 @@ void *write_function(void *arg)
|
||||
goto write_error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
iso_ring_buffer_writer_close(target->buffer);
|
||||
pthread_exit(NULL);
|
||||
|
||||
write_error:;
|
||||
iso_msg_fatal(target->image, LIBISO_WRITE_ERROR,
|
||||
|
||||
write_error: ;
|
||||
iso_msg_fatal(target->image, LIBISO_WRITE_ERROR,
|
||||
"Image write error, code %d", res);
|
||||
iso_ring_buffer_writer_close(target->buffer);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
static
|
||||
int ecma119_image_new(IsoImage *src, Ecma119WriteOpts *opts,
|
||||
Ecma119Image **img)
|
||||
static
|
||||
int ecma119_image_new(IsoImage *src, Ecma119WriteOpts *opts, Ecma119Image **img)
|
||||
{
|
||||
int ret, i;
|
||||
Ecma119Image *target;
|
||||
|
||||
|
||||
/* 1. Allocate target and copy opts there */
|
||||
target = calloc(1, sizeof(Ecma119Image));
|
||||
if (target == NULL) {
|
||||
return ISO_MEM_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/* create the tree for file caching */
|
||||
ret = iso_rbtree_new(iso_file_src_cmp, &(target->files));
|
||||
if (ret < 0) {
|
||||
free(target);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
target->image = src;
|
||||
iso_image_ref(src);
|
||||
|
||||
|
||||
target->iso_level = opts->level;
|
||||
target->rockridge = opts->rockridge;
|
||||
target->ino = 0;
|
||||
@ -748,7 +747,7 @@ int ecma119_image_new(IsoImage *src, Ecma119WriteOpts *opts,
|
||||
target->gid = opts->replace_gid == 2 ? opts->gid : 0;
|
||||
target->dir_mode = opts->replace_dir_mode == 2 ? opts->dir_mode : 0555;
|
||||
target->file_mode = opts->replace_file_mode == 2 ? opts->file_mode : 0444;
|
||||
|
||||
|
||||
target->now = time(NULL);
|
||||
target->ms_block = 0;
|
||||
|
||||
@ -760,7 +759,7 @@ int ecma119_image_new(IsoImage *src, Ecma119WriteOpts *opts,
|
||||
free(target);
|
||||
return ISO_MEM_ERROR;
|
||||
}
|
||||
|
||||
|
||||
if (opts->output_charset != NULL) {
|
||||
target->output_charset = strdup(opts->output_charset);
|
||||
} else {
|
||||
@ -771,7 +770,7 @@ int ecma119_image_new(IsoImage *src, Ecma119WriteOpts *opts,
|
||||
free(target);
|
||||
return ISO_MEM_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 2. Based on those options, create needed writers: iso, joliet...
|
||||
* Each writer inits its structures and stores needed info into
|
||||
@ -780,8 +779,8 @@ int ecma119_image_new(IsoImage *src, Ecma119WriteOpts *opts,
|
||||
* current block.
|
||||
* Finally, create Writer for files.
|
||||
*/
|
||||
target->curblock = target->ms_block + 16;
|
||||
|
||||
target->curblock = target->ms_block + 16;
|
||||
|
||||
/* the number of writers is dependent of the extensions */
|
||||
target->writers = malloc(2 * sizeof(void*));
|
||||
if (target->writers == NULL) {
|
||||
@ -789,22 +788,22 @@ int ecma119_image_new(IsoImage *src, Ecma119WriteOpts *opts,
|
||||
free(target);
|
||||
return ISO_MEM_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/* create writer for ECMA-119 structure */
|
||||
ret = ecma119_writer_create(target);
|
||||
if (ret < 0) {
|
||||
goto target_cleanup;
|
||||
}
|
||||
|
||||
|
||||
/* Volume Descriptor Set Terminator */
|
||||
target->curblock++;
|
||||
|
||||
|
||||
/* create writer for file contents */
|
||||
ret = iso_file_src_writer_create(target);
|
||||
if (ret < 0) {
|
||||
goto target_cleanup;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 3.
|
||||
* Call compute_data_blocks() in each Writer.
|
||||
@ -818,27 +817,27 @@ int ecma119_image_new(IsoImage *src, Ecma119WriteOpts *opts,
|
||||
goto target_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The volume space size is just the size of the last session, in
|
||||
* case of ms images.
|
||||
*/
|
||||
target->total_size = (target->curblock - target->ms_block) * BLOCK_SIZE;
|
||||
target->vol_space_size = target->curblock - target->ms_block;
|
||||
|
||||
|
||||
/* 4. Create and start writting thread */
|
||||
|
||||
|
||||
/* create the ring buffer */
|
||||
ret = iso_ring_buffer_new(&target->buffer);
|
||||
if (ret < 0) {
|
||||
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), &(target->th_attr),
|
||||
ret = pthread_create(&(target->wthread), &(target->th_attr),
|
||||
write_function, (void *) target);
|
||||
if (ret != 0) {
|
||||
iso_msg_fatal(target->image, LIBISO_THREAD_ERROR,
|
||||
@ -846,24 +845,23 @@ int ecma119_image_new(IsoImage *src, Ecma119WriteOpts *opts,
|
||||
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;
|
||||
return ISO_SUCCESS;
|
||||
|
||||
target_cleanup:;
|
||||
|
||||
target_cleanup: ;
|
||||
ecma119_image_free(target);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
bs_read(struct burn_source *bs, unsigned char *buf, int size)
|
||||
static int bs_read(struct burn_source *bs, unsigned char *buf, int size)
|
||||
{
|
||||
int ret;
|
||||
Ecma119Image *t = (Ecma119Image*)bs->data;
|
||||
@ -881,29 +879,27 @@ bs_read(struct burn_source *bs, unsigned char *buf, int size)
|
||||
}
|
||||
}
|
||||
|
||||
static off_t
|
||||
bs_get_size(struct burn_source *bs)
|
||||
static off_t bs_get_size(struct burn_source *bs)
|
||||
{
|
||||
Ecma119Image *target = (Ecma119Image*)bs->data;
|
||||
return target->total_size;
|
||||
}
|
||||
|
||||
static void
|
||||
bs_free_data(struct burn_source *bs)
|
||||
static void bs_free_data(struct burn_source *bs)
|
||||
{
|
||||
Ecma119Image *target = (Ecma119Image*)bs->data;
|
||||
|
||||
|
||||
/* forces writer to stop if it is still running */
|
||||
iso_ring_buffer_reader_close(target->buffer);
|
||||
|
||||
|
||||
/* wait until writer thread finishes */
|
||||
pthread_join(target->wthread, NULL);
|
||||
|
||||
|
||||
iso_msg_debug(target->image, "Writer thread joined");
|
||||
iso_msg_debug(target->image, "Ring buffer was %d times full and %d times "
|
||||
"empty", iso_ring_buffer_get_times_full(target->buffer),
|
||||
iso_ring_buffer_get_times_empty(target->buffer));
|
||||
|
||||
|
||||
/* now we can safety free target */
|
||||
ecma119_image_free(target);
|
||||
}
|
||||
@ -912,7 +908,7 @@ static
|
||||
int bs_set_size(struct burn_source *bs, off_t size)
|
||||
{
|
||||
Ecma119Image *target = (Ecma119Image*)bs->data;
|
||||
|
||||
|
||||