最近工作的一个项目,使用libssh2在HP-UX环境下实现SFTP的文件传输。测试时发现一个问题,使用libssh2_sftp_rename重命名文件时,若目标文件已经存在,总是不能成功。使用libssh2_sftp_last_error得到的错误代码是LIBSSH2_FX_FAILURE(4),基本没有参考价值;另外可排除用户权限因素。
查阅libssh2的文档及include/libssh2_sftp.h文件,得知libssh2_sftp_rename实际是libssh2_sftp_rename_ex的宏定义,该宏传入的flags参数是LIBSSH2_SFTP_RENAME_OVERWRITE | LIBSSH2_SFTP_RENAME_ATOMIC | LIBSSH2_SFTP_RENAME_NATIVE,即包含了覆盖已存在文件的选项,可为什么还是失败呢?继续追查libssh2_sftp_rename_ex的实现,逐步跟踪到src/sftp.c文件中的sftp_rename函数,发现这段代码。
1 2 |
|
这是flags参数唯一出现的地方,也就是说只有SFTP服务器协议版本不小于5时,重命名的那些选项才有效,HP-UX上出现的很有可能就是这种情况。为了证实,使用系统内建的sftp工具连接,输入version命令,得到以下输出。
1 2 |
|
显然,SFTP服务协议版本就是造成这个问题的原因,解决办法很简单,重命名文件之前调用libssh2_sftp_unlink删除目标文件即可。libssh2应该在文档中说明SFTP服务协议版本对相关函数的影响。
此问题在HP-UX B.11.31/IA-64和B.11.11/PA-RISC中都存在。