首页 > 编程语言 >系统编程(触屏和ls指令)

系统编程(触屏和ls指令)

时间:2025-01-10 11:33:17浏览次数:3  
标签:info 文件 编程 strcat char mode 触屏 event ls

触屏实现

  1. 文件操作:
    • open函数:用于打开文件或设备,返回文件描述符。在这里,它用于打开触摸屏设备文件/dev/input/event0
    • read函数:从文件或设备中读取数据。这里,它用于读取触摸事件数据到struct input_event结构体中。
    • close函数:关闭打开的文件或设备。
  2. 结构体与内存操作:
    • struct input_event结构体:这是Linux输入子系统定义的一个结构体,用于表示输入事件。它包含事件类型(type)、事件代码(code)和事件值(value)。
    • memset函数:用于将内存块的内容设置为指定的值,这里用于清零struct input_event结构体,确保在读取新事件前结构体是干净的。
  3. 条件判断与循环:
    • if语句:用于条件判断,这里用于检查事件类型、事件代码和事件值,以确定触摸行为(按下或抬起)和触摸坐标。
    • while循环:用于持续监听触摸事件,直到程序被外部方式终止。
  4. 输入事件处理:
    • 输入事件类型(event.type):EV_KEY表示按键事件,EV_ABS表示绝对坐标事件。
    • 事件代码(event.code):对于EV_KEY类型,BTN_TOUCH表示触摸行为;对于EV_ABS类型,ABS_XABS_Y分别表示X轴和Y轴的绝对坐标。
    • 事件值(event.value):对于EV_KEY类型,值为1表示按下,0表示抬起;对于EV_ABS类型,值表示坐标的具体数值。
  5. 坐标转换:
    • 代码中进行了坐标转换,以适应不同触摸屏的分辨率。例如,X坐标被乘以800/1024,Y坐标被乘以480/600,这可能是为了将触摸屏的原生分辨率转换为应用程序或显示设备所需的分辨率。
  6. 错误处理:
    • 使用perror函数打印打开文件失败时的错误信息。
  7. Linux输入子系统:
    • 这段代码展示了如何在Linux环境下使用输入子系统来读取和处理来自输入设备(如触摸屏)的事件。输入子系统是Linux内核的一部分,提供了一种统一的方式来处理各种输入设备。
  8. 头文件包含:
    • #include <stdio.h>:包含标准输入输出库的头文件,用于printfputs等函数。
    • #include "header.h":可能是一个自定义头文件,但在这段代码中没有给出其内容。它可能包含了一些额外的定义或声明。
    • #include <linux/input.h>:包含Linux输入子系统相关的定义和声明,如struct input_event结构体和事件类型常量。
#include <stdio.h>
#include "header.h"
#include <linux/input.h>


//触摸屏的设备文件路径
#define DEV_TOUCH "/dev/input/event0"

int main(int argc, char const *argv[])
{
    //1.打开文件
    int fd = open(DEV_TOUCH, O_RDONLY);
    if (fd == -1)
    {
        perror("open touch failed");
        return -1;
    }

    //2.操作文件
    //定义结构体变量
    struct input_event event;
    //结构体清零操作
    memset(&event, 0, sizeof(event));
    //循环检测输入设备的状态变化
    while (1)
    {
        //读取输入设备文件数据到结构体中
        read(fd, &event, sizeof(event));
        /*
        type:  区分事件的类型:EV_KEY: 类似按键行为
        code:  进一步筛选事件:
            BTN_TOUCH   :触摸行为
        value:  进一步筛选事件
            0抬起状态,1按下状态
        */
       //检测手指的按下或抬起状态
       if (event.type == EV_KEY)
       {
            if (event.code == BTN_TOUCH)
            {
                printf("%d\n", event.value); 
                if (event.value ==1)
                    puts("手指按下状态!");
                else
                     puts("手指抬起状态!");
            }       
       } 

       //检测手指触摸的坐标
       if (event.type == EV_ABS)
       {
            if (event.code == ABS_X)
            {
                //GEC6818有两个批次,黑色地板和蓝色地板;蓝色地板代码不变
                //printf("X方向的绝对坐标值是:%d\n", event.value);
                //黑色地板的触摸检查范围是1024   600; 可以做如下的处理
                printf("X方向的绝对坐标值是:%d\n", event.value * 800 / 1024);
            }
            else if(event.code == ABS_Y)
            {
                //printf("Y方向的绝对坐标值是:%d\n", event.value);
                 //黑色地板的触摸检查范围是1024   600; 可以做如下的处理
                printf("X方向的绝对坐标值是:%d\n", event.value * 480 / 600);
            }      
       }
    
       //结构体清零操作
        memset(&event, 0, sizeof(event));   
    }
    //3.关闭文件
    close(fd);
    return 0;
}

在这里插入图片描述

ls指令实现

  1. 文件类型判断:

    • S_ISLNK(mode)S_ISREG(mode)S_ISDIR(mode)S_ISCHR(mode)S_ISBLK(mode)S_ISSOCK(mode)S_ISFIFO(mode):这些宏用于判断文件的类型,如符号链接、普通文件、目录、字符设备文件、块设备文件、套接字和命名管道(FIFO)。
    • mode_t:这是一个数据类型,用于表示文件的模式(包括类型和权限)。
    st_mode 常见取值: (八进制,文件类型主要取决第3字节)
    S_IFSOCK     0140000           socket 套接字文件
    S_IFLNK        0120000          链接文件
    S_IFREG        0100000          一般文件
    S_IFBLK         0060000         块设备文件
    S_IFDIR         0040000         目录
    S_IFCHR        0020000        字符设备文件
    S_IFIFO         0010000         管道文件
    上述的文件类型在POSIX中定义了检查这些类型的宏定义:
    S_ISLNK (st_mode)                判断是否为链接文件
    S_ISREG (st_mode)               是否为一般文件
    S_ISDIR (st_mode)                是否为目录
    S_ISCHR (st_mode)              是否为字符设备文件
    S_ISBLK (st_mode)               是否为块设备文件
    S_ISSOCK (st_mode)            是否为socket套接字文件
    S_ISFIFO (st_mode)             是否为管道文件 
    
    
  2. 文件权限处理:

    • S_IRWXUS_IRUSRS_IWUSRS_IXUSR:这些宏分别表示用户(文件所有者)的读、写、执行权限。
    • S_IRWXGS_IRGRPS_IWGRPS_IXGRP:这些宏分别表示用户组的读、写、执行权限。
    • S_IRWXOS_IROTHS_IWOTHS_IXOTH:这些宏分别表示其他用户的读、写、执行权限。
    • 位运算(&):用于提取特定的权限位。
    S_IRWXU  00700 文件拥有者可读,可写,可执行
    S_IRUSR   00400 文件拥有者可读
    S_IWUSR  00200 文件拥有者可写
    S_IXUSR   00100 文件拥有者可执行 
    
    S_IRWXG  00070 组用户可读,可写,可执行
    S_IRGRP   00040 组用户可读
    S_IWGRP  00020 组用户可写
    S_IXGRP   00010 组用户可执行
    
    S_IRWXO  00007 其他组用户可读,可写,可执行
    S_IROTH   00004 其他组用户可读
    S_IWOTH  00002 其他组用户可写
    S_IXOTH   00001 其他组用户可执行
    
    
  3. 字符串操作:

    • strcat:用于连接两个字符串。在这里,它用于将权限字符(如"rwx")追加到info字符串的末尾。
    • 字符数组(char *info):用于存储最终的文件类型和权限信息。
  4. 用户和组信息获取:

    • uid_tgid_t:这些数据类型分别用于表示用户ID和组ID。
    • getpwuid:根据用户ID获取用户信息结构体passwd
    • getgrgid:根据组ID获取组信息结构体group
    • struct passwdstruct group:这些结构体分别包含用户和组的信息,如用户名、组名、用户ID、组ID等。
    • pw_namegr_name:这些成员分别表示用户名和组名。
    struct passwd {
                   char*   pw_name;                   /* user name */
                   char*   pw_passwd;                /* user password */
                   uid_t    pw_uid;                         /* user ID */
                   gid_t    pw_gid;                          /* group ID */
                   char*  pw_gecos;                    /* user information */
                   char*  pw_dir;                         /* home directory */
                   char*  pw_shell;                      /* shell program */
               };
    struct group {
                   char*   gr_name;                     /* group name */
                   char*   gr_passwd;                  /* group password */
                   gid_t     gr_gid;                           /* group ID */
                   char** gr_mem;                    /* group members */
             };
    
    
  5. 错误处理:

    • getOwnerGroupName函数中,通过检查getgrgid的返回值是否为NULL来处理获取组信息失败的情况。
  6. 结构体成员访问:

    • 代码通过pstat->st_modepstat->st_uidpstat->st_gid来访问Stat结构体(这里假设是struct stat的别名或类似结构)的成员,这些成员分别表示文件的模式、所有者的用户ID和所有者的组ID。
  7. 函数设计和返回值:

    • 每个函数都接受一个指向Stat结构体的指针和一个字符数组作为参数,用于获取文件信息并填充到字符数组中。
    • 函数的返回值用于表示操作的成功或失败(尽管在某些函数中,如getOwnerPremgetgrPremgetgrrPrem,返回值似乎没有被充分利用)。
  8. 打印调试信息:

    • printf用于打印文件的模式(以八进制表示)和用户组权限的调试信息。

需要注意的是,代码中有几个潜在的问题和改进点:

  • getFileType函数没有返回值,但根据函数名和上下文,它应该返回一个表示文件类型的字符或某种状态码。然而,它实际上是通过修改info字符串来传达信息的。
  • getOwnerPremgetgrPremgetgrrPrem函数中,虽然计算了权限并更新了info字符串,但返回值没有被用来表示不同的权限组合情况,这可能导致调用者无法准确知道函数执行的结果。
  • 在使用strcat之前,应该检查info字符串是否有足够的空间来容纳追加的内容,以避免缓冲区溢出。
  • Stat结构体在代码中没有定义,但根据上下文,它应该是struct stat的别名或具有相似成员的自定义结构体。在实际使用中,需要确保这个结构体与stat系统调用的输出兼容。
myls.c

#include "header.h"

// 1.获取文件的类型
int getFileType(Stat *pstat, char *info)
{
    // 获取结构体成员的值
    mode_t mode = pstat->st_mode;
    printf("mode: %o\n", mode);
    // 判断文件类型
    if (S_ISLNK(mode))
        info[0] = 'l';
    else if (S_ISREG(mode))
        info[0] = '-';
    else if (S_ISDIR(mode))
        info[0] = 'd';
    else if (S_ISCHR(mode))
        info[0] = 'c';
    else if (S_ISBLK(mode))
        info[0] = 'b';
    else if (S_ISSOCK(mode))
        info[0] = 's';
    else if (S_ISFIFO(mode))
        info[0] = 'p';
}

int getOwnerPrem(Stat *pstat, char *info)
{
    // 获取结构体成员的值
    mode_t mode = pstat->st_mode; // 40542
    /*
     100 000 101 100 010
&    000 000 111 000 000
---------------------------
     000 000 101  000 000
     0   0   5    0   0

    */
    // 判断文件类型
    // int perm = mode & 00700;   drwx0000000000000000
    int perm = mode & S_IRWXU;
    if (perm == S_IRWXU)
        strcat(info, "rwx");
    else if (perm == S_IRUSR)
        strcat(info, "r--");
    else if (perm == S_IWUSR)
        strcat(info, "-w-");
    else if (perm == S_IXUSR)
        strcat(info, "--x");
    else if (perm == (S_IRUSR | S_IWUSR))
        strcat(info, "rw-");
    else if (perm == (S_IXUSR | S_IWUSR))
        strcat(info, "-wx");
    else if (perm == (S_IXUSR | S_IRUSR))
        strcat(info, "r-x");
    else
        strcat(info, "---");
}
// 用户组权限
int getgrPrem(Stat *pstat, char *info)
{
    // 获取结构体成员的值
    mode_t mode = pstat->st_mode; // 40542
    printf("用户组权限\n");
    int perm = mode & S_IRWXG; // 获取用户组权限位
    switch (perm)
    {
    case S_IRWXG:
        strcat(info, "rwx");
        break;
    case S_IRGRP:
        strcat(info, "r--");
        break;
    case S_IWGRP:
        strcat(info, "-w-");
        break;
    case S_IXGRP:
        strcat(info, "--x");
        break;
    case (S_IRGRP | S_IWGRP):
        strcat(info, "rw-");
        break;
    case (S_IXGRP | S_IWGRP):
        strcat(info, "-wx");
        break;
    case (S_IXGRP | S_IRGRP):
        strcat(info, "r-x");
        break;
    default:
        strcat(info, "---");
        break;
    }

    // 返回一些值,这里假设返回1表示成功
    return 1;
}
// 其他用户
int getgrrPrem(Stat *pstat, char *info)
{
    // 获取结构体成员的值
    mode_t mode = pstat->st_mode; // 40542
    printf("其他用户权限\n");
    int perm = mode & S_IRWXO; // 获取用户组权限位
    switch (perm)
    {
    case S_IRWXO:
        strcat(info, "rwx");
        break;
    case S_IROTH:
        strcat(info, "r--");
        break;
    case S_IWOTH:
        strcat(info, "-w-");
        break;
    case S_IXOTH:
        strcat(info, "--x");
        break;
    case (S_IROTH | S_IWOTH):
        strcat(info, "rw-");
        break;
    case (S_IXOTH | S_IWOTH):
        strcat(info, "-wx");
        break;
    case (S_IXOTH | S_IROTH):
        strcat(info, "r-x");
        break;
    default:
        strcat(info, "---");
        break;
    }

    // 返回一些值,这里假设返回1表示成功
    return 1;
}

// 6.获取文件的所属名称
int getOwnerName(Stat *pstat, char *info)
{
    // 获取所属用户的uid
    uid_t uid = pstat->st_uid;
    // 调用函数通过用户id获取用户名称
    struct passwd *passwd_p = getpwuid(uid);
    // 获取结构体成员中的name
    char *uname = passwd_p->pw_name;
    strcat(info, "  ");
    // 将用户名拼接到字符串中
    strcat(info, uname);
}

// 7.获取文件所属组名称
int getOwnerGroupName(Stat *pstat, char *info)
{
    // 获取所属组的gid
    gid_t gid = pstat->st_gid;
    // 调用函数通过组id获取组信息
    struct group *grp_p = getgrgid(gid);
    if (grp_p == NULL)
    {
        strcat(info, "  [unknown group]");
        return -1; // 返回错误码表示失败
    }
    // 获取结构体成员中的组名
    char *gname = grp_p->gr_name;

    // 在info字符串中添加空格和组名
    strcat(info, "  ");
    strcat(info, gname);

    return 0;
}
header.c
#ifndef _HEARD_H
#define _HEARD_H

// 常用头文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// access, read, write, lseek, stat
#include <unistd.h>
// open, lseek, stat, getpwuid
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <grp.h>

// mmap, munmap
#include <sys/mman.h>

// getpwuid
#include <pwd.h>

typedef struct stat Stat;
// 1.获取文件的类型
int getFileType(Stat *pstat, char *info);
int getOwnerPrem(Stat *pstat, char *info);
int getgrPrem(Stat *pstat, char *info);
int getgrrPrem(Stat *pstat, char *info);
// 6.获取文件的所属名称
int getOwnerName(Stat *pstat, char *info);
int getOwnerGroupName(Stat *pstat, char *info);
#endif
main.c
#include <stdio.h>
#include "header.h"

int main(int argc, char const *argv[])
{
    if (argc < 2)
    {
        puts("缺少参数");
        return -1;
    }
    puts(argv[1]);

    // 调用stat函数获取文件的状态信息
    Stat fstat = {0};
    // int r = stat(argv[1], &fstat);
    int r = lstat(argv[1], &fstat);
    if (r == -1)
    {
        perror("stat failed");
        return -1;
    }

    // 定义一个数组,用于凭借文件的状态信息:-rwxrwxrwx 1 root root 2250 1月   9 15:08 07-touch-screen.c
    char info[100] = {0};
    // 1.调用函数获取文件的类型并拼接的info中
    getFileType(&fstat, info);
    // 2.获取文件用户者的权限
    getOwnerPrem(&fstat, info);
    // 3.获取同组用户的权限---自学
    getgrPrem(&fstat, info);
    // 4.获取不同组的其他用户权限---自学
    getgrrPrem(&fstat, info);
    // 5.获取链接数量

    // 6.获取文件所属用户名称
    getOwnerName(&fstat, info);

    // 7.获取文件所属组名称---自学
    getOwnerGroupName(&fstat, info);
    // 打印文件信息
    puts(info);

    return 0;
}

在这里插入图片描述

标签:info,文件,编程,strcat,char,mode,触屏,event,ls
From: https://blog.csdn.net/weixin_69851948/article/details/145042429

