dirent,进程,僵尸

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

#include <stdio.h>
#include <string.h>  //strerror
#include <errno.h>  //errno
#include <unistd.h>  //read write
/*open*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#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 <unistd.h>
#include <stdio.h>  //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 <stdio.h>
#include <string.h>
/*stat()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
/*opendir()*/
#include <sys/types.h>
#include <dirent.h>

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 <unistd.h>   //fork()
#include <stdio.h>
#include <string.h>

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 <unistd.h>   //fork()
#include <stdio.h>
#include <string.h>
//一个进程结束时会关闭所有的文件描述符,
//释放在用户空间分配的内存,
//但它的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 <unistd.h>   //fork()
#include <stdio.h>
#include <string.h>
/*waitpid()*/
#include <sys/types.h>
#include <sys/wait.h>

//僵尸进程的处理方式
//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;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容