【问题标题】:Read input without specifying input length读取输入而不指定输入长度
【发布时间】:2021-03-11 15:09:05
【问题描述】:

我正在尝试让用户输入任意长度。

更具体地说,我正在尝试从输入中读取将使用mkdir 系统调用(0x27)创建的目录。但是由于这种特异性仅适用于mkdir;您还可以包括我的程序“创建目录”的问题;我有多个这样的程序。

如果没有 C 库将不胜感激。

我试过了

mov r7, #0x04
mov r0, #0x00
ldr r1, =some_variable
mov r2, #(1 << 30)
swi 0x00

但它可以工作(在终止的字符串上);不过,我想知道其他解决方法。

【问题讨论】:

  • 您的意思是读取目录条目,例如使用 getdents Linux 系统调用 (man7.org/linux/man-pages/man2/getdents.2.html)?系统调用需要一个大小;你可以传递一个大的尺寸,但如果 API 不能指定已经分配的缓冲区用户空间的大小,那就没有意义了。
  • 或者你想读取一个字符串,然后用那个名字作为 mkdir?同样,您不告诉read 缓冲区的限制是没有意义的。 man7.org/linux/man-pages/man2/read.2.html。你希望发生什么样的事情?就像那个系统调用会为你分配内存把输入放进去?如果您是从管道或套接字读取,splice(2) 我认为曾经试图让您这样做 (man7.org/linux/man-pages/man2/splice.2.html),但它远没有read 简单。鉴于SPLICE_F_MOVE 的文档,我认为这实际上是不可能的
  • 有点蒙眼的帖子,已编辑。
  • 哦,没关系,我想的是“分配”部分而不是长度部分:拼接/vmsplice 确实需要长度。而且似乎您无法让内核为您提供页面,只有在写入管道时使用 vmsplice 将页面提供给内核的相反。
  • 有什么问题?一般来说,读取输入通常不是问题。分配一个合理大小的缓冲区,如本例中的 PATH_MAX,然后将 read() 放入其中。如果 read 返回缓冲区大小,则可能还有更多内容要读取。

标签: linux assembly arm system-calls armv7


【解决方案1】:

一般来说,如果你不知道长度但想读取所有数据,你将不得不分块读取。块大小可以是任意大小,小至 1 字节,大至任意大小。

某些数据结构不适合这种分块,因此对于它们,我们需要将来自固定大小读取的块组合成可以处理的单元的策略。可变长度记录(例如文本行)可能属于这一类,其中有时一行的长度会超过固定的块大小,但处理算法希望看到整行。

有时我们必须将所有块合并到一个缓冲区中以进行进一步处理。与其一开始就分配尽可能大的缓冲区,不如使用动态内存分配和内存复制来最终呈现连续的数据缓冲区。

过大的数据集可能需要特殊处理,例如使用 64 位计算机。内存映射文件也是一个选项,可以在应用程序级别删除一些缓冲,有利于让系统这样做。

以上内容无论是用 C 还是汇编语言编写都适用。

【讨论】:

    猜你喜欢
    • 2020-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    • 2011-03-07
    • 2019-04-28
    相关资源
    最近更新 更多