在Linux中用C语言写一个自己的ls -l命令

在Linux中用C语言写一个自己的ls-l命令

在Linux中我们会经常使用ls -l 这条命令来查看文件信息,但是这个命令到底是怎么实现的呢?下面我就带大家用C语言来实现ls -l 这条命令,直接上代码吧:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>

// ls-l 功能函数,参数为一个文件名
void ls_l(char name[])
{
	// 定义一个stat类型的结构体
    struct stat my_stat;
    int ret = stat(name,&my_stat);
    if (ret  == -1){
        perror("stat");
        return ;
    }
    // 判断并打印文件类型 ,这里用到了很多函数调用,后面会为大家贴上这些函数的用法
    if (S_ISDIR(my_stat.st_mode))
        printf("d");
    else if (S_ISBLK(my_stat.st_mode))
        printf("b");
    else if (S_ISCHR(my_stat.st_mode))
        printf("c");
    else if (S_ISLNK(my_stat.st_mode))
        printf("l");
    else if (S_ISSOCK(my_stat.st_mode))
        printf("s");
    else if (S_ISREG(my_stat.st_mode))
        printf("-");
    else if (S_ISFIFO(my_stat.st_mode))
        printf("p");
    // 判断文件的权限信息
    printf("%c",(my_stat.st_mode) & (1<<8)?'r':'-');
    printf("%c",(my_stat.st_mode) & (1<<7)?'w':'-');
    printf("%c",(my_stat.st_mode) & (1<<6)?'x':'-');
    printf("%c",(my_stat.st_mode) & (1<<5)?'r':'-');
    printf("%c",(my_stat.st_mode) & (1<<4)?'w':'-');
    printf("%c",(my_stat.st_mode) & (1<<3)?'x':'-');
    printf("%c",(my_stat.st_mode) & (1<<2)?'r':'-');
    printf("%c",(my_stat.st_mode) & (1<<1)?'w':'-');
    printf("%c",(my_stat.st_mode) & (1<<0)?'x':'-');
    // 打印链接数
    printf(" %ld",my_stat.st_nlink);
    // 打印所属用户
    struct passwd *uid = getpwuid(my_stat.st_uid);
    printf(" %s",uid->pw_name);
    // 打印所属组
    struct group *gid = getgrgid(my_stat.st_gid);
    printf(" %s",gid->gr_name);
    // 打印文件大小
    printf(" %-8ld",my_stat.st_size);
    // 打印时间
    struct tm *t = localtime((time_t *)&my_stat.st_mtim);
    printf(" %d月   %d  %d:%d ",t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min);
    // 打印文件名
    printf("%-2s\n",name);

}
// 这里是使用命令行传参
int main(int argc, const char *argv[])
{
 //判断是否携带参数,如果没有携带参数,就默认为当前路径
 if (argc == 1){
        printf("请输入文件路径,或者文件名\n");
        return -1;
    }
    struct stat my_stat;
    int ret = stat(argv[1],&my_stat);
    // 判断输入的是否为目录
    if (S_ISDIR(my_stat.st_mode)){
    	// 如果为目录,我们将目录打开,把里面的内容(文件名)传给功能函数
        DIR * dir = opendir(argv[1]);
        if (NULL == dir){
            perror("opendir");
            return -1;
        }
        struct dirent *p = readdir(dir);
        if (NULL == p)
        {
            perror("readdir");
            return -1;
        }
        while (p!=NULL){
            ls_l(p->d_name);
            p = readdir(dir);
        }
        closedir(dir);
    }else  // 不是目录
        ls_l(argv[1]);

    return 0;
}

上述代码中用到了库函数和结构体,下面是一部分函数和结构体的具体内容:

  1. 【stat结构体的内容】
