Fix uncommon handle leak when opening too many files

This commit is contained in:
bnnm 2019-11-03 17:55:47 +01:00
parent 65a96502fa
commit e06e2f2bb2
3 changed files with 43 additions and 31 deletions

View File

@ -500,9 +500,8 @@ int main(int argc, char ** argv) {
/* prints done */
if (cfg.print_metaonly) {
if (!cfg.play_sdtout) {
if(outfile != NULL) {
fclose(outfile);
}
if (outfile != NULL)
fclose(outfile);
}
close_vgmstream(vgmstream);
return EXIT_SUCCESS;
@ -590,8 +589,10 @@ int main(int argc, char ** argv) {
}
}
fclose(outfile);
outfile = NULL;
if (outfile != NULL) {
fclose(outfile);
outfile = NULL;
}
/* try again with (for testing reset_vgmstream, simulates a seek to 0 after changing internal state) */
@ -647,8 +648,11 @@ int main(int argc, char ** argv) {
}
}
}
fclose(outfile);
outfile = NULL;
if (outfile != NULL) {
fclose(outfile);
outfile = NULL;
}
}
close_vgmstream(vgmstream);

View File

@ -29,6 +29,8 @@ static size_t read_stdio(STDIO_STREAMFILE *streamfile, uint8_t *dst, off_t offse
if (!streamfile->infile || !dst || length <= 0 || offset < 0)
return 0;
//;VGM_LOG("STDIO: read %lx + %x (buf %lx + %x)\n", offset, length, streamfile->buffer_offset, streamfile->validsize);
/* is the part of the requested length in the buffer? */
if (offset >= streamfile->buffer_offset && offset < streamfile->buffer_offset + streamfile->validsize) {
size_t length_to_read;
@ -38,6 +40,8 @@ static size_t read_stdio(STDIO_STREAMFILE *streamfile, uint8_t *dst, off_t offse
if (length_to_read > length)
length_to_read = length;
//;VGM_LOG("STDIO: copy buf %lx + %x (+ %x) (buf %lx + %x)\n", offset, length_to_read, (length - length_to_read), streamfile->buffer_offset, streamfile->validsize);
memcpy(dst, streamfile->buffer + offset_into_buffer, length_to_read);
length_read_total += length_to_read;
length -= length_to_read;
@ -46,8 +50,10 @@ static size_t read_stdio(STDIO_STREAMFILE *streamfile, uint8_t *dst, off_t offse
}
#ifdef VGM_DEBUG_OUTPUT
if (offset < streamfile->buffer_offset) {
if (offset < streamfile->buffer_offset && length > 0) {
VGM_LOG("STDIO: rebuffer, requested %lx vs %lx (sf %x)\n", offset, streamfile->buffer_offset, (uint32_t)streamfile);
//streamfile->rebuffer++;
//if (rebuffer > N) ...
}
#endif
@ -78,6 +84,7 @@ static size_t read_stdio(STDIO_STREAMFILE *streamfile, uint8_t *dst, off_t offse
/* fill the buffer (offset now is beyond buffer_offset) */
streamfile->buffer_offset = offset;
streamfile->validsize = fread(streamfile->buffer, sizeof(uint8_t), streamfile->buffersize, streamfile->infile);
//;VGM_LOG("STDIO: read buf %lx + %x\n", streamfile->buffer_offset, streamfile->validsize);
/* decide how much must be read this time */
if (length > streamfile->buffersize)
@ -126,20 +133,21 @@ static STREAMFILE* open_stdio(STDIO_STREAMFILE *streamfile, const char * const f
return NULL;
#if !defined (__ANDROID__)
// if same name, duplicate the file pointer we already have open
/* if same name, duplicate the file descriptor we already have open */
if (streamfile->infile && !strcmp(streamfile->name,filename)) {
int newfd;
FILE *newfile;
STREAMFILE *new_sf;
int new_fd;
FILE *new_file = NULL;
if ( ((newfd = dup(fileno(streamfile->infile))) >= 0) && (newfile = fdopen(newfd, "rb")) ) {
new_sf = open_stdio_streamfile_buffer_by_file(newfile, filename, buffersize);
if (new_sf) {
if (((new_fd = dup(fileno(streamfile->infile))) >= 0) && (new_file = fdopen(new_fd, "rb"))) {
STREAMFILE *new_sf = open_stdio_streamfile_buffer_by_file(new_file, filename, buffersize);
if (new_sf)
return new_sf;
}
// failure, close it and try the default path (which will probably fail a second time)
fclose(newfile);
fclose(new_file);
}
if (new_fd >= 0 && !new_file)
close(new_fd); /* fdopen may fail when opening too many files */
/* on failure just close and try the default path (which will probably fail a second time) */
}
#endif
// a normal open, open a new file

View File

@ -241,28 +241,28 @@ static void wasf_get_name(WINAMP_STREAMFILE *streamfile, char *buffer, size_t le
}
static STREAMFILE *wasf_open(WINAMP_STREAMFILE *streamFile, const char *const filename, size_t buffersize) {
int newfd;
FILE *newfile;
STREAMFILE *newstreamFile;
in_char wpath[PATH_LIMIT];
char name[PATH_LIMIT];
if (!filename)
return NULL;
/* if same name, duplicate the file pointer we already have open */ //unsure if all this is needed
streamFile->stdiosf->get_name(streamFile->stdiosf, name, PATH_LIMIT);
/* if same name, duplicate the file descriptor we already have open */ //unsure if all this is needed
if (streamFile->infile_ref && !strcmp(name,filename)) {
if (((newfd = dup(fileno(streamFile->infile_ref))) >= 0) &&
(newfile = wa_fdopen(newfd)))
{
newstreamFile = open_winamp_streamfile_by_file(newfile,filename);
if (newstreamFile) {
return newstreamFile;
}
// failure, close it and try the default path (which will probably fail a second time)
fclose(newfile);
int new_fd;
FILE *new_file;
if (((new_fd = dup(fileno(streamFile->infile_ref))) >= 0) && (new_file = wa_fdopen(new_fd))) {
STREAMFILE *new_sf = open_winamp_streamfile_by_file(new_file, filename);
if (new_sf)
return new_sf;
fclose(new_file);
}
if (new_fd >= 0 && !new_file)
close(new_fd); /* fdopen may fail when opening too many files */
/* on failure just close and try the default path (which will probably fail a second time) */
}
/* STREAMFILEs carry char/UTF8 names, convert to wchar for Winamp */