原内核版本4.0.3的工程内,使用软件包FTP服务器一直运行正常,移植4.0.4(完全覆盖rtthread路径,无4.0.3内核的文件残留)后,通过以太网链接FTP服务器正常登录,但涉及文件读写时出现文件打开错误,返回值550 "/temp/qbt_report.txt" : not a regular file,根据返回内容找到代码异常位置,该问题原因是fopen打开文件是返回值是NULL,确认过文件路径存在,把fopen替换成open后,FTP服务器功能正常,请问fopen的参数是通过什么方式传递到open函数,在syscall.c内的open_r内打印path文件名为乱码,请求大佬点拨一下,如何修复fopen的文件打开异常的问题。
你好 该问题已经修复:https://github.com/RT-Thread/rt-thread/pull/5267
经过再次查证,这个不是arm-链的问题,
历史上fcntl.h有两种标准,一个是以16进制进行编码的版本 也就是newlib arm链用的https://github.com/bminor/newlib/blob/80cda9bbda04a1e9e3bee5eadf99061ed69ca5fb/newlib/libc/include/sys/_default_fcntl.h
还有一种是8进制编码的标准 也就是rtt给keil iar以及musl库用的 https://github.com/bminor/musl/blob/cfdfd5ea3ce14c6abf7fb22a531f3d99518b5a1b/arch/arm/bits/fcntl.h
这两种标准的编码值并不相同,因此造成了冲突,这个问题是我在4.0.4整理libc时引入的。目前已经修复了。
4.0.4是一个快速过度版本,会在年底左右发布4.0.5或者4.1.0版本
fopen模式最近有小伙伴反应rb+是有偶问题的,如果改成r就是可以打开来,主要是arm-none-eabi-gcc的bug,用IAR和keil是可以的。楼主可以试下
在移植4.0.4的时候,有一个地方比较特别,dfs.h内的头文件fctnl.h,与sys/fctnl.h这个头文件定义的内容是不相同的,fctnl.h是RTT内核提供的头文件,sys/fctnl.h是gcc工具链提供的头文件,fopen产生的flags是符合sys/fctnl.h内的定义。
#ifndef _SYS__DEFAULT_FCNTL_H_
#ifdef __cplusplus
extern "C" {
#endif
#define _SYS__DEFAULT_FCNTL_H_
#include <_ansi.h>
#include <sys/cdefs.h>
#define _FOPEN (-1) /* from sys/file.h, kernel use only */
#define _FREAD 0x0001 /* read enabled */
#define _FWRITE 0x0002 /* write enabled */
#define _FAPPEND 0x0008 /* append (writes guaranteed at the end) */
#define _FMARK 0x0010 /* internal; mark during gc() */
#define _FDEFER 0x0020 /* internal; defer for next gc pass */
#define _FASYNC 0x0040 /* signal pgrp when data ready */
#define _FSHLOCK 0x0080 /* BSD flock() shared lock present */
#define _FEXLOCK 0x0100 /* BSD flock() exclusive lock present */
#define _FCREAT 0x0200 /* open with file create */
#define _FTRUNC 0x0400 /* open with truncation */
#define _FEXCL 0x0800 /* error on open if file exists */
#define _FNBIO 0x1000 /* non blocking I/O (sys5 style) */
#define _FSYNC 0x2000 /* do all writes synchronously */
#define _FNONBLOCK 0x4000 /* non blocking I/O (POSIX style) */
#define _FNDELAY _FNONBLOCK /* non blocking I/O (4.2 style) */
#define _FNOCTTY 0x8000 /* don't assign a ctty on this open */
#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
/*
* Flag values for open(2) and fcntl(2)
* The kernel adds 1 to the open modes to turn it into some
* combination of FREAD and FWRITE.
*/
#define O_RDONLY 0 /* +1 == FREAD */
#define O_WRONLY 1 /* +1 == FWRITE */
#define O_RDWR 2 /* +1 == FREAD|FWRITE */
#define O_APPEND _FAPPEND
#define O_CREAT _FCREAT
#define O_TRUNC _FTRUNC
#define O_EXCL _FEXCL
#define O_SYNC _FSYNC
/* O_NDELAY _FNDELAY set in include/fcntl.h */
/* O_NDELAY _FNBIO set in include/fcntl.h */
#define O_NONBLOCK _FNONBLOCK
#define O_NOCTTY _FNOCTTY
/* For machines which care - */
#if defined (__CYGWIN__)
#define _FBINARY 0x10000
#define _FTEXT 0x20000
#define _FNOINHERIT 0x40000
#define _FDIRECT 0x80000
#define _FNOFOLLOW 0x100000
#define _FDIRECTORY 0x200000
#define _FEXECSRCH 0x400000
#define O_BINARY _FBINARY
#define O_TEXT _FTEXT
#define O_CLOEXEC _FNOINHERIT
#define O_DIRECT _FDIRECT
#define O_NOFOLLOW _FNOFOLLOW
#define O_DSYNC _FSYNC
#define O_RSYNC _FSYNC
#define O_DIRECTORY _FDIRECTORY
#define O_EXEC _FEXECSRCH
#define O_SEARCH _FEXECSRCH
#endif
#define _FREAD 0x0001 /* read enabled */
#define _FCREAT 0x0200 /* open with file create */
#define _FTRUNC 0x0400 /* open with truncation */
#define _FBINARY 0x10000
#define O_WRONLY 1 /* +1 == FWRITE */
#define O_CREAT _FCREAT
#define O_TRUNC _FTRUNC
#define O_BINARY _FBINARY
四个宏组合起来就是 0x10601 = 0203001 是符合上述的flags值
跟 FILE *fp = fopen(path, "wb"); 代码传递的参数吻合
应该是RTT内核的fctnl.h与编译器的sys/fctnl.h定义上有冲突,但是我编译的时候并没有提示redefined的警告,这个就很神奇了
总结的很到位。给你点个赞。不知道是否有解决方案,有的话欢迎PR,也欢迎讲你的理解提交到下面issue里面
https://github.com/RT-Thread/rt-thread/issues/5186
好的,期待新版本的发布。