struct stat {
	dev_t     st_dev;     /* ID of device containing file */
	ino_t     st_ino;     /* inode number */
	mode_t    st_mode; 文件的权限、文件的类型   /* protection */
	nlink_t   st_nlink;   /* number of hard links */
	uid_t     st_uid;  所属用户ID   /* user ID of owner */ 
	gid_t     st_gid;  所属组ID   /* group ID of owner */
	dev_t     st_rdev;    /* device ID (if special file) */
	off_t     st_size; 文件的大小   /* total size, in bytes */
	blksize_t st_blksize; /* blocksize for filesystem I/O */
	blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
	time_t    st_atime; 最后一次访问时间  /* time of last access */
	time_t    st_mtime; 最后一次修改时间  /* time of last modification */
	time_t    st_ctime; 最后一次文件文件属性修改时间  /* time of last status change */
};

2.【将uid 转换为 用户名】


#include <sys/types.h>
#include <pwd.h>
struct passwd *getpwuid(uid_t uid);
struct passwd {
   char   *pw_name;       /* username */
   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 */
};
  1. 【将gid 转换为 组名】

#include <sys/types.h>
#include <grp.h>
struct group *getgrgid(gid_t gid);
struct group {
	char   *gr_name;       /* group name */
	char   *gr_passwd;     /* group password */
	gid_t   gr_gid;        /* group ID */
	char  **gr_mem;        /* group members */
};
  1. 【文件类型】
{
	常规文件:S_ISREG 	'-'
	目录:S_ISDIR 		'd'
	字符设备:S_ISCHR 	'c'
	块设备:S_ISBLK 	'b'
	管道:S_ISFIFO 		'p'
	套接字:S_ISSOCK 	's'
	符号链接:S_ISLNK 	'l'
}
  1. 【目录操作函数】


include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
/*****************************************
*功能: 打开一个目录文件
*参数: @name   	目录文件路径
*返回值:  成功  返回 目录流指针
*		  失败  返回 NULL   更新 errno
******************************************/


#include <dirent.h>
struct dirent *readdir(DIR *dirp);
/*****************************************
*功能: 读目录流指针
*参数: @dirp   	目录流指针
*返回值:  成功  返回 struct dirent 指针
*		  失败  返回 NULL 表示目录中的文件读完
******************************************/
struct dirent {
   ino_t          d_ino;       /* inode number */
   off_t          d_off;       /* not an offset; see NOTES */
   unsigned short d_reclen;    /* length of this record */
   unsigned char  d_type;      /* type of file; not supported
								  by all filesystem types */
   char           d_name[256]; /* filename */
};


#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
/*****************************************
*功能: 关闭目录流
*参数: @dirp   	目录流指针
*返回值:  成功  返回 0
*		  失败  返回 -1   更新 errno
******************************************/
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 以下是 Linux 中使用 C 语言编的简单 socket 编程示例: 服务端代码: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> void error(const char *msg) { perror(msg); exit(1); } int main(int argc, char *argv[]) { int sockfd, newsockfd, portno; socklen_t clilen; char buffer[256]; struct sockaddr_in serv_addr, cli_addr; int n; if (argc < 2) { fprintf(stderr,"ERROR, no port provided\n"); exit(1); } sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); bzero((char *) &serv_addr, sizeof(serv_addr)); portno = atoi(argv[1]); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding"); listen(sockfd,5); clilen = sizeof(cli_addr); newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd < 0) error("ERROR on accept"); bzero(buffer,256); n = read(newsockfd,buffer,255); if (n < 0) error("ERROR reading from socket"); printf("Here is the message: %s\n",buffer); n = write(newsockfd,"I got your message",18); if (n < 0) error("ERROR writing to socket"); close(newsockfd); close(sockfd); return 0; } ``` 客户端代码: ``` #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> void error(const char *msg) { perror(msg); exit(0); } int main(int argc, char *argv[]) { int sockfd, portno, n; struct sockaddr_in serv_addr; struct hostent * ### 回答2: 以下是一个C语言的简单的Linux socket编程示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> // close函数 #include <arpa/inet.h> // htons, inet_pton函数 #include <sys/socket.h> // socket, bind, listen, accept, recv, send函数 #define PORT 8080 #define BUFFER_SIZE 1024 int main() { int server_fd, new_socket, valread; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); char buffer[BUFFER_SIZE] = {0}; char *hello = "Hello from server"; // 创建套接字 if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("Socket creation failed"); exit(EXIT_FAILURE); } // 设置套接字选项,允许地址重复使用 if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { perror("Setsockopt failed"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); // 绑定套接字到指定端口 if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("Bind failed"); exit(EXIT_FAILURE); } // 监听连接请求 if (listen(server_fd, 3) < 0) { perror("Listen failed"); exit(EXIT_FAILURE); } // 接受连接请求 if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) { perror("Accept failed"); exit(EXIT_FAILURE); } // 接收客户端数据 valread = recv(new_socket, buffer, BUFFER_SIZE, 0); printf("Received: %s\n", buffer); // 向客户端发送消息 send(new_socket, hello, strlen(hello), 0); printf("Hello message sent\n"); // 关闭套接字 close(new_socket); close(server_fd); return 0; } ``` 该示例中创建了一个TCP服务器,会监听在8080端口上。当有客户端连接后,会接收客户端发送的消息,并向客户端发送"Hello from server"消息。最后关闭套接字。 ### 回答3: 在Linux系统中,我们可以使用C语言一个基本的Socket编程示例。以下是一个简单的Server-Client示例,包括了服务器端和客户端的代码。 服务器端代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define PORT 8080 #define BUFFER_SIZE 1024 int main() { int server_fd, new_socket; struct sockaddr_in address; int addrlen = sizeof(address); char buffer[BUFFER_SIZE] = {0}; char *server_response = "Server is connected!\n"; // 创建Socket if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("Socket creation failed"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); // 绑定Socket到指定端口 if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0) { perror("Binding failed"); exit(EXIT_FAILURE); } // 监听连接 if (listen(server_fd, 3) < 0) { perror("Listening failed"); exit(EXIT_FAILURE); } // 建立连接 if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) { perror("Acceptance failed"); exit(EXIT_FAILURE); } // 发送欢迎消息 send(new_socket, server_response, strlen(server_response), 0); printf("Welcome message sent\n"); // 接收客户端消息并发送回复 while (1) { memset(buffer, 0, sizeof(buffer)); read(new_socket, buffer, BUFFER_SIZE); printf("Client message: %s\n", buffer); send(new_socket, buffer, BUFFER_SIZE, 0); } return 0; } ``` 客户端代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT 8080 #define BUFFER_SIZE 1024 int main() { int sock = 0, valread; struct sockaddr_in serv_addr; char *client_message = "Hello from client"; char buffer[BUFFER_SIZE] = {0}; // 创建Socket if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("Socket creation failed"); exit(EXIT_FAILURE); } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); // 将IPv4地址从点分十进制转换为网络字节序 if(inet_pton(AF_INET, "127.0.0.1", &(serv_addr.sin_addr))<=0) { perror("Invalid address or address not supported"); exit(EXIT_FAILURE); } // 连接到服务器 if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { perror("Connection failed"); exit(EXIT_FAILURE); } // 发送消息 send(sock, client_message, strlen(client_message), 0); printf("Message sent to server\n"); // 接收回复消息 valread = read(sock, buffer, BUFFER_SIZE); printf("Server message: %s\n", buffer); return 0; } ``` 以上代码示例展示了Linux中使用C语言Socket通信的基本原理。服务器端使用`socket()`函数创建socket,`bind()`函数将socket绑定到指定的端口,`listen()`函数监听连接请求,并使用`accept()`函数接收来自客户端的连接。客户端使用`socket()`函数创建socket,`connect()`函数连接到服务器,并使用`send()`函数发送消息,`read()`函数接收并打印服务器端回复的消息。 以上示例是一个简单的基于TCP协议的Socket通信示例,可以通过编译并在Linux系统上运行进行测试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值