Commit d0ab3b20 authored by conrad's avatar conrad

oggz-merge, oggz-sort: handle out-of-memory, and use checked_fwrite()

git-svn-id: http://svn.annodex.net/liboggz/trunk@3859 8158c8cd-e7e1-0310-9fa4-c5954c97daef
parent 7292ebc6
...@@ -56,6 +56,8 @@ ...@@ -56,6 +56,8 @@
" contain %d tracks in parallel, interleaved for simultaneous playback.\n"\ " contain %d tracks in parallel, interleaved for simultaneous playback.\n"\
" If you want to sequence these files one after another, use cat instead.\n" " If you want to sequence these files one after another, use cat instead.\n"
static char * progname;
static void static void
usage (char * progname) usage (char * progname)
{ {
...@@ -71,6 +73,23 @@ usage (char * progname) ...@@ -71,6 +73,23 @@ usage (char * progname)
printf ("Please report bugs to <ogg-dev@xiph.org>\n"); printf ("Please report bugs to <ogg-dev@xiph.org>\n");
} }
static void
exit_out_of_memory (void)
{
fprintf (stderr, "%s: Out of memory\n", progname);
exit (1);
}
static void
checked_fwrite (const void *data, size_t size, size_t count, FILE *stream)
{
int n = fwrite (data, size, count, stream);
if ((size_t)n != count) {
perror ("write failed");
exit (1);
}
}
typedef struct _OMData OMData; typedef struct _OMData OMData;
typedef struct _OMInput OMInput; typedef struct _OMInput OMInput;
typedef struct _OMITrack OMITrack; typedef struct _OMITrack OMITrack;
...@@ -96,10 +115,22 @@ _ogg_page_copy (const ogg_page * og) ...@@ -96,10 +115,22 @@ _ogg_page_copy (const ogg_page * og)
ogg_page * new_og; ogg_page * new_og;
new_og = malloc (sizeof (*og)); new_og = malloc (sizeof (*og));
if (new_og == NULL) return NULL;
new_og->header = malloc (og->header_len); new_og->header = malloc (og->header_len);
if (new_og->header == NULL) {
free (new_og);
return NULL;
}
new_og->header_len = og->header_len; new_og->header_len = og->header_len;
memcpy (new_og->header, og->header, og->header_len); memcpy (new_og->header, og->header, og->header_len);
new_og->body = malloc (og->body_len); new_og->body = malloc (og->body_len);
if (new_og->body == NULL) {
free (new_og->header);
free (new_og);
return NULL;
}
new_og->body_len = og->body_len; new_og->body_len = og->body_len;
memcpy (new_og->body, og->body, og->body_len); memcpy (new_og->body, og->body, og->body_len);
...@@ -129,6 +160,7 @@ omdata_new (void) ...@@ -129,6 +160,7 @@ omdata_new (void)
OMData * omdata; OMData * omdata;
omdata = (OMData *) malloc (sizeof (OMData)); omdata = (OMData *) malloc (sizeof (OMData));
if (omdata == NULL) return NULL;
omdata->inputs = oggz_table_new (); omdata->inputs = oggz_table_new ();
omdata->verbose = 0; omdata->verbose = 0;
...@@ -158,6 +190,7 @@ read_page (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data) ...@@ -158,6 +190,7 @@ read_page (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data)
OMInput * input = (OMInput *) user_data; OMInput * input = (OMInput *) user_data;
input->og = _ogg_page_copy (og); input->og = _ogg_page_copy (og);
if (input->og == NULL) return OGGZ_STOP_ERR;
return OGGZ_STOP_OK; return OGGZ_STOP_OK;
} }
...@@ -226,7 +259,9 @@ oggz_merge (OMData * omdata, FILE * outfile) ...@@ -226,7 +259,9 @@ oggz_merge (OMData * omdata, FILE * outfile)
oggz_table_remove (omdata->inputs, key); oggz_table_remove (omdata->inputs, key);
ominput_delete (input); ominput_delete (input);
input = NULL; input = NULL;
} } else if (n == OGGZ_ERR_STOP_ERR) {
exit_out_of_memory();
}
} }
if (input && input->og) { if (input && input->og) {
if (ogg_page_bos ((ogg_page *)input->og)) { if (ogg_page_bos ((ogg_page *)input->og)) {
...@@ -306,8 +341,8 @@ oggz_merge (OMData * omdata, FILE * outfile) ...@@ -306,8 +341,8 @@ oggz_merge (OMData * omdata, FILE * outfile)
if (min_i != -1) { if (min_i != -1) {
input = (OMInput *) oggz_table_nth (omdata->inputs, min_i, &key); input = (OMInput *) oggz_table_nth (omdata->inputs, min_i, &key);
og = input->og; og = input->og;
fwrite (og->header, 1, og->header_len, outfile); checked_fwrite (og->header, 1, og->header_len, outfile);
fwrite (og->body, 1, og->body_len, outfile); checked_fwrite (og->body, 1, og->body_len, outfile);
_ogg_page_free (og); _ogg_page_free (og);
input->og = NULL; input->og = NULL;
...@@ -323,7 +358,6 @@ main (int argc, char * argv[]) ...@@ -323,7 +358,6 @@ main (int argc, char * argv[])
int show_version = 0; int show_version = 0;
int show_help = 0; int show_help = 0;
char * progname;
char * infilename = NULL, * outfilename = NULL; char * infilename = NULL, * outfilename = NULL;
FILE * infile = NULL, * outfile = NULL; FILE * infile = NULL, * outfile = NULL;
int used_stdin = 0; /* Flag usage of stdin, only use it once */ int used_stdin = 0; /* Flag usage of stdin, only use it once */
...@@ -361,6 +395,8 @@ main (int argc, char * argv[]) ...@@ -361,6 +395,8 @@ main (int argc, char * argv[])
} }
omdata = omdata_new(); omdata = omdata_new();
if (omdata == NULL)
exit_out_of_memory();
while (1) { while (1) {
#ifdef HAVE_GETOPT_LONG #ifdef HAVE_GETOPT_LONG
...@@ -428,7 +464,8 @@ main (int argc, char * argv[]) ...@@ -428,7 +464,8 @@ main (int argc, char * argv[])
fprintf (stderr, "%s: unable to open input file %s\n", progname, fprintf (stderr, "%s: unable to open input file %s\n", progname,
infilename); infilename);
} else { } else {
omdata_add_input (omdata, infile); if (omdata_add_input (omdata, infile) == NULL)
exit_out_of_memory();
} }
} }
......
...@@ -44,6 +44,8 @@ ...@@ -44,6 +44,8 @@
#define READ_SIZE 4096 #define READ_SIZE 4096
static char * progname;
static void static void
usage (char * progname) usage (char * progname)
{ {
...@@ -59,6 +61,23 @@ usage (char * progname) ...@@ -59,6 +61,23 @@ usage (char * progname)
printf ("Please report bugs to <ogg-dev@xiph.org>\n"); printf ("Please report bugs to <ogg-dev@xiph.org>\n");
} }
static void
exit_out_of_memory (void)
{
fprintf (stderr, "%s: Out of memory\n", progname);
exit (1);
}
static void
checked_fwrite (const void *data, size_t size, size_t count, FILE *stream)
{
int n = fwrite (data, size, count, stream);
if ((size_t)n != count) {
perror ("write failed");
exit (1);
}
}
typedef struct _OSData OSData; typedef struct _OSData OSData;
typedef struct _OSInput OSInput; typedef struct _OSInput OSInput;
typedef struct _OSITrack OSITrack; typedef struct _OSITrack OSITrack;
...@@ -86,10 +105,22 @@ _ogg_page_copy (const ogg_page * og) ...@@ -86,10 +105,22 @@ _ogg_page_copy (const ogg_page * og)
ogg_page * new_og; ogg_page * new_og;
new_og = malloc (sizeof (*og)); new_og = malloc (sizeof (*og));
if (new_og == NULL) return NULL;
new_og->header = malloc (og->header_len); new_og->header = malloc (og->header_len);
if (new_og->header == NULL) {
free (new_og);
return NULL;
}
new_og->header_len = og->header_len; new_og->header_len = og->header_len;
memcpy (new_og->header, og->header, og->header_len); memcpy (new_og->header, og->header, og->header_len);
new_og->body = malloc (og->body_len); new_og->body = malloc (og->body_len);
if (new_og->body == NULL) {
free (new_og->header);
free (new_og);
return NULL;
}
new_og->body_len = og->body_len; new_og->body_len = og->body_len;
memcpy (new_og->body, og->body, og->body_len); memcpy (new_og->body, og->body, og->body_len);
...@@ -119,8 +150,14 @@ osdata_new (void) ...@@ -119,8 +150,14 @@ osdata_new (void)
OSData * osdata; OSData * osdata;
osdata = (OSData *) malloc (sizeof (OSData)); osdata = (OSData *) malloc (sizeof (OSData));
if (osdata == NULL) return NULL;
osdata->inputs = oggz_table_new (); osdata->inputs = oggz_table_new ();
if (osdata->inputs == NULL) {
free (osdata);
return NULL;
}
osdata->verbose = 0; osdata->verbose = 0;
return osdata; return osdata;
...@@ -152,6 +189,8 @@ read_page (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data) ...@@ -152,6 +189,8 @@ read_page (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data)
if (serialno == input->serialno) { if (serialno == input->serialno) {
ogg_page *iog; ogg_page *iog;
iog = _ogg_page_copy (og); iog = _ogg_page_copy (og);
if (iog == NULL) return OGGZ_STOP_ERR;
/* If this page's granulepos should be -1 but isn't then fix that before /* If this page's granulepos should be -1 but isn't then fix that before
* storing and sorting the page. */ * storing and sorting the page. */
if(ogg_page_packets(iog)==0&&ogg_page_granulepos(iog)!=-1) { if(ogg_page_packets(iog)==0&&ogg_page_granulepos(iog)!=-1) {
...@@ -181,10 +220,15 @@ read_page_add_input (OGGZ * oggz, const ogg_page * og, long serialno, ...@@ -181,10 +220,15 @@ read_page_add_input (OGGZ * oggz, const ogg_page * og, long serialno,
if (is_bos) { if (is_bos) {
input = (OSInput *) malloc (sizeof (OSInput)); input = (OSInput *) malloc (sizeof (OSInput));
if (input == NULL) return -1; if (input == NULL) return OGGZ_STOP_ERR;
input->osdata = osdata; input->osdata = osdata;
input->reader = oggz_open (osdata->infilename, OGGZ_READ|OGGZ_AUTO); input->reader = oggz_open (osdata->infilename, OGGZ_READ|OGGZ_AUTO);
if (input->reader == NULL) {
free (input);
return OGGZ_STOP_ERR;
}
input->serialno = serialno; input->serialno = serialno;
input->og = NULL; input->og = NULL;
...@@ -193,7 +237,7 @@ read_page_add_input (OGGZ * oggz, const ogg_page * og, long serialno, ...@@ -193,7 +237,7 @@ read_page_add_input (OGGZ * oggz, const ogg_page * og, long serialno,
nfiles = oggz_table_size (osdata->inputs); nfiles = oggz_table_size (osdata->inputs);
if (!oggz_table_insert (osdata->inputs, nfiles++, input)) { if (!oggz_table_insert (osdata->inputs, nfiles++, input)) {
osinput_delete (input); osinput_delete (input);
return -1; return OGGZ_STOP_ERR;
} }
return OGGZ_CONTINUE; return OGGZ_CONTINUE;
...@@ -255,6 +299,8 @@ oggz_sort (OSData * osdata, FILE * outfile) ...@@ -255,6 +299,8 @@ oggz_sort (OSData * osdata, FILE * outfile)
oggz_table_remove (osdata->inputs, key); oggz_table_remove (osdata->inputs, key);
osinput_delete (input); osinput_delete (input);
input = NULL; input = NULL;
} else if (n == OGGZ_ERR_STOP_ERR) {
exit_out_of_memory();
} }
} }
if (input && input->og) { if (input && input->og) {
...@@ -305,8 +351,8 @@ oggz_sort (OSData * osdata, FILE * outfile) ...@@ -305,8 +351,8 @@ oggz_sort (OSData * osdata, FILE * outfile)
if (min_i != -1) { if (min_i != -1) {
input = (OSInput *) oggz_table_nth (osdata->inputs, min_i, &key); input = (OSInput *) oggz_table_nth (osdata->inputs, min_i, &key);
og = input->og; og = input->og;
fwrite (og->header, 1, og->header_len, outfile); checked_fwrite (og->header, 1, og->header_len, outfile);
fwrite (og->body, 1, og->body_len, outfile); checked_fwrite (og->body, 1, og->body_len, outfile);
_ogg_page_free (og); _ogg_page_free (og);
input->og = NULL; input->og = NULL;
...@@ -322,7 +368,6 @@ main (int argc, char * argv[]) ...@@ -322,7 +368,6 @@ main (int argc, char * argv[])
int show_version = 0; int show_version = 0;
int show_help = 0; int show_help = 0;
char * progname;
char * infilename = NULL, * outfilename = NULL; char * infilename = NULL, * outfilename = NULL;
FILE * infile = NULL, * outfile = NULL; FILE * infile = NULL, * outfile = NULL;
OSData * osdata; OSData * osdata;
...@@ -359,6 +404,8 @@ main (int argc, char * argv[]) ...@@ -359,6 +404,8 @@ main (int argc, char * argv[])
} }
osdata = osdata_new(); osdata = osdata_new();
if (osdata == NULL)
exit_out_of_memory();
while (1) { while (1) {
#ifdef HAVE_GETOPT_LONG #ifdef HAVE_GETOPT_LONG
...@@ -407,7 +454,11 @@ main (int argc, char * argv[]) ...@@ -407,7 +454,11 @@ main (int argc, char * argv[])
} }
infilename = argv[optind++]; infilename = argv[optind++];
osdata_add_file (osdata, infilename); if (osdata_add_file (osdata, infilename) == -1) {
fprintf (stderr, "%s: unable to open input file %s\n",
progname, infilename);
goto exit_err;
}
if (outfilename == NULL) { if (outfilename == NULL) {
outfile = stdout; outfile = stdout;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment