作业
题目一
- 从终端获取一个文件的路径以及名字。
- 若该文件是目录文件,则将该文件下的所有文件的属性显示到终端,类似ls -l该文件夹
- 若该文件不是目录文件,则显示该文件的属性到终端上,类似ls -l这单个文件
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <head.h>
void get_filePermission(mode_t m)
{
int i;
char p[3]="rwx";
for(i=0;i<9;i++)
{
if((m & 0400>>i)!=0)
putchar(p[i%3]);
else
putchar('-');
}
putchar('\t');
}
void get_fileType(mode_t m)
{
switch(m & S_IFMT)
{
case S_IFSOCK:putchar('s');break;
case S_IFIFO:putchar('p');break;
case S_IFLNK:putchar('l');break;
case S_IFREG:putchar('-');break;
case S_IFBLK:putchar('b');break;
case S_IFCHR:putchar('c');break;
case S_IFDIR:putchar('d');break;
}
return;
}
void get_fileuid(uid_t uid)
{
struct passwd* p=getpwuid(uid);
if(NULL==p)
{
ERR_MSG("getpwuid");
return;
}
printf("\t%s",p->pw_name);
}
void get_filegid(gid_t gid)
{
struct group* g=getgrgid(gid);
if(NULL==g)
{
ERR_MSG("getgrgid");
return;
}
printf("\t%s",g->gr_name);
}
void get_dir(DIR *dp,char name[])
{
int i=0;
struct stat sub;
while(1)
{
struct dirent* rp = readdir(dp);
char r_name[100]="";
strcpy(r_name,name);
strcat(r_name,"/");
if(NULL == rp)
{
if(0 == errno)
{
printf("read over\n");
break;
}
else
{
ERR_MSG("readdir");
return;
}
}
printf("[%d]%s\n",++i,rp->d_name);
strcat(r_name,rp->d_name);
if(stat(r_name,&sub)<0)
{
ERR_MSG("stat");
return;
}
get_fileType(sub.st_mode);
get_filePermission(sub.st_mode);
printf("\t%ld",sub.st_nlink);
get_fileuid(sub.st_uid);
get_filegid(sub.st_gid);
printf("\t%ld",sub.st_size);
struct tm* tt = localtime(&sub.st_ctime);
printf("\t%4d-%02d-%02d %02d:%02d:%02d",\
tt->tm_year+1900,tt->tm_mon+1,tt->tm_mday,\
tt->tm_hour,tt->tm_min,tt->tm_sec);
putchar(10);
}
return;
}
int main(int argc, const char *argv[])
{
struct stat buf;
char name[100]="";
scanf("%s",name);
if(stat(name,&buf)<0)
{
ERR_MSG("stat");
return -1;
}
if((buf.st_mode & S_IFMT)==S_IFDIR)
{
DIR* dp = opendir(name);
if(NULL==dp)
{
ERR_MSG("opendir");
return -1;
}
printf("opendir success\n");
get_dir(dp,name);
if(closedir(dp)<0)
{
ERR_MSG("closedir");
return -1;
}
printf("closedir success\n");
}
else
{
get_fileType(buf.st_mode);
get_filePermission(buf.st_mode);
printf("\t%ld",buf.st_nlink);
get_fileuid(buf.st_uid);
get_filegid(buf.st_gid);
printf("\t%ld",buf.st_size);
struct tm* t = localtime(&buf.st_ctime);
printf("\t%4d-%02d-%02d %02d:%02d:%02d",\
t->tm_year+1900,t->tm_mon+1,t->tm_mday,\
t->tm_hour,t->tm_min,t->tm_sec);
putchar(10);
}
return 0;
}
题目二
文件IO函数实现,拷贝文件。子进程先拷贝后半部分,父进程再拷贝前半部分。允许使用sleep函数。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <head.h>
int main(int argc, const char *argv[])
{
//打开要复制的文件和被复制的文件
int pt=open("./1.txt",O_RDONLY);
if(0 == pt)
{
ERR_MSG("open");
return -1;
}
int tp=open("./2.txt",O_WRONLY|O_CREAT|O_TRUNC,0777);
if(0 == tp)
{
ERR_MSG("open");
return -1;
}
//在创建子进程前将需要的变量定义完
struct stat buf;
if(stat("./1.txt",&buf)<0)
{
ERR_MSG("stat");
return -1;
}
int size = buf.st_size/2;
char sub[size+1];
int res;
//创建子进程
pid_t cpid = fork();
//子进程先读取后半部分,打印到复制目标文件的后半部分
if(cpid == 0)
{
lseek(pt,size+1,SEEK_SET);
res = read(pt,sub,size+1);
lseek(tp,size+1,SEEK_SET);
write(tp,sub,res);
}
//父进程后读取前半部分,打印到复制目标文件的前半部分
else if(cpid>0)
{
sleep(1);
lseek(pt,0,SEEK_SET);
res = read(pt,sub,size+1);
lseek(tp,0,SEEK_SET);
write(tp,sub,res);
}
else
return 0;
close(pt);
close(tp);
return 0;
}
思维导图