Repository: pymedusa/Medusa

Issue:
Regular bad file descriptor errors, OSX
 


Discussion:
@medariox a race condition could cause this, as could a file being opened in the wrong mode (e.g. opened 'wb' instead of 'r').   This is happening in `shutil_custom`.  The code I posted previously with changes to `shutil_custom` that used context managers for properly opening/closing files would likely fix this.
@labrys Do you want to PR it or should I do it?
Feel free to PR it.  I'll review it if you would like.
@bobbysteel I assume you have already checked your permissions?  Also are you sure it only happens once a day?  Don't rely on the error count in the UI for the number of times it happens - many errors are only counted once until reset.

Resolving patch:
diff --git a/lib/shutil_custom/__init__.py b/lib/shutil_custom/__init__.py
--- a/lib/shutil_custom/__init__.py
+++ b/lib/shutil_custom/__init__.py
@@ -1,52 +1,37 @@
 import os
-import platform
 import stat
+from io import open
+from shutil import SpecialFileError, _samefile
 try:
-    from shutil import SpecialFileError, Error
-except:
-    from shutil import Error
-from shutil import _samefile
+    from shutil import SameFileError
+except ImportError:
+    from shutil import Error as SameFileError
 
 
-def copyfile_custom(src, dst):
-    """Copy data from src to dst"""
-    if _samefile(src, dst):
-        raise Error("`%s` and `%s` are the same file" % (src, dst))
+BUFFER_SIZE = 1024 * 1024 if os.name == 'nt' else 16 * 1024
 
-    for fn in [src, dst]:
+
+def copyfile_custom(src, dst):
+    """Copy data from src to dst."""
+    def special_file(fn):
         try:
             st = os.stat(fn)
         except OSError:
             # File most likely does not exist
             pass
         else:
-            # XXX What about other special files? (sockets, devices...)
             if stat.S_ISFIFO(st.st_mode):
-                try:
-                    raise SpecialFileError("`%s` is a named pipe" % fn)
-                except NameError:
-                    raise Error("`%s` is a named pipe" % fn)
+                raise SpecialFileError("{!r} is a named pipe".format(fn))
 
-    try:
-        # Windows
-        O_BINARY = os.O_BINARY
-    except:
-        O_BINARY = 0
+    if _samefile(src, dst):
+        raise SameFileError("{!r} and {!r} are the same file".format(src, dst))
 
-    READ_FLAGS = os.O_RDONLY | O_BINARY
-    WRITE_FLAGS = os.O_WRONLY | os.O_CREAT | os.O_TRUNC | O_BINARY
-    BUFFER_SIZE = 128*1024
+    special_file(src)
+    special_file(dst)
 
-    try:
-        fin = os.open(src, READ_FLAGS)
-        fout = os.open(dst, WRITE_FLAGS)
-        for x in iter(lambda: os.read(fin, BUFFER_SIZE), ""):
-            os.write(fout, x)
-    except Exception as e:
-        raise
-    finally:
-        try:
-            os.close(fin)
-            os.close(fout)
-        except:
-            pass
+    with open(src, 'rb') as fsrc, open(dst, 'wb') as fdst:
+        while True:
+            buf = fsrc.read(BUFFER_SIZE)
+            if not buf:
+                break
+            fdst.write(buf)
diff --git a/medusa/process_tv.py b/medusa/process_tv.py
--- a/medusa/process_tv.py
+++ b/medusa/process_tv.py
@@ -17,16 +17,12 @@
 from medusa.name_parser.parser import InvalidNameException, InvalidShowException, NameParser
 from medusa.subtitles import accept_any, accept_unknown, get_embedded_subtitles
 
-import shutil_custom
-
 from six import iteritems
 
 from unrar2 import RarFile
 from unrar2.rar_exceptions import (ArchiveHeaderBroken, FileOpenError, IncorrectRARPassword, InvalidRARArchive,
                                    InvalidRARArchiveUsage)
 
-shutil.copyfile = shutil_custom.copyfile_custom
-
 
 class ProcessResult(object):
 


Test patch: