IO进程线程DAY 4

该代码段展示了使用C语言模拟实现ls-l命令的功能,包括获取文件状态、类型、权限、用户和组名、时间戳以及文件名。代码包含多个辅助函数,如GetStat、GetType、GetMode等,以及主函数MainFunc,该函数读取目录并打印出文件的详细信息。
摘要由CSDN通过智能技术生成

代码:

LS_Head.h:

/***********************************************************************
 * File name    : LS_Head.h
 * Module Name  : LS
 * Author       : George
 * Create Date  : 2023.03.27
 * Abstract Description: 用于模拟实现ls -l功能
 * 
 * ------------------------- Revision History -------------------------
 *  No  Version Date        Revise By   Item        Deacription
 *  1   V1.0    2023.03.27  George      (omit)      用于模拟实现ls -l功能
 *  2   v1.1    2023.03.28  George      (omit)      用于模拟实现ls -l功能
 * 
 ***********************************************************************/ 

#ifndef __LS_HEAD_H
#define __LS_HEAD_H

/***********************************************************************
 *  (1)Debug switch Section
 ***********************************************************************/


/***********************************************************************
 *  (2)Include File Section
 ***********************************************************************/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
#include <dirent.h>
#include <errno.h>

 /***********************************************************************
 *  (3)Macro Define Section
 ***********************************************************************/


 /***********************************************************************
 *  (4)Struct(Data Types) Define Section
 ***********************************************************************/


 /***********************************************************************
 *  (5)Prototype Declare Section
 ***********************************************************************/
// stat
extern int GetStat(const char *pathname, struct stat *buf);

// type
extern int GetType(mode_t mode, char *ch);
// mode
extern int GetMode(mode_t mode, char modeRet[10]);
// uid
extern int GetUsrName(uid_t uid, char usrNameRet[20]);
// gid
extern int GetGrpName(gid_t gid, char grpNameRet[20]);
// mon
extern int GetMon(int mon, char monRet[4]);
// day time
extern int GetTime(time_t *time, int timeRet[4]);
// file name
extern int GetFileName(const char pathname[20], char fileNameRet[20]);
// single output
extern int OutPutFileInfo(char pathname[20]);
// absolute path
extern int GetAbsolutePath(char absPath[128], char dirPath[40], char pathname[20]);
// (main)multiple output
extern int MainFunc(void);
#endif

LS_Func.c:

/***********************************************************************
 * File name    : LS_Func.c
 * Module Name  : LS
 * Author       : George
 * Create Date  : 2023.03.27
 * Abstract Description: 用于模拟实现ls -l功能
 * 
 * ------------------------- Revision History -------------------------
 *  No  Version Date        Revise By   Item        Deacription
 *  1   V1.0    2023.03.27  George      (omit)      用于模拟实现ls -l功能
 *  2   v1.1    2023.03.28  George      (omit)      用于模拟实现ls -l功能
 * 
 ***********************************************************************/ 

/***********************************************************************
 *  (1)Debug switch Section
 ***********************************************************************/

/***********************************************************************
 *  (2)Include File Section
 ***********************************************************************/
#include "LS_Head.h"

 /***********************************************************************
 *  (3)Macro Define Section
 ***********************************************************************/
#define __NO_ERR 0 // 正常
#define __INPUT_ERR -1 // 入口参数输入错误
#define __FUNC_INVOKE_ERR -2 // 调用函数返回错误

// 返回整型的错误退出检测封装
#define IF_ERR(MSG) if(0 > ret)\
        { \
        printf(MSG); \
        printf(" : exit with %d\n", ret); \
        return __FUNC_INVOKE_ERR; \
        }
// 返回指针的错误退出检测封装
#define IF_ERR_P(MSG, PTR) if(NULL == PTR)\
        { \
        printf(MSG); \
        printf(" : exit with NULL\n"); \
        return __FUNC_INVOKE_ERR; \
        }

 /***********************************************************************
 *  (4)Struct(Data Types) Define Section
 ***********************************************************************/


 /***********************************************************************
 *  (5)Prototype Declare Section
 ***********************************************************************/


 /***********************************************************************
 *  (6)Global Variable Declare Section
 ***********************************************************************/
int ret = 0; // return for print error

 /***********************************************************************
 *  (7)File Static Variable Define Section
 ***********************************************************************/


 /***********************************************************************
 *  (8)Function Define Section
 ***********************************************************************/

 /***********************************************************************
  * Function    : GetStat
  * Description : 用于获取文件状态结构体
  * Input       : 文件路径,用于存储文件属性结构体的结构体
  * Output      : 无
  * Input_Output: 文件属性结构体
  * Return      : 整型错误码
  * Author      : George
  **********************************************************************/
int GetStat(const char *pathname, struct stat *buf)
{
    if(NULL == pathname | NULL == buf)
    {
        return __INPUT_ERR;
    }
    else
    {
        ret = stat(pathname, buf);
        IF_ERR("stat")
        else
        {
            return __NO_ERR;
        }
    }
}

 /***********************************************************************
  * Function    : GetType
  * Description : 用于获取文件种类{bsp-lcd}
  * Input       : st_mode文件类型及权限,用于存储文件类型的字符
  * Output      : 无
  * Input_Output: 存储文件类型的字符
  * Return      : 整型错误码
  * Author      : George
  **********************************************************************/
int GetType(mode_t mode, char *ch)
{
    if(NULL == ch)
    {
        return __INPUT_ERR; 
    }
    else
    {
        switch (mode & S_IFMT)// bsp-lcd
        {
        case __S_IFBLK: *ch = 'b'; break;
        case __S_IFSOCK: *ch = 's'; break;
        case __S_IFIFO: *ch = 'p'; break;
        case __S_IFREG: *ch = '-'; break;
        case __S_IFLNK: *ch = 'l'; break;
        case __S_IFCHR: *ch = 'c'; break;
        case __S_IFDIR: *ch = 'd'; break;
        default: return __INPUT_ERR; break;
        }
        return __NO_ERR;
    }
}

 /***********************************************************************
  * Function    : GetMode
  * Description : 用于获取文件权限{rwx-}
  * Input       : st_mode文件类型及权限,用于存储文件权限的字符数组
  * Output      : 无
  * Input_Output: 存储文件权限的字符数组
  * Return      : 整型错误码
  * Author      : George
  **********************************************************************/
int GetMode(mode_t mode, char modeRet[10])
{
    if(NULL == modeRet)
    {
        return __INPUT_ERR; 
    }
    else
    {
        char Temp[4] = "rwx";// 0-r 1-w 2-x
        for(int i = 1; i < 10; i++)// 123 456 789
        {
            if(1 == (((mode) & (1 << 9-i)) >> 9-i))
            {
                modeRet[i-1] = Temp[(i-1)%3];
            }
            else
            {
                modeRet[i-1] = '-';
            }
        }
        return __NO_ERR;
    }
}

 /***********************************************************************
  * Function    : GetUsrName
  * Description : 用于通过uid获取所属用户名
  * Input       : uid,用于存储所属用户名的字符数组
  * Output      : 无
  * Input_Output: 存储所属用户名的字符数组
  * Return      : 整型错误码
  * Author      : George
  **********************************************************************/
int GetUsrName(uid_t uid, char usrNameRet[20])
{
    if(NULL == usrNameRet)
    {
        return __INPUT_ERR;
    }
    else
    {
        struct passwd *pwd = getpwuid(uid);
        IF_ERR_P("getwuid", pwd)
        else
        {
            strcpy(usrNameRet, pwd->pw_name);
            return __NO_ERR;
        }
    }
}

 /***********************************************************************
  * Function    : GetGrpName
  * Description : 用于通过gid获取所属组用户名
  * Input       : gid,用于存储所属组用户名的字符数组
  * Output      : 无
  * Input_Output: 存储所属组用户名的字符数组
  * Return      : 整型错误码
  * Author      : George
  **********************************************************************/
int GetGrpName(gid_t gid, char grpNameRet[20])
{
    if(NULL == grpNameRet)
    {
        return __INPUT_ERR;
    }
    else
    {
        struct group *grp = getgrgid(gid);
        IF_ERR_P("getgrgid", grp)
        else
        {
            strcpy(grpNameRet, grp->gr_name);
            return __NO_ERR;
        }
    }
}

 /***********************************************************************
  * Function    : GetMon
  * Description : 用于获取最后访问时间的月份
  * Input       : 由localtime获得的月份(加一版本),用于存储最后访问时间月份的字符数组
  * Output      : 无
  * Input_Output: 最后访问时间月份的字符数组
  * Return      : 整型错误码
  * Author      : George
  **********************************************************************/
int GetMon(int mon, char monRet[4])
{
    // input legal exam (omit)
    if(NULL == monRet)
    {
        return __INPUT_ERR;
    }
    else
    {
        bzero(monRet, 4);
        switch (mon)
        {
            case 1: strcpy(monRet, "Mon"); break;
            case 2: strcpy(monRet, "Feb"); break;
            case 3: strcpy(monRet, "Mar"); break;
            case 4: strcpy(monRet, "Apr"); break;
            case 5: strcpy(monRet, "May"); break;
            case 6: strcpy(monRet, "Jun"); break;
            case 7: strcpy(monRet, "Jul"); break;
            case 8: strcpy(monRet, "Aug"); break;
            case 9: strcpy(monRet, "Sep"); break;
            case 10: strcpy(monRet, "Oct"); break;
            case 11: strcpy(monRet, "Nov"); break;
            case 12: strcpy(monRet, "Dec"); break;
            default: return __INPUT_ERR; break;
        }
        return __NO_ERR;
    }
}

 /***********************************************************************
  * Function    : GetTime
  * Description : 用于获取月份、小时、分钟
  * Input       : 文件最近访问时间返回的秒数,用于存储时间的数组
  * Output      : 无
  * Input_Output: 存储时间的数组
  * Return      : 整型错误码
  * Author      : George
  **********************************************************************/
int GetTime(time_t *time, int timeRet[4])
{
    if(NULL == time | NULL == timeRet)
    {
        return __INPUT_ERR;
    }
    else
    {
        struct tm *tm = localtime(time);
        IF_ERR_P("localtime", tm);
        timeRet[0] = tm->tm_mon+1;
        timeRet[1] = tm->tm_mday;
        timeRet[2] = tm->tm_hour;
        timeRet[3] = tm->tm_sec;
        return __NO_ERR;
    }
}

 /***********************************************************************
  * Function    : GetFileName
  * Description : 用于获取文件名
  * Input       : 文件路径,用于存储文件名的字符数组
  * Output      : 无
  * Input_Output: 存储文件名的字符数组
  * Return      : 整型错误码
  * Author      : George
  **********************************************************************/
int GetFileName(const char pathname[32], char fileNameRet[20])
{
    if(NULL == pathname | NULL == fileNameRet)
    {
        return __INPUT_ERR;
    }
    else
    {
        int flag = 0;
        for(int i = strlen(pathname)-1; i >= 0; i--)
        {
            if('/' == pathname[i])
            {
                flag = i+1;
                break;
            }
        }
        for(int i = flag, j = 0; i < strlen(pathname); i++, j++)
        {
            fileNameRet[j] = pathname[i];
        }
        return __NO_ERR;
    }
}

 /***********************************************************************
  * Function    : OutPutFileInfo
  * Description : 调用其它函数实现单个文件ls -l功能
  * Input       : 文件的绝对路径
  * Output      : 无
  * Input_Output: 无
  * Return      : 整型错误码
  * Author      : George
  **********************************************************************/
int OutPutFileInfo(char absPath[160])
{
    if(NULL == absPath)
    {
        return __INPUT_ERR;
    }
    else
    {
        // get file-stat
        struct stat buf;
        ret = GetStat(absPath, &buf);
        IF_ERR("GetStat")
        else
        {
            // get type
            char ch = '\0';
            ret = GetType(buf.st_mode, &ch);
            IF_ERR("GetType")
            // get mode
            char modeRet[10] = "";
            ret = GetMode(buf.st_mode, modeRet);
            IF_ERR("GetMode")
            // get link
            int link = buf.st_nlink;
            // get id
            char usrNameRet[20] = "";
            ret = GetUsrName(buf.st_uid, usrNameRet);
            IF_ERR("GetUsrName")
            char grpNameRet[20] = "";
            ret = GetGrpName(buf.st_gid, grpNameRet);
            IF_ERR("GetGrpName")
            // get size
            int size = buf.st_size;
            // get time
            int timeRet[4] = {0};
            time_t time = buf.st_mtime;// st_atime st_ctime st_mtime
            ret = GetTime(&time, timeRet);
            IF_ERR("GetTime")
            char monRet[4] = "";
            ret = GetMon(timeRet[0], monRet);
            IF_ERR("GetMon")
            // get file name
            char fileNameRet[20] = "";
            ret = GetFileName(absPath, fileNameRet);
            IF_ERR("GetFileName")

            // output ls -l
            printf("%c%s %d %s %s %5d %s %d %02d:%02d %s\n", \
            ch, modeRet, \
            link, \
            usrNameRet, grpNameRet, \
            size, \
            monRet, timeRet[1], timeRet[2], timeRet[3], \
            fileNameRet);
            return __NO_ERR;
        }
    }
}

 /***********************************************************************
  * Function    : GetAbsolutePath
  * Description : 获取文件的绝对路径
  * Input       : 用于存储文件绝对路径的字符数组,目录绝对路径,文件名
  * Output      : 无
  * Input_Output: 存储文件绝对路径的字符数组
  * Return      : 整型错误码
  * Author      : George
  **********************************************************************/
int GetAbsolutePath(char absPath[160], char dirPath[128], char pathname[32])
{
    if(NULL == absPath | NULL == dirPath | NULL == pathname)
    {
        return __INPUT_ERR;
    }
    else
    {
        bzero(absPath, 160);
        strcpy(absPath, dirPath);
        strcat(absPath, "/");
        strcat(absPath, pathname);
        return __NO_ERR;
    }
}

 /***********************************************************************
  * Function    : OutPutFileInfo
  * Description : 调用其它函数实现完整ls -l功能
  * Input       : 无
  * Output      : 无
  * Input_Output: 无
  * Return      : 整型错误码
  * Author      : George
  **********************************************************************/
int MainFunc(void)
{
    char dirPath[128] = "";
    printf("Please input your path(Absolute path) >>> ");
    scanf("%s", dirPath);
    DIR *DirPtr = opendir(dirPath);
    IF_ERR_P("opendir", DirPtr)
    else
    {
        char absPath[160] = "";
        struct dirent *readPtr = NULL;
        while(1)
        {
            readPtr = readdir(DirPtr);
            if(NULL == readPtr)
            {
                if(errno == 0)
                {
                    break;
                }
                else
                {
                    perror("readdir");
                }
            }
            if(0 == strcmp(".", readPtr->d_name) | 0 == strcmp("..", readPtr->d_name))
            {
                continue;
            }
            ret = GetAbsolutePath(absPath, dirPath, readPtr->d_name);
            IF_ERR("GetAbsolutePath")
            ret = OutPutFileInfo(absPath);
            IF_ERR("OutPutFileInfo")
        }
        ret = closedir(DirPtr);
        IF_ERR("closedir")
        return __NO_ERR;
    }
}

 main.c:

#include "LS_Head.h"

int main(int argc, char const *argv[])
{
    MainFunc();
    return 0;
}

运行截图:

 已知缺陷:输入绝对路径,文件时间,文件名排序,输出对齐。

作业:拷贝图片

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/stat.h>

int main(int argc, char const *argv[])
{
    // open file
    int fd_src = open("./src.jpg", O_RDONLY);
    int fd_des = open("./des.jpg", O_WRONLY|O_CREAT|O_TRUNC, 0664);
    // Legality testing omit

    // get size
    int size = lseek(fd_src, 0, SEEK_END);
    printf("size of pic : %d\n", size);

    // copy
    char cBuf = '\0';
    ssize_t ret = 0;
    pid_t iPid = fork();
    if(iPid < 0)
    {
        perror("fork");
        return -1;
    }
    else if(iPid > 0)// parent 
    {
        lseek(fd_src, 0, SEEK_SET);
        lseek(fd_des, 0, SEEK_SET);
        for(int i = 0; i < size/2; i++)
        {
            read(fd_src, &cBuf, 1);
            write(fd_des, &cBuf, 1);
        }
        printf("parent copy success.\n");
        wait(NULL);
    }
    else// child
    {
        sleep(1);// the time blocked depends on the size of pic
        lseek(fd_src, size/2, SEEK_SET);
        lseek(fd_des, size/2, SEEK_SET);
        for(int i = size/2; i < size; i++)
        {
            read(fd_src, &cBuf, 1);
            write(fd_des, &cBuf, 1);
        }
        printf("child copy success.\n");
    }

    close(fd_src);
    close(fd_des);
    // Legality testing omit
    return 0;
}

截图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值