]> granicus.if.org Git - transmission/commitdiff
(trunk, libt) #4147 'bad file descriptor': in cached_file_open(), ensure the file...
authorJordan Lee <jordan@transmissionbt.com>
Sat, 27 Jul 2013 16:18:12 +0000 (16:18 +0000)
committerJordan Lee <jordan@transmissionbt.com>
Sat, 27 Jul 2013 16:18:12 +0000 (16:18 +0000)
libtransmission/fdlimit.c

index 546e988a286019c424dd7cb3455dae92ffc50413..2a1bf4e3dbfb10776bb6de5b21f42c4c2555a023 100644 (file)
@@ -335,7 +335,8 @@ cached_file_open (struct tr_cached_file  * o,
 {
   int flags;
   struct stat sb;
-  bool alreadyExisted;
+  bool already_existed;
+  bool resize_needed;
 
   /* create subfolders, if any */
   if (writable)
@@ -351,12 +352,16 @@ cached_file_open (struct tr_cached_file  * o,
       tr_free (dir);
     }
 
-  alreadyExisted = !stat (filename, &sb) && S_ISREG (sb.st_mode);
+  already_existed = !stat (filename, &sb) && S_ISREG (sb.st_mode);
 
-  if (writable && !alreadyExisted && (allocation == TR_PREALLOCATE_FULL))
+  if (writable && !already_existed && (allocation == TR_PREALLOCATE_FULL))
     if (preallocate_file_full (filename, file_size))
       tr_logAddDebug ("Preallocated file \"%s\"", filename);
 
+  /* we can't resize the file w/o write permissions */
+  resize_needed = already_existed && (file_size < (uint64_t)sb.st_size);
+  writable |= resize_needed;
+
   /* open the file */
   flags = writable ? (O_RDWR | O_CREAT) : O_RDONLY;
   flags |= O_LARGEFILE | O_BINARY | O_SEQUENTIAL;
@@ -375,17 +380,14 @@ cached_file_open (struct tr_cached_file  * o,
    * http://trac.transmissionbt.com/ticket/2228
    * https://bugs.launchpad.net/ubuntu/+source/transmission/+bug/318249
    */
-  if (alreadyExisted && (file_size < (uint64_t)sb.st_size))
+  if (resize_needed && (ftruncate (o->fd, file_size) == -1))
     {
-      if (ftruncate (o->fd, file_size) == -1)
-        {
-          const int err = errno;
-          tr_logAddError (_("Couldn't truncate \"%1$s\": %2$s"), filename, tr_strerror (err));
-          return err;
-        }
+      const int err = errno;
+      tr_logAddError (_("Couldn't truncate \"%1$s\": %2$s"), filename, tr_strerror (err));
+      return err;
     }
 
-  if (writable && !alreadyExisted && (allocation == TR_PREALLOCATE_SPARSE))
+  if (writable && !already_existed && (allocation == TR_PREALLOCATE_SPARSE))
     preallocate_file_sparse (o->fd, file_size);
 
   /* Many (most?) clients request blocks in ascending order,