Toolbox中ls不支持超过2G文件的问题

       一般的嵌入式系统是32位的。所以默认都支持不了超过2G的文件。实测了一下,放一个3G的文件到U盘。然后ls

 

17:10:16.305:uid=0 gid=0@gold:/mnt/udisk/4g # ls

17:10:18.108: lstat './4gfile.img' failed: Value too largefor defined data type

 

       因为整个系统的升级包是超过2G的,所以需要toolbox能够支持超过2G的文件。上网搜索一下,说如果在32位系统中支持大文件的话,只需要打开一个配置:-D_FILE_OFFSET_BITS=64

 

       在系统中grep了一下,发现系统中有其它模块已经有打开此功能了,所以就参考了一下。拷贝了两个宏定义,放在所有的include之前。

#define_FILE_OFFSET_BITS 64

#define_LARGEFILE64_SOURCE 1

 

       编译了一版,测试,发现不报错,但加-l参数时文件名显示不出来,另外文件大小也是错误的。

15:50:33.112: uid=0gid=0@gold:/mnt/udisk/4g # ls

15:50:34.008: 3gFile.img

15:50:34.008: UPDATE_G.KEY

15:50:34.012: uid=0gid=0@gold:/mnt/udisk/4g # ls -l

15:50:36.116: ----rwxr-x 1000     1023    -551550976 (null) 2016-11-01 10:15

15:50:36.121: ----r-xr-x 1000     1023            0 (null)2016-08-30 15:08

 

       看了一下ls的代码。system/core/toolbox/ls.c,实现比较简单,如果加了-l,会调用listfile_long()这个函数。如果是普通文件,打印是在

   case S_IFREG:

        printf("%s %-8s %-8s %8ld %s%s\n",

               mode, user, group, s.st_size,date, name);

       break;

 

       如果超过2G,算了一下,长度应该是10,所以修改了一下此函数。

    case S_IFREG:

-        printf("%s %-8s %-8s %8ld %s%s\n",

-               mode, user, group, s.st_size,date, name);

+        printf("%s %-8s %-8s %10lu %s%s\n",

+               mode, user, group, (unsignedlong)s.st_size, date, name);

        break;

 

       再测试,文件名和大小显示正常了。

16:48:14.758: uid=0gid=0@gold:/mnt/udisk/4g # ls -l

16:48:16.286: ----rwxr-x1000     1023     3743416320 2016-11-01 10:15 3gFile.img

16:48:16.291: ----r-xr-x 1000     1023              0 2016-08-30 15:08 UPDATE_G.KEY

 

       但还有点小毛病,就是不对齐。把其它文件格式显示也增加两个空格,问题解决。本想把这两个宏定义放在Make文件中,但cp.c会提示编译错误:error: #error <fts.h> cannot be used with-D_FILE_OFFSET_BITS==64

 

       暂时就不去解决cp的问题了。所以就把宏定义在单独的工具中。最终的修改如下:

--- a/system/core/toolbox/dd.c

+++ b/system/core/toolbox/dd.c

@@ -33,6 +33,8 @@

  *SUCH DAMAGE.

  */

 

+#define_FILE_OFFSET_BITS 64

+#define_LARGEFILE64_SOURCE 1

 #include <sys/cdefs.h>

 #ifndef lint

diff --git a/system/core/toolbox/ls.cb/system/core/toolbox/ls.c

index 357c5c7..29bd795 100644 (file)

--- a/system/core/toolbox/ls.c

+++ b/system/core/toolbox/ls.c

@@ -1,3 +1,6 @@

+#define_FILE_OFFSET_BITS 64

+#define_LARGEFILE64_SOURCE 1

#include <stdio.h>

 #include <stdlib.h>

 #include <string.h>

@@ -101,7 +104,7 @@ static intshow_total_size(const char *dirname, DIR *d, int flags)

    struct dirent *de;

    char tmp[1024];

    struct stat s;

-    int sum = 0;

+    int64_t sum = 0;

 

    /* run through the directory and sum up the file block sizes */

    while ((de = readdir(d)) != 0) {

@@ -124,7 +127,7 @@ static intshow_total_size(const char *dirname, DIR *d, int flags)

        sum += s.st_blocks / 2;

    }

 

-    printf("total %d\n", sum);

+    printf("total %lld\n", sum);

    rewinddir(d);

    return 0;

 }

@@ -140,7 +143,7 @@ static int listfile_size(constchar *path, const char *filename, int flags)

 

    /* blocks are 512 bytes, we want output to be KB */

    if ((flags & LIST_SIZE) != 0) {

-        printf("%ld ", s.st_blocks /2);

+        printf("%lld ", s.st_blocks /2);

    }

 

    if ((flags & LIST_CLASSIFY) != 0) {

@@ -202,14 +205,14 @@ static intlistfile_long(const char *path, int flags)

    switch(s.st_mode & S_IFMT) {

    case S_IFBLK:

    case S_IFCHR:

-        printf("%s %-8s %-8s %3d, %3d %s%s\n",

+        printf("%s %-8s %-8s %3d, %3d   %s %s\n",

                mode, user, group,

                (int) MAJOR(s.st_rdev), (int)MINOR(s.st_rdev),

                date, name);

        break;

    case S_IFREG:

-        printf("%s %-8s %-8s %8ld %s%s\n",

-               mode, user, group, s.st_size,date, name);

+        printf("%s %-8s %-8s %10lu %s%s\n",

+               mode, user, group, (unsignedlong)s.st_size, date, name);

        break;

    case S_IFLNK: {

        char linkto[256];

@@ -227,12 +230,12 @@ static int listfile_long(constchar *path, int flags)

            linkto[len] = 0;

        }

 

-        printf("%s %-8s %-8s          %s %s -> %s\n",

+        printf("%s %-8s %-8s            %s %s -> %s\n",

                mode, user, group, date, name,linkto);

         break;

    }

    default:

-        printf("%s %-8s %-8s          %s %s\n",

+        printf("%s %-8s %-8s            %s %s\n",

                mode, user, group, date, name);

 

    }

 

       看了一下代码,dd默认应该是可以支持超过2G的文件的。但在调用dd时好象也会去调用stat相关函数,所以会报同样的错,加上两个宏就可以了。实测可以正常dd操作超过2G的文件。

 

       Toolbox中的ls及dd可以支持2G文件了,但在shell脚本中,if [ -fxxx ] 还不能支持超过2G的文件,还需要查一下。看了一下当前系统的shell,使用的是mksh,文件在externals/mksh目录下,if [ -f xxx ] 的判断应该是在funcs.c文件的test_eval()函数中:

       /*-a */

       caseTO_FILAXST:

       /* -e */

       caseTO_FILEXST:

              return(stat(opnd1, &b1) == 0);

 

       和之前一样,试着在Makefile中增加两个宏定义,编译出版本测试了一下。问题解决。

@@ -61,6 +61,8 @@ LOCAL_CFLAGS:=               -DMKSH_DEFAULT_EXECSHELL=\"/bin/sh\" \

                        -DHAVE_REVOKE_DECL=1-DHAVE_SYS_SIGLIST_DECL=1 \

                        -DHAVE_PERSISTENT_HISTORY=0

 

+LOCAL_CFLAGS +=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE=1

+

 LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)/bin

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值