open() can return -1. If that negative value is given to
From: Erik Hovland <erik@hovland.org>
close() then the behavior is undefined (and some C libraries
will segfault).
---
mythtv/libs/libmythupnp/httprequest.cpp | 49 +++++++++++++++++--------------
1 files changed, 27 insertions(+), 22 deletions(-)
diff --git a/mythtv/libs/libmythupnp/httprequest.cpp b/mythtv/libs/libmythupnp/httprequest.cpp
index 5970122..62c232a 100644
a
|
b
|
long HTTPRequest::SendResponseFile( QString sFileName ) |
317 | 317 | setsockopt( getSocketHandle(), SOL_TCP, TCP_CORK, &g_on, sizeof( g_on )); |
318 | 318 | #endif |
319 | 319 | |
320 | | if (QFile::exists( sFileName )) |
| 320 | QFile tmpFile( sFileName ); |
| 321 | if (tmpFile.exists( ) && tmpFile.open( QIODevice::ReadOnly )) |
321 | 322 | { |
322 | 323 | |
323 | 324 | m_sResponseTypeText = TestMimeType( sFileName ); |
… |
… |
long HTTPRequest::SendResponseFile( QString sFileName ) |
326 | 327 | // Get File size |
327 | 328 | // ------------------------------------------------------------------ |
328 | 329 | |
329 | | struct stat st; |
330 | | |
331 | | QByteArray tmp = sFileName.toAscii(); |
332 | | if (stat( tmp.constData(), &st ) == 0) |
333 | | llSize = llEnd = st.st_size; |
| 330 | llSize = llEnd = tmpFile.size( ); |
334 | 331 | |
335 | 332 | m_nResponseStatus = 200; |
336 | 333 | |
… |
… |
long HTTPRequest::SendResponseFile( QString sFileName ) |
405 | 402 | if (( m_eType != RequestTypeHead ) && (llSize != 0)) |
406 | 403 | { |
407 | 404 | __off64_t offset = llStart; |
408 | | QByteArray tmp = sFileName.toAscii(); |
409 | | int file = open( tmp.constData(), O_RDONLY | O_LARGEFILE ); |
| 405 | int file = tmpFile.handle( ); |
410 | 406 | ssize_t sent = 0; |
411 | 407 | |
412 | | do |
413 | | { |
414 | | // SSIZE_MAX should work in kernels 2.6.16 and later. |
415 | | // The loop is needed in any case. |
416 | | |
417 | | sent = sendfile64( getSocketHandle(), file, &offset, |
418 | | (size_t)(llSize > INT_MAX ? INT_MAX : llSize)); |
419 | | |
420 | | llSize = llEnd - offset; |
421 | | //VERBOSE(VB_UPNP, QString("SendResponseFile : --- size = %1, offset = %2, sent = %3").arg(llSize).arg(offset).arg(sent)); |
422 | | } |
423 | | while (( sent >= 0 ) && ( llSize > 0 )); |
| 408 | if ( file == -1 ) |
| 409 | { |
| 410 | VERBOSE(VB_UPNP, QString("SendResponseFile( %1 ) Error: %2 [%3]" ) |
| 411 | .arg( sFileName ) |
| 412 | .arg( tmpFile.error( )) |
| 413 | .arg( strerror( tmpFile.error( ) ))); |
| 414 | nBytes = -1; |
| 415 | } |
| 416 | else |
| 417 | { |
| 418 | do |
| 419 | { |
| 420 | // SSIZE_MAX should work in kernels 2.6.16 and later. |
| 421 | // The loop is needed in any case. |
| 422 | |
| 423 | sent = sendfile64( getSocketHandle(), file, &offset, |
| 424 | (size_t)(llSize > INT_MAX ? INT_MAX : llSize)); |
| 425 | |
| 426 | llSize = llEnd - offset; |
| 427 | //VERBOSE(VB_UPNP, QString("SendResponseFile : --- size = %1, offset = %2, sent = %3").arg(llSize).arg(offset).arg(sent)); |
| 428 | } |
| 429 | while (( sent >= 0 ) && ( llSize > 0 )); |
| 430 | } |
424 | 431 | |
425 | 432 | if (sent == -1) |
426 | 433 | { |
… |
… |
long HTTPRequest::SendResponseFile( QString sFileName ) |
431 | 438 | |
432 | 439 | nBytes = -1; |
433 | 440 | } |
434 | | |
435 | | close( file ); |
436 | 441 | } |
437 | 442 | |
438 | 443 | // ---------------------------------------------------------------------- |