【问题标题】:Reading the linux utmp file without using fopen() and fread()不使用 fopen() 和 fread() 读取 linux utmp 文件
【发布时间】:2014-10-13 05:14:35
【问题描述】:

我正在尝试在 Linux 中打开 utmp 文件并将其内容读入 utmp 结构数组。之后,我显示数组中每个结构的 ut_user 和 ut_type。当我使用File *file 打开文件并使用fopen()fread() 函数时,我可以正常工作,但是当我尝试仅使用文件描述符int fileopen()read() 执行相同的任务时函数我在尝试访问 utmp 结构的成员时获取地址位置。

所以在下面的程序中,您可以看到我注释掉了三行代码,我可以使用它们一起成功地执行将 utmp 文件读入 utmp 结构数组并打印出它们的两个成员值的任务。但是,当我尝试用三行代码(表示为“新方式”)代替旧的方式做完全相同的事情时,我得到了一堆地址位置,而不是ut_userut_id 的值。

    #include <unistd.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <utmp.h>


    void utmpprint(struct utmp *log) {

        printf("\n ut_user: %s \n ut_type: %ld \n", log->ut_user, log->ut_type);
    }


    int main() {

        int logsize = 10;

        //FILE *file;        //Working way
        int file;            //New way

        struct utmp log[logsize];
        int i = 0;

        //file = fopen("/var/run/utmp", "rb");   //Working way
        file = open("/var/run/utmp", O_RDONLY);  //New way

        if( file < 0 ) {  //New way
           printf("Failed to open");
           return(0);
        }

        if (file) {

                //fread(&log, sizeof(struct utmp), logsize, file);  //Working way
                read(file, &log, logsize);                          //New way

                for(i = 0; i < logsize; i++) {

                        utmpprint(&log[i]);
                }

                close(file);     //New way

        } else {
                return(0);
        }

        return(0);
    }

这是工作方式的一些输出:

这是无效的新方法的输出:

我尝试在网上查找有关此问题的更多信息,但我似乎找不到任何使用文件描述符而不是 File 的内容。我还尝试更改一些指针和引用,但这并没有改善任何结果。

我对 C 语言非常陌生,我认为在这种情况下我可能错误地使用了 read() 函数,因为当我认为应该以某种方式将 utmp structure array 传递给 read 函数时,我正在将一个简单的缓冲区传递给它。

【问题讨论】:

  • file = file = open("/var/run/utmp", O_RDONLY);?那是错字吗?当您改为 file = open("/var/run/utmp", O_RDONLY); 时有什么变化吗?此外,您对"success" 的检查应为if (file &gt;= 0) { ... }

标签: c linux file


【解决方案1】:

您没有从文件中读取足够的数据。

read(file, &log, logsize);

应该是:

read(file, &log, sizeof(log));
// or
read(file, &log, logsize * sizeof (struct utmp));

此外,在这两种情况下,您都应该检查返回值以查看实际读取了多少字节。

【讨论】:

    【解决方案2】:

    即使您可以通过使用open() 系统调用或从open() 派生的函数来操作utmp 文件中的数据,但这是不切实际的。

    您可以在项目中包含“utmp.h”标头并使用预定义的函数和数据结构。

    Here你可以找到utmp.h文件文档。

    下面是一些使用 utmp.h 数据结构和函数打印 ut_userut_type 的代码。

    #include <utmp.h>
    #include <stdio.h>
    #include <string.h>
    int main()
    {
        struct utmp* data;
        char aux[50];
        data = getutent();
        //getutent() populates the data structure with information 
        while(data != NULL )
        {
            /*make sure to use strncpy 
             *because most data fiels in the utmp struct 
             *have ___nonstring___ atribute */
            strncpy(aux, data->ut_user, 32);
                    aux[32] = '\0';
            printf("ut_user: %s\n", aux);
            printf("ut_type: %hi\n\n", data->ut_type);
            data = getutent();
        }
        return 0;
    }
    

    代码的输出是:

    ut_user: reboot
    ut_type: 2
        
    ut_user: alc
    ut_type: 7
        
    ut_user: runlevel
    ut_type: 1
    

    【讨论】:

    • 七年后你回答!大声笑,谢谢你
    • 处理那个库太烦人了,我想确保没有人再经历过那个:))
    猜你喜欢
    • 2012-08-06
    • 2014-12-13
    • 1970-01-01
    • 2019-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-18
    • 1970-01-01
    相关资源
    最近更新 更多