C 如何向用户复制字符串并在Linux内核读取函数中使用offp

C 如何向用户复制字符串并在Linux内核读取函数中使用offp,c,linux,linux-kernel,kernel,device,C,Linux,Linux Kernel,Kernel,Device,声明: static char status[128] = "off\0"; 并实现了读取功能: static ssize_t read_proc(struct file *filep, char __user *buf, size_t len, loff_t *offp) { ssize_t cnt = strlen(status), ret; ret = copy_to_user(buf, status, cnt); *of

声明:

static char status[128] = "off\0";
并实现了
读取
功能:

static ssize_t read_proc(struct file *filep, char __user *buf,
                    size_t len, loff_t *offp)
{
    ssize_t cnt = strlen(status), ret;

    ret = copy_to_user(buf, status, cnt);
    *offp += cnt;
    return cnt;
}
  • 我如何考虑
    offp
  • 目前,它将
    状态打印到屏幕上

在函数返回“0”或错误之前,您的read\u proc()不会停止读取。我相信您需要修改read\u proc以获得此逻辑。

在函数返回“0”或错误之前,read\u proc()不会停止读取。我相信您需要修改read_proc以获得此逻辑。

感谢各位的评论,我提出了以下实现,我认为这是使用
offp
的正确方法:

static ssize_t read_proc(struct file *filep, char __user *buf,
                    size_t len, loff_t *offp)
{

    ssize_t cnt = strlen(status), ret;

    /* ret contains the amount of chare wasn't successfully written to `buf` */
    ret = copy_to_user(buf, status, cnt);
    *offp += cnt - ret;

    /* Making sure there are no left bytes of data to send user */
    if (*offp > cnt)
         return 0;
    else
         return cnt;
}

感谢各位的评论,我提出了以下实现,我认为这是使用
offp
的正确方法:

static ssize_t read_proc(struct file *filep, char __user *buf,
                    size_t len, loff_t *offp)
{

    ssize_t cnt = strlen(status), ret;

    /* ret contains the amount of chare wasn't successfully written to `buf` */
    ret = copy_to_user(buf, status, cnt);
    *offp += cnt - ret;

    /* Making sure there are no left bytes of data to send user */
    if (*offp > cnt)
         return 0;
    else
         return cnt;
}

要理解
read
中的返回值,让我引用
Linux设备驱动程序第三版中的内容:

The return value for read is interpreted by the calling application program:

    If the value equals the count argument passed to the read system call, the requested number of bytes has been transferred. This is the optimal case.

    If the value is positive, but smaller than count, only part of the data has been transferred. This may happen for a number of reasons, depending on the device. Most often, the application program retries the read. For instance, if you read using the fread function, the library function reissues the system call until completion of the requested data transfer.

    If the value is 0, end-of-file was reached (and no data was read).

    A negative value means there was an error. The value specifies what the error was, according to <linux/errno.h>. Typical values returned on error include -EINTR (interrupted system call) or -EFAULT (bad address).
参考资料:

  • -第3章

要理解
读取的返回值,让我引用
Linux设备驱动程序第三版的内容:

The return value for read is interpreted by the calling application program:

    If the value equals the count argument passed to the read system call, the requested number of bytes has been transferred. This is the optimal case.

    If the value is positive, but smaller than count, only part of the data has been transferred. This may happen for a number of reasons, depending on the device. Most often, the application program retries the read. For instance, if you read using the fread function, the library function reissues the system call until completion of the requested data transfer.

    If the value is 0, end-of-file was reached (and no data was read).

    A negative value means there was an error. The value specifies what the error was, according to <linux/errno.h>. Typical values returned on error include -EINTR (interrupted system call) or -EFAULT (bad address).
参考资料:

  • -第3章

您所说的“它无休止地打印”到底是什么意思?@MichaelBurr Offoff……。您必须检查并说明传入的offp。如果偏移量大于字符串,则不希望再次复制该字符串。请注意,API提供了一种更简单的方法,例如创建/proc文件。(例如,请参见fs/proc/version.c,了解一个示例您确实需要解释更多的情况-缓冲区是如何被使用它的任何代码使用的?调用此函数的是什么(我猜您使用它来备份设备上打开的文件描述符)。按照您编写它的方式,它还能做什么?您只是将字节['o'、'f'、'f']复制到缓冲区中,大概这是用来备份文件的。您从读取中永远不会返回0字节,因此如果它被用于服务文件描述符,那么用户land程序当然只会读取“offoff”。如果希望用户登录程序停止读取,则需要在某个点返回0。因为
offp
告诉您已经写入了多少字节,所以如果
*offp=>cnt
,则只需返回0。您所说的“它无休止地打印”到底是什么意思?@MichaelBurr Offoff……。您必须检查并说明传入的offp。如果偏移量大于字符串,则不希望再次复制字符串。请注意,API提供了一种更简单的方法,例如创建/proc文件。(例如,请参见fs/proc/version.c,了解一个示例您确实需要解释更多的情况-缓冲区是如何被使用它的任何代码使用的?调用此函数的是什么(我猜您使用它来备份设备上打开的文件描述符)。按照您编写它的方式,它还能做什么?您只是将字节['o'、'f'、'f']复制到缓冲区中,大概这是用来备份文件的。您从读取中永远不会返回0字节,因此如果它被用于服务文件描述符,那么用户land程序当然只会读取“offoff”。如果希望用户登录程序停止读取,则需要在某个点返回0。由于
offp
告诉您已写入多少字节,因此如果
*offp=>cnt
,只需返回0即可。