2017.1.3 网络编程--文件与进程

  • getpwuid() 给出用户的具体数据

函数原型:
struct passwd *getpwnam(const char *name);
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 */
 };
  • memset();清零

memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。
常见错误
第一:搞反了 ch 和 n 的位置. 一定要记住如果要把一个char a[20]清零,一定是 memset(a,0,20); 而不是 memset(a,20,0);


ctime();
getgrgid();获得给出组的信息
getpid();获得当前进程的pid号
getppid();获得当前进程的父进程pid号
fork(); 复制生成子进程
exec();替换子进程
getcwd();查看当前的工作目录


  • wait();

会暂时停止目前进程的执行, 直到有信号来到或子进程结束. 如果在调用wait()时子进程已经结束, 则wait()会立即返回子进程结束状态值. 子进程的结束状态值会由参数status 返回, 而子进程的进程识别码也会一快返回. 如果不在意结束状态值, 则参数 status 可以设成NULL. 子进程的结束状态值请参考waitpid().

strtok();字符串按格式分割
open(); 打开一个文件
read(); 读取打开的文件
write(); 写入读取到的缓存字符
access();判断文件的权限 R_OK W_OK X_OK F_OK
opendir();打开一个目录并返回一个DIR *类型的指针指向目录项
readdir();读取一个目录流并将信息保存在结构体中struct dirent 中
closedir();与opendir配对,用来关闭打开的目录
atexit() 设置程序正常结束前调用的函数
execl() 执行文件函数
execlp() 从PATH 环境变量中查找文件并执行
execv() 执行文件函数
execve() 执行文件函数
execvp() 执行文件函数


  • 几个用的命令

ps aux 查看所有进程
top 打开一个类似于任务管理器的界面,可看到zombie进程
kill 传入信号,-l是查看所有的参数

练习

1.实现ls

#include 
#include 
#include 
#include 
#include 

int main(int argc,char *argv[])
{

     DIR *dirp = NULL;
     struct dirent *dp = NULL;
     struct stat sp;
     char str[11] = {"\0"};
     if((dirp = opendir("/home/w/桌面/f")) == NULL)d
     {
         perror("opendir preeor");
         return 1;
     }
    while((dp = readdir(dirp)) != NULL)
    {
        if(dp->d_name[0] != '.')
        {
            stat(dp->d_name , &sp);
            str[0] = '-';
            if(sp.st_mode & S_IFBLK) str[0] = 'b';
            if(sp.st_mode & S_IFDIR) str[0] = 'd';
            if(sp.st_mode & S_IFCHR) str[0] = 'c';
            if(sp.st_mode & S_IFIFO) str[0] = 'p';
            
            if(sp.st_mode & S_IRUSR) str[1] = 'r';
            else str[1] = '-';
            if(sp.st_mode & S_IWUSR) str[2] = 'w';
            else str[2] = '-';
            if(sp.st_mode & S_IXUSR) str[3] = 'x';
            else str[3] = '-';
            
            if(sp.st_mode & S_IRGRP) str[4] = 'r';
            else str[4] = '-';
            if(sp.st_mode & S_IWGRP) str[5] = 'w';
            else str[5] = '-';
            if(sp.st_mode & S_IXGRP) str[6] = 'x';
            else str[6] = '-';
            
            if(sp.st_mode & S_IROTH) str[7] = 'r';
            else str[7] = '-';
            if(sp.st_mode & S_IWOTH) str[8] = 'w';
            else str[8] = '-';
            if(sp.st_mode & S_IXOTH) str[9] = 'x';
            else str[9] = '-';
            printf("%s %ld %ld \t%s \n",str,sp.st_nlink,sp.st_size,dp->d_name);
        }
    }
     closedir(dirp);
     return 0;
}

2.实现cp命令并改进

#include 
#include 
#include 
#include 
#include 

#define BUFFER_S 100

int main(int argc,char *argv[])
{
    int src_fd = 0;
    int dst_fd = 0;
    int n = 0;
    char ch = '0';
    char buf[BUFFER_S] = {'\0'};
     if(argc != 3)
     {
         printf("usage : %s \n",argv[0]);
         return 1;
     }
     if((src_fd = open(argv[1],O_RDONLY)) == -1)
     {
        perror("open dst_fd perror");
        return 1;
     }
     while(1)   
     {      
     if(access(argv[2],F_OK) == 0)
     {
         printf("目的文件名已经存在!是否覆盖掉?(y ro n)");
         scanf("%c",&ch);
         getchar();
         if(ch == 'y')
         {
            if((dst_fd = open(argv[2],O_WRONLY | O_TRUNC,S_IRWXU)) == -1)
            {
                perror("open dst_fd perror");
                    return 1;
            }
            break;
         }
         else if(ch == 'n')
         {
            printf("是否重新输入目的路径?(y ro n)");
            scanf("%c",&ch);
            getchar();
            if(ch == 'y')
            scanf("%s",argv[2]);//最好不占用不改变argv的值
            else 
               return 1;
         }
         else 
            break;
     }
     else 
     {
        if((dst_fd = open(argv[2],O_WRONLY | O_CREAT,S_IRWXU)) == -1)
        {
                perror("open dst_fd perror");
                return 1;
        }
        break;
     }
     }
     while((n = read(src_fd,buf,BUFFER_S)) > 0)
     {
         write(dst_fd,buf,n);
     }
     close(src_fd);
     close(dst_fd);
     return 0;
}

3.实现ls命令

#include 
#include 
#include 
#include 
#include 

#define MAX_CMD_LEN 128

void main(int argc,char *argv[])
{
    pid_t pid;
    char in[MAX_CMD_LEN] = {'\0'};
    char cmd[MAX_CMD_LEN] = {'\0'};
    char cmdl[MAX_CMD_LEN] = {'\0'};
    char pwd[MAX_CMD_LEN] = {'\0'};
    char* delim = " ";
    char* p = NULL;
    int status = 0;
    
    struct passwd *pw;
    
    while(1)
    {
        pw = getpwuid(getuid());
        getcwd(pwd,MAX_CMD_LEN);
        printf(" %s@|%s>",pw->pw_name,pwd);
        fgets(in,MAX_CMD_LEN,stdin);
        in[strlen(in) - 1] = '\0';
        p = strtok(in,delim);
        if(p == NULL)
            continue;
        strcpy(cmd,p);
        if(strcmp(cmd,".exit") == 0)
            return ;
        p = strtok(NULL,delim);
        if(p != NULL)
        {
            strcpy(cmdl,p);
            if(fork() == 0)
            {
                execlp(cmd,cmd,cmdl,NULL);
                return ;
            }
        }
        else 
        {
            strcpy(cmdl,"NULL");
            if(fork() == 0)
            {
                execlp(cmd,cmd,NULL);
                return ;
            }
        }
        wait(&status);
    }   
}

你可能感兴趣的:(2017.1.3 网络编程--文件与进程)