dirent,进程,僵尸

在文件指定位置插入数据而不覆盖

#include 
#include   //strerror
#include   //errno
#include   //read write
/*open*/
#include 
#include 
#include 

#define PER_IO_BYTES 4096

int main(int argc, char *argv[])
{
    char caFile[64] = {'\0'};
    strncpy(caFile, argv[1], sizeof(caFile));
    
    int ret = -1;
    strcat(caFile, ".old");
    ret = rename(argv[1], caFile);
    if (-1 == ret)
    {
        printf("rename error:%s\n", strerror(errno));
        return -1;
    }

    int fdNew = -1;
    fdNew = open(argv[1], O_WRONLY | O_CREAT
                 , S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    if (-1 == fdNew)
    {
        printf("open error:%s\n", strerror(errno));
        return -1;
    }
    int fdOld = -1;
    fdOld = open(caFile, O_RDONLY);
    if (-1 == fdOld)
    {
        printf("open error:%s\n", strerror(errno));
        return -1;
    }

    off_t offset = 0;
    printf("please input position:");
    scanf("%ld", &offset);
    char caBuf[PER_IO_BYTES] = {'\0'};
    int iLeft = offset;
    //将指定位置之前的数据拷贝到新文件中
    while (iLeft)
    {
        if (iLeft >= PER_IO_BYTES)
        {
            ret = read(fdOld, caBuf, PER_IO_BYTES);
        }
        else
        {
            ret = read(fdOld, caBuf, iLeft);
        }
        if (-1 == ret)
        {
            printf("read error:%s\n", strerror(errno));
            break;
        }
        iLeft -= ret;
        ret = write(fdNew, caBuf, ret);
        if (-1 == ret)
        {
            printf("write error:%s\n", strerror(errno));
            break;
        }
    }

    //在指定的位置写入数据
    char *pData = "$$$qwertyuiopasdfghjklzxcvbnm$$$";
    ret = write(fdNew, pData, strlen(pData));
    if (-1 == ret)
    {
        printf("write error:%s\n", strerror(errno));
        return;
    }

    //将指定位置之后的数据写入新文件中  
    while (1)
    {
        ret = read(fdOld, caBuf, PER_IO_BYTES);
        if (-1 == ret)
        {
            printf("read error:%s\n", strerror(errno));
            break;
        }
        else if (0 == ret)
        {
            break;
        }
        ret = write(fdNew, caBuf, ret);
        if (-1 == ret)
        {
            printf("write error:%s\n", strerror(errno));
            break;
        }
    }

    close(fdNew);
    close(fdOld);

    ret = remove(caFile);
    if (-1 == ret)
    {
        printf("remove error:%s\n", strerror(errno));
        return -1;
    }

    return 0;
}

测试文件是否存在(可读可写可执行)

#include 
#include   //perror

//mode:
//    F_OK:测试文件是否存在
//    R_OK:测试用户是否对文件具有可读权限
//    W_OK:测试用户是否对文件具有可写权限
//    X_OK:测试用户是否对文件具有可执行权限
//测试用户对于指定的文件是否具有mode权限
//如果有,则函数返回0
//否则返回-1
//int access(const char *pathname, int mode);

int main(int argc, char *argv[])
{
    int ret = -1;
    //ret = access(argv[1], F_OK);
    //ret = access(argv[1], R_OK | W_OK);
    ret = access(argv[1], X_OK);
    if (-1 == ret)
    {
        perror("access");
        return -1;
    }
    else if (0 == ret)
    {
        printf("user has those permissions\n");
    }

    return 0;
}

判断文件类型(普通文件,目录文件)

#include 
#include 
/*stat()*/
#include 
#include 
#include 
/*opendir()*/
#include 
#include 

int main(int argc, char *argv[])
{
    DIR *pDir = opendir(argv[1]);
    if (NULL == pDir)
    {
        perror("opendir:");
        return -1;
    }
    printf("opendir ok\n");
    struct dirent *pDirent = NULL;
    struct stat fileStat;
    int ret = -1;
    pDirent = readdir(pDir);
    int iRegNum = 0;
    int iDirNum = 0;
    int iOthNum = 0;
    while (NULL != pDirent)
    {
        printf("%s\n", pDirent->d_name);
        ret = stat(pDirent->d_name, &fileStat);
        if (0 == ret)
        {
            switch (fileStat.st_mode & S_IFMT)
            {
            case S_IFREG:
                iRegNum++;
                break;
            case S_IFDIR:
                iDirNum++;
                break;
            default:
                iOthNum++;
                break;
            }
        }
        else if (-1 == ret)
        {
            perror("stat");
            break;
        }
        pDirent = readdir(pDir);
    }
    printf("普通的文件:%d个.\n", iRegNum);
    printf("目录的文件:%d个.\n", iDirNum);
    printf("其他类型的文件:%d个.\n", iOthNum);

    closedir(pDir);

    return 0;
}

1.进程的命令

查看CPU:top
查看所有的进程:ps -A
查看当前的进程:ps
关闭进程:kill -9 进程id
创建进程:fork

父进程,子进程(fork)

#include    //fork()
#include 
#include 

int main(void)
{
    pid_t pid = -1;
    int iNum = 0;
    char caData[32] = {'\0'};
    //子进程创建后,和父进程属于两个相互独立的进程
    //父进程调用fork,这是一个系统调用,因此进入内核
    //内核根据父进程复制出一个子进程,父子进程的PCB信息相同
    //用户态代码和数据也完全相同。
    //因此,子进程现在的状态看起来和父进程一样,做完了初始化
    //刚调用了fork进入内核,还没有从内核返回。
    //现在有两个一模一样的进程看起来都调用了fork进入内核等待
    //从内核返回(实际上fork只调用了一次)。此外系统中还有其他
    //进程等待从内核返回。是父进程先返回还是子进程先返回,还是
    //父子进程都等待,其他进程先返回,这是不确定的。
    //取决于内核的调度算法
    pid = fork();
    //fork成功:将子进程的id返回给父进程的pid变量
    //          将0返回给子进程的pid变量
    //    失败:返回-1给父进程的pid变量,子进程不会被创建   
    //          并且错误号会被设置
    if (pid > 0)  //父进程
    {
        printf("this is parent process\n");
        strcpy(caData, "this is parent process\n");
        iNum = 3;
    }
    else if (0 == pid)  //子进程
    {
        printf("this is child process\n");
        strcpy(caData, "this is child process\n");
        iNum = 6;
    }
    else if (-1 == pid)  //创建进程失败
    {
        perror("fork");
        return -1;
    }
    int i = 0;
    for (; i < iNum; i++)
    {
        printf("%s", caData);
        sleep(1);   
    }

    printf("Hello World\n");
    return 0;
}

僵尸进程

#include    //fork()
#include 
#include 
//一个进程结束时会关闭所有的文件描述符,
//释放在用户空间分配的内存,
//但它的PCB还保留着,
//如果进程异常终止则保留着导致该进程终止的信号
//如果正常终止则保留退出状态:在终端可以用“$?”来查看
//父进程可以调用wait或waitpid获取这些信息,
//然后彻底清楚掉这个进程

//如果一个进程终止,但是其父进程尚未调用wait或者waitpid
//对他进行清理,这时的进程状态称之为僵尸进程。

//任何进程在刚终止的时候都是僵尸进程,
//正常情况下僵尸进程会立刻被父进程清理。

//僵尸进程的危害:
//    系统允许存在的进程数是有上限的。
//    若存在大量的僵尸进程,则可能创建新的进程由于没有
//    进程号分配而失败


//形成僵尸进程实例:
int main(void)
{
    pid_t pid = -1;
    pid = fork();
    if (pid > 0)  //父进程
    {
        printf("this is parent process\n");
        while (1)
        {}
    }
    else if (0 == pid)  //子进程
    {
        printf("this is child process\n");
        return 0;
    }
    else if (-1 == pid)  //创建进程失败
    {
        perror("fork");
        return -1;
    }

    printf("Hello World\n");
    return 0;
}

处理僵尸进程

#include    //fork()
#include 
#include 
/*waitpid()*/
#include 
#include 

//僵尸进程的处理方式
//1,将子进程的善后处理交给祖宗进程(父进程不方便对子进程清理)
//   A-->B-->C: 将B进程挂掉,那么C进程的清理工作由祖宗进程来做
//2,父进程自己调用相应函数来对子进程做善后处理
//   调用wait()或者waitpid()
int main(void)
{
    pid_t pid = -1;
    pid = fork();
    if (pid > 0)  //父进程
    {
        printf("this is parent process\n");
        //阻塞等待子进程的结束
        //获得子进程的退出状态,并对子进程做清理工作
        wait(NULL);
        while (1)
        {}
    }
    else if (0 == pid)  //子进程
    {
        printf("this is first child process\n");
        pid_t pid2 = fork();
        if (pid2 > 0)
        {
            return 0;
        }
        else if (0 == pid2)
        {
            int i = 0;
            for (; i < 3; i++)
            {
                printf("this is second child process\n");
            }
            return 0;
        }
        
    }
    else if (-1 == pid)  //创建进程失败
    {
        perror("fork");
        return -1;
    }

    printf("Hello World\n");
    return 0;
}

你可能感兴趣的:(dirent,进程,僵尸)