相关文章

  • SQLSER中使用DATALENGTH 函数返回字符串的字节长度
    DATALENGTH函数返回字符串的字节长度,这对于varchar类型的字段非常有用,因为varchar类型的字段存储的是变长字符串,其实际占用的字节数可能小于定义的最大长度。示例假设有一个表Articles,其中有一个varchar类型的字段Content,你想查询每篇文章内容的实际占用字节数,可以使用......
  • 新版 Cursor 把其他 AI 编程工具按在地上摩擦了!
    大家好,我是汤师爷~AI编程助手Cursor背后的Anysphere公司刚刚完成了1亿美元的B轮融资,估值直接飙升至26亿美元。四个月前,这家公司刚拿下6000万美元,估值还只有4亿美元。如今,增长6.5倍,这速度,简直让人怀疑开挂了。Anysphere不仅融资拿到手软,收入增长更是逆天。公司从4月的年收入400......
  • SQLSERVER截取q前300字节长度
    在SQLServer中,如果你想截取一个字符串的前300个字节,可以使用LEFT函数结合DATALENGTH函数来实现。LEFT函数用于从字符串的左侧开始截取指定长度的字符,而DATALENGTH函数用于获取字符串的实际字节长度。示例假设有一个表Articles,其中有一个varchar类型的字段Conten......
  • 【Spring Cloud编程】Spring Cloud 集成AlloyDB
    1.AlloyDB是什么?AlloyDB是GoogleCloud提供的一种高度可扩展、强性能的关系型数据库服务,它兼容PostgreSQL,并提供了更快的查询性能和更高的可用性。AlloyDB主要适用于需要处理复杂查询、高吞吐量和对数据库性能要求严格的应用场景。AlloyDB的工作原理AlloyDB是建立在Goo......
  • 在Java并发编程中保证操作的原子性的方法
    在Java并发编程中,保证操作的原子性是确保数据一致性和程序正确性的关键。以下是几种常见的方法及其使用场景:1. synchronized 关键字实现原理:synchronized关键字用于同步代码块或方法,以确保同一时间只有一个线程可以执行该代码块或方法。它通过内部锁机制来实现,当一个线程......
  • macOS的PrivilegedHelperTools文件夹
    在 macOS 上,/Library/PrivilegedHelperTools 文件夹是一个特殊的位置,用于存放可以以更高权限运行的辅助工具或守护进程。这些工具通常由各种应用程序安装,以执行需要超出普通应用程序沙箱权限的任务,例如Proxy的应用,常见都是带有helper的应用。让我们更详细地了解这个目录及其用......
  • 基于CNN卷积神经网络的金融数据预测matlab仿真,对比BP,RBF,LSTM
    1.程序功能描述基于CNN卷积神经网络的金融数据预测matlab仿真,对比BP神经网络,RBF神经网络,LSTM网络.对比预测结果和预测误差。2.测试软件版本以及运行结果展示MATLAB2022A版本运行 3.核心程序fori=1:floor(length(data1)/5);p1w(5*i-4:5*i,1)=[p1(i......
  • 在Lazarus下的Free Pascal编程教程——打造有智能感知的用户设置操作界面
    0.前言我想通过编写一个完整的游戏程序方式引导读者体验程序设计的全过程。我将采用多种方式编写具有相同效果的应用程序,并通过不同方式形成的代码和实现方法的对比来理解程序开发更深层的知识。了解我编写教程的思路,请参阅体现我最初想法的那篇文章中的“1.编程计划”和“2.已经......
  • 【Spring Aop】使用全攻略,开启面向切面编程世界的大门
    概述使用AOP(面向切面编程)可以帮助你实现横切关注点(如日志记录、事务管理、权限控制等)的分离,比如你对外提供了一个接口,接口上线后产品又要求需要对接口的出入参做记录,以提供数据支撑供业务分析以及方便问题排查。你想着,这不简单嘛,我只要在接口返回的时候发送一个MQ记录下......
  • C++泛型编程:类模版中成员函数的创建时机,类模版函数传参、类模版继承
    普通类的成员函数的话,在刚开始就创建出来了,但是类模版中的成员函数的话,只有在具体调用运行的时候才会被创建,可见以下代码例子:#include<iostream>usingnamespacestd;classpeople1{public: voidrun(){ cout<<"跑"<<endl; }};classcircle1{public: void......