Linux对于文件路径和文件名都有长度限制,在/usr/include/linux/limits.h头文件中有具体定义:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _LINUX_LIMITS_H
#define _LINUX_LIMITS_H

#define NR_OPEN         1024

#define NGROUPS_MAX    65536    /* supplemental group IDs are available */
#define ARG_MAX       131072    /* # bytes of args + environ for exec() */
#define LINK_MAX         127    /* # links a file may have */
#define MAX_CANON        255    /* size of the canonical input queue */
#define MAX_INPUT        255    /* size of the type-ahead buffer */
#define NAME_MAX         255    /* # chars in a file name */
#define PATH_MAX        4096    /* # chars in a path name including nul */
#define PIPE_BUF        4096    /* # bytes in atomic write to a pipe */
#define XATTR_NAME_MAX   255    /* # chars in an extended attribute name */
#define XATTR_SIZE_MAX 65536    /* size of an extended attribute value (64k) */
#define XATTR_LIST_MAX 65536    /* size of extended attribute namelist (64k) */

#define RTSIG_MAX         32

#endif

  NAME_MAX定义了文件名的最大长度,为255个字节,PATH_MAX定义了路径的最大长度,为4096字节。
  Windows系统下也有类似限制,但稍有区别,似乎是按照字符数而不是字节数来计算的。因此当某些文件名包含中文或者日文,并且巨长的时候,就会导致在Linux下无法正常创建文件进行下载,而Windows下使用µTorrent可以正常下载。 File name too long error

  因此,如果要在Linux下载这些文件,就需要对文件名进行截断处理。rtorrent后端使用libtorrent,简单修改libtorrent代码重新编译就可以了,对于libtorrent-0.13.8,具体修改位置在src/data/socket_file.cc:72

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
bool
SocketFile::open(const std::string& path, int prot, int flags, mode_t mode) {
  close();

  if (prot & MemoryChunk::prot_read &&
      prot & MemoryChunk::prot_write)
    flags |= O_RDWR;
  else if (prot & MemoryChunk::prot_read)
    flags |= O_RDONLY;
  else if (prot & MemoryChunk::prot_write)
    flags |= O_WRONLY;
  else
    throw internal_error("torrent::open(...) Tried to open file with no protection flags");

#ifdef O_LARGEFILE
  fd_type fd = ::open(path.c_str(), flags | O_LARGEFILE, mode);
#else
  fd_type fd = ::open(path.c_str(), flags, mode);
#endif
  
  if (fd == invalid_fd)
    return false;

  m_fd = fd;
  return true;
}

  增加判断path长度,超长则进行截断处理就可以了,简单修改将71-75行修改为以下代码,判断超过240字节截断:

1
2
3
4
5
6
7
8
  std::string new_path = path;
  if (new_path.length() > 240)
      new_path = new_path.substr(0, 240);
#ifdef O_LARGEFILE
  fd_type fd = ::open(new_path.c_str(), flags | O_LARGEFILE, mode);
#else
  fd_type fd = ::open(new_path.c_str(), flags, mode);
#endif

  然后重新编译:

1
./configure;make

  编译出来的动态库位于src/.libs/libtorrent.so.21.0.0,替换原有的libtorrent动态库就可以开心的下载了。