《C++高并发服务器笔记——第一章Linux系统编程入门》

第一章

Linux入门

1.1、Linux环境搭建

下载安装Xshell,在本地和自己的linux服务器链接起来
打开vscode,下载插件Remote Development
如果发现安装之后没有SSH Targets,那就切换Remote SSH版本
在windows下生成公钥和密钥,将公钥放在Ubuntu下,配置免密登录!

1.2和1.3、GCC

1.2和1.3、GCC

1.2.1、什么是GCC

1.2.2、编程语言的发展

1.2.3、GCC工作流程

1.2.4、gcc和g++的区别

1.2.5、GCC常用参数选项

实际操作

①接下来进行预处理操作(test.c为需要预处理的源代码,test.i为要生成的目标代码)

②汇编操作(生成汇编代码)

③生成而二进制文件

④将生成的代码进行链接

⑤定义指定的宏(DEBUG为需要定义的宏)

⑥展示全部警告

1.4和1.5、静态库的制作(静态库的使用)

1.4.1、什么是库

1.4.2、静态库的制作

实际操作

②先生成.o文件

③生成我们的静态库

1.5、静态库的使用

1.6和1.7、1.6、动态库的制作和使用(错误处理)

1.6、动态库的制作和使用

实际操作

1.7、动态库加载失败的原因

1.8、解决动态库加载失败问题

1.8、如何解决动态库加载失败的问题

①第一种方法(临时的,在终端配置环境变量LD_LIBRARY_PATH)

②第二种方法(在终端配置环境变量LD_LIBRARY_PATH,永久的)

③第三种方,修改我们的/etc/ld.so.cache

1.9、静态库和动态库的对比

1.静态库和动态库的对比

1.10和1.11和1.12、Makefile

1.10、Makefile(1)

1.10.1、什么是Makefile

1.10.2、Makefile的文件命名和规则

实际操作

1.11、Makefile(2)

1.工作原理(1.10.3)

实际操作

1.12、Makefile(3)

1.变量

2.模式匹配

3.函数

实际操作

①实现变量和模式匹配
②实现函数操作
③加入新的执行代码实现删除生成的.o文件

1.13|1.14|1.15|1.6、GDB调试

1.13、GDB调试(1),GDB调试(2)

1.什么是GDB

2.准备工作

3.GDB命令—启动、推出、查看代码

实际操作

①用list查看代码

1.15、GDB调试(3)

1.GDB命令—断点操作

实际操作

①对当前文件布置断点操作
②对非当前文件布置断点操作
③设置无效断点和有效断点
④条件断点

1.16、GDB调试(4)

1.GDB调试—调试命令

实际操作

①自动变量

1.17、标准C库IO函数和Linux系统系统IO函数对比

1.标准C库IO函数

①打开C库标准函数API的的命令

2.标准C库IO函数和Linux系统IO的关系

1.18、虚拟地址空间

在这里插入图片描述

1.19、文件描述符

在这里插入图片描述

  • 文件描述符表为数组,文件描述符数组大小默认为1024,默认的标准输入输出其实就是当前终端

1.20、open打开文件

LInux系统IO函数

在这里插入图片描述

  • Linux系统IO函数在第2
    在这里插入图片描述
①open的介绍

在这里插入图片描述
perror作用
终端输入命令man 3 perror

②如何使用open
  • 需要三个头文件
    在这里插入图片描述
  • 具有两种形式
      1. 第一个形式用于打开已经存在的文件
      1. 第二个用于创建文件

在这里插入图片描述
flags是一个宏,分别放在不同的头文件中

  • 举例使用
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> //函数声明
#include <stdio.h>
#include <unistd.h>

int main()
{
    //打开文件获取返回值,fd就是文件描述符
    int fd = open("a.txt", O_RDONLY);

    if (fd == -1)
    {
        perror("open");
    }

    close(fd);//关闭文件
    return 0;
}

1.21、open创建文件

open创建文件的介绍

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(const char *pathname, int flags, mode_t mode);
    参数:
        - pathname:要创建文件的路径
        - flags:对文件的操作权限和其他的设置
            - 必选项:O_RDONLY, O_WRONLY, O_RDWR  这三个互斥
            - 可选项:O_CREAT  文件不存在,创建文件
        - mode:八进制的数,表示用户对创建出的新的文件的操作权限,比如0775
        - 最终的权限:mode & ~umask
        0777    ->  0111111111
    &   0775    ->  0111111101
    --------------------------
                ->  0111111101
    按位与:0和任何数都为0
    umask的作用就是抹去某些权限

    flags参数是一个int类型的数据,占四个字节,32位。
    flags 32位数,每一个位就是一个标志位。
umask是什么
  • umask是当前的执行权限
    • 通过命令umask可以直接获取
    • 通过命令umask xxx可以直接修改
    • 修改只对当前终端的有效

open创建文件的使用

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main()
{
    //创建文件(fd为文件描述符)
    int fd = open("create.txt", O_RDWR | O_CREAT, 0777);

    if (fd == -1)
    {
        perror("open");
    }

    //关闭
    close(fd);

    return 0;
}

1.22、read、write函数

read和write的介绍

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
    参数:
        - fd:文件描述符,open得到的,通过这个文件描述符操作某个文件
        - buf:需要读取数据存放的地方,数组的地址
        - count:指定的数组的大小
    返回值:
        - 成功:
            > 0:返回实际读取到的字节数
            = 0:文件已经读取完了
        - 失败: -1,并且设置errno
-------------------------------------------------------------------
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
    参数:
        - fd:文件描述符,open得到的,通过这个文件描述符操作某个文件
        - buf:要网磁盘写入的数据,一般是数组
        - count:要写的数据的实际大小
    返回值:
        成功:实际写入的字节数
        失败:返回-1,并设置errno

read、write的使用

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


int main() {

    // 1.通过open打开english.txt文件
    int srcfd = open("english.txt", O_RDONLY);
    if (srcfd == -1) {
        perror("open");
        return -1;
    }

    // 2.创建一个新的拷贝文件
    int destfd = open("cpy.txt", O_WRONLY | O_CREAT, 0664);
    if (destfd == -1) {
        perror("open");
        return -1;
    }

    // 3.频繁的读写操作
    char buf[1024] = {'\0'};

    int len = 0;
    while ((len = read(srcfd, buf, sizeof (buf))) > 0) {
        write(destfd, buf, len);
    }

    // 4.关闭文件
    close(srcfd);
    close(destfd);

    return 0;
}

1.23、lseek函数

lessk介绍

标准c库
#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);

Linux系统函数
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
    参数:
        - fd:文件描述符,通过open得到的,通过fd操作某个文件
        - offset:偏移量
        - whence:
            SEEK_SET
                The file offset is set to offset bytes.
                设置文件指针的偏移量
            SEEK_CUR
                The file offset is set to its current location plus offset bytes.
                设置偏移量:当前位置 + 第二个参数offset的值
            SEEK_END
                The file offset is set to the size of the file plus offset bytes.
                设置偏移量:文件的大小 + 第二个参数offset的值
    返回值:返回文件指针最终所在的位置


作用:
    1.移动文件指针到文件头
        lseek(fd, 0, SEEK_SET);
    2.获取当前文件指针的位置
        lseek(fd, 0, SEEK_CUR);
    3.获取文件的长度
        lseek(fd, 0, SEEK_END
        
        );
    4.扩展文件的长度,当前10B,增加至110B,增加100字节
        lseek(fd, 100, SEEK_END);

lseek的使用

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
    int fd = open("hello.txt", O_RDWR);

    if (fd == -1) {
        perror("open");
        return -1;
    }

    //扩展文件长度
    int ret = lseek(fd, 100, SEEK_END);
    if (ret == -1) {
        perror("lseek");
        return -1;
    }

    //写入一个空数据
    write(fd, " ", 1);

    close(fd);

    return 0;
}

1.24、stat、lstat函数

stat的介绍

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>

    int stat(const char *pathname, struct stat *statbuf);
        作用:获取一个文件相关的一些信息
        参数:
            - pathname:操作的文件的路径
            - statbuf:stat类型的指针,结构体变量,传出参数, 用于保存获取到的文件的信息
        返回值:
            成功:返回0
            失败:返回-1,并且设置errno


    int lstat(const char *pathname, struct stat *statbuf);
    作用:
        参数:
            - pathname:操作的文件的路径
            - statbuf:stat类型的指针,结构体变量,传出参数, 用于保存获取到的文件的信息
        返回值:
            成功:返回0
            失败:返回-1,并且设置errno
stat查看文件的技巧
  • stat + 文件名可以查看文件的一些信息
    在这里插入图片描述
stat结构体

在这里插入图片描述

st_mode类型是一个十六位的整数

在这里插入图片描述

stat的使用

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
    struct stat statbuf;
    int ret = stat("a.txt", &statbuf);
    
    if (ret == -1) 
    {
        perror("stat");
        return -1;
    }

    printf("size :%ld\n", statbuf.st_size);

    return 0;
}

stat和lstat的区别

  • stat是用来获取目标的最终文件的信息,而lstat是用来获取软链接的信息

1.25、模拟实现 ls -l 命令

我们的目标与一些介绍

模拟实现 ls -l 命令
    nowcoder@nowcoder:~/Linux/lesson12$ ls -l a.txt 
    -rw-rw-r-- 1 nowcoder nowcoder 8 211 13:05 a.txt
    权限   硬连接数  所有者  所在组  

    argc 是 argument count的缩写,表示传入main函数的参数个数;
    argv 是 argument vector的缩写,表示传入main函数的参数序列或指针,
    并且第一个参数argv[0]一定是程序的名称,并且包含了程序所在的完整路径,
    所以确切的说需要我们输入的main函数的参数个数应该是argc-1个;
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <pwd.h>
#include <grp.h>
#include <string.h>
#include <time.h>

int main(int argc, char* argv[])
{
    //判断输入的参数是否正确
    if (argc < 2) 
    {
        printf("%s filename\n", argv[0]);
        return -1;
    }

    struct stat st;
    int ret = stat(argv[1], &st);

    if (ret == -1)
    {
        perror("stat");
        return -1;
    }

    //获取文件类型和权限
    char perms[11] = {'\0'};    //用于保存文件类型和文件权限的字符串

    //判断的类型
    switch (st.st_mode & __S_IFMT)
    {
        case __S_IFLNK:
            perms[0] = 'l';
            break;
        case __S_IFDIR:
            perms[0] = 'd';
            break;
        case __S_IFREG:
            perms[0] = '-';
            break;
        case __S_IFBLK:
            perms[0] = 'b';
            break;
        case __S_IFCHR:
            perms[0] = 'c';
            break;
        case __S_IFSOCK:
            perms[0] = 's';
            break;
        case __S_IFIFO:
            perms[0] = 'p';
            break;
        default:
            perms[0] = '?';
            break;
    }

    //文件的访问权限
    //文件所有者
    perms[1] = (st.st_mode & S_IRUSR) ? 'r' : '-';
    perms[2] = (st.st_mode & S_IWUSR) ? 'w' : '-';
    perms[3] = (st.st_mode & S_IXUSR) ? 'x' : '-';

    //文件所在组
    perms[4] = (st.st_mode & S_IRGRP) ? 'r' : '-';
    perms[5] = (st.st_mode & S_IWGRP) ? 'w' : '-';
    perms[6] = (st.st_mode & S_IXGRP) ? 'x' : '-';

    //其他人
    perms[7] = (st.st_mode & S_IROTH) ? 'r' : '-';
    perms[8] = (st.st_mode & S_IWOTH) ? 'w' : '-';
    perms[9] = (st.st_mode & S_IXOTH) ? 'x' : '-';

    //硬连接数
    int linkNum = st.st_nlink;

    // 所有者(getpwuid 为获取使用者的信息)
    char* fileUser = getpwuid(st.st_uid)->pw_name;

    // 所在组(getgrgid 为获取所在组的信息)
    char* fileGrp = getgrgid(st.st_gid)->gr_name;

    // 文件大小
    long int fileSize = st.st_size;

    //获取文件的修改时间
    char *time = ctime(&st.st_mtime);
    char mtime[512] = {'\0'};
    strncpy(mtime, time, strlen(time) - 1);

    char buf[1024];
    sprintf(buf, "%s %d %s %s %ld %s %s", perms, linkNum, fileUser, fileGrp, fileSize, mtime, argv[1]);

    printf("%s\n", buf);
    return 0;
}

1.26、文件属性操作函数

文件属性操作函数有哪几个

在这里插入图片描述

access

  • access的介绍
    #include <unistd.h>
    int access(const char *pathname, int mode);
        作用:判断某个文件是否有某个权限,或者判断文件是否存在
        参数:
            - pathname:判断的文件路径
            - mode:
                R_OK:是否有读权限
                W_OK:是否有写权限
                X_OK:是否有执行权限
                F_OK:文件是否存在
        返回值:成功返回0,失败返回-1
  • acess的使用
#include <unistd.h>
#include <stdio.h>

int main()
{
    int ret = access("a.txt", F_OK);
    if (ret == -1)
    {
        perror("access");
        return -1;
    }
    printf("文件存在\n");
    return 0;
}

chmod

  • chmod的介绍
    #include <sys/stat.h>
    int chmod(const char *pathname, mode_t mode);
        作用:修改文件的权限
        参数:
            - pathname:需要修改的文件的路径
            - mode:需要修改的值,八进制的数
        返回值:成功返回0,失败返回1
  • chmod的使用
#include <sys/stat.h>
#include <stdio.h>

int main()
{
    int ret = chmod("a.txt", 0660);

    if (ret == -1) 
    {
        perror("chmod");
        return -1;
    }

    return 0;
}

chown

查看用户和组的id
id 用户名/组名
  • chown的介绍
    #include <unistd.h>
    int chown(const char *pathname, uid_t owner, gid_t group);
        作用:修改文件的所属用户和所属组
        参数:
            - pathname:需要修改的文件的路径
            - owner:最终文件所在用户
            - group:最终文件所在组
        返回值:成功返回0,失败返回-1
  • chown的使用
#include <unistd.h>
#include <stdio.h>

int main()
{
    int ret = chown("a.txt", 1001, 1001);
    if (ret == -1)
    {
        perror("chown");
        return -1;
    }
    return 0;
}

truncate

  • truncate的介绍
    #include <unistd.h>
    #include <sys/types.h>
    int truncate(const char *path, off_t length);
        作用:缩减或者扩展文件的尺寸至指定大小
        参数:
            - path:需要修改的文件的路径
            - length:需要文件最终变成的大小
        返回值:成功返回0,失败返回-1
  • truncate的使用
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>

int main()
{
    int ret = truncate("b.txt", 5);

    if (ret == -1)
    {
        perror("truncate");
        return -1;
    }
    return 0;
}

1.27、目录操作函数

目录操作函数有哪些

在这里插入图片描述

1.mkdir
  • mkdir的功能
    #include <sys/stat.h>
    #include <sys/types.h>
    int mkdir(const char *pathname, mode_t mode);
        作用:创建一个目录
        参数:
            - pathname:创建 一个目录的路径
            - mode:权限,一个八进制的数
        返回值:成功返回0,失败返回-1,并且修改eroorn
  • 实际操作
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>

int main()
{
    int ret = mkdir("aaa", 0777);

    if (ret == -1)
    {
        perror("mkdir");
        return -1;
    }
    return 0;
}
2.rmdir

作用就是删除目录,但是只能消除空目录

3.rename
  • rename的功能
    #include <sys/stat.h>
    #include <sys/types.h>
    int rename(const char *oldpath, const char *newpath);
        作用:将旧目录修改为新的目录,也可以修改文件名称
        参数:
            - oldpath:旧目录
            - newpath:新目录
        返回值:成功返回0,失败返回-1,并且修改eroorn
  • 实际操作
#include <stdio.h>

int main()
{
    int ret = rename("aaa", "bbb");
    if (ret == -1)
    {
        perror("rename");
        return -1;
    }

    return 0;
}
4.chdir、getcwd
  • chdirgetcwd的功能
    #include <unistd.h>
    int chdir(const char *path);
        作用:修改进程的工作目录
            比如在/home/nowcoder 启动了一个可执行程序a.out,进程的工作目录就是/home/nowcoder
        参数:
            - path:需要修改的工作目录
        返回值:成功返回0,失败返回-1,并且修改eroorn
    
    #include <unistd.h>
    char *getcwd(char *buf, size_t size);
        作用:获取当前工作目录
        参数:
            - buf:存储的路径,指向的是一个数组(传出参数)
            - size:数组的大小
        返回值:返回指向的一块内存,这个数据就是第一个参数的内存地址
  • 实际操作
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    //获取当前的工作目录
    char buf[128];
    getcwd(buf, sizeof(buf));

    printf("当前的工作目录%s\n", buf);

    //修改工作目录
    int ret = chdir("/home/nowcoder/Linux/lesson13");
    if (ret == -1)
    {
        perror("chdir");
        return -1;
    }

    //创建一个新的文件
    int fd = open("chdir.txt", O_CREAT | O_RDWR, 0664);
    if (fd == - 1)
    {
        perror("open");
        return -1;
    }

    close(fd);

    //获取当前工作目录
    char buf1[108];
    getcwd(buf1, sizeof buf1);
    printf("当前的工作目录是%s\n", buf1);

    return 0;
}

1.28、目录操作函数

目录函数有哪些

在这里插入图片描述

dirent结构体和d_type

在这里插入图片描述

opendir、readdir、closedir的介绍与使用

处于man 3下,标准c库函数

    //打开一个目录
    #include <sys/types.h>
    #include <dirent.h>
    DIR *opendir(const char *name);
        参数:
            - name:需要打开的目录名称
        返回值:
            DIR* 类型,理解为目录流信息
            错误返回NULL
    
    //读取目录中的数据
    #include <dirent.h>
    struct dirent *readdir(DIR *dirp);
        参数:
            - dirp:是opendir返回的结果
        返回值:
            - struct dirent:代表读取到的文件信息
            读取到末尾或者失败,返回NULL,读到末尾不设置errorn

    //关闭目录
    #include <sys/types.h>
    #include <dirent.h>
    int closedir(DIR *dirp);
  • 寻找指定目录下普通文件的个数
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>

int getFileNum(const char* path);

//读取某个目录所有的普通文件的个数
int main(int argc, char* argv[])
{
    //./a.out lesson15
    if (argc < 2)
    {
        printf("%s path\n", argv[0]);
        return -1;
    }

    int num = getFileNum(argv[1]);

    printf("普通文件的个数为:%d\n", num);

    return 0;
}

//用于递归计算目录下所有普通文件的个数
int getFileNum(const char* path)
{
    //1.打开目录
    DIR* dir = opendir(path);

    //记录普通文件的个数
    int total = 0;

    if (dir == NULL)
    {
        perror("DIR");
        exit(0);
    }

    struct dirent* ptr;
    while ((ptr = readdir(dir)) != NULL)
    {
        //获取名称
        char* dname = ptr->d_name;

        if (strcmp(dname, ".") == 0 || strcmp(dname, "..") == 0) 
        {
            continue;
        }

        //判断是普通文件还是目录
        if (ptr->d_type == DT_DIR)
        {
            //目录,继续读取这个文件
            char newPath[256];
            sprintf(newPath, "%s/%s", path, dname);
            total += getFileNum(newPath);
        } 
        else if (ptr->d_type == DT_REG)
        {
            //普通文件
            total ++ ;
        }
    }

    //关闭目录
    closedir(dir);

    return total;
}

1.29、dup和dup2函数

dup函数和dup2函数得介绍

在这里插入图片描述

dup函数
  • dup函数介绍
    #include <unistd.h>
    int dup(int oldfd);
        作用:复制一个新的文件描述符
            fd,int fd1 = dup(fd)
            fd指向a.txt,fd1也指向a.txt
            从空闲的文件描述符表中找一个最小的,作为新的拷贝得文件描述符
        返回值:返回一个新的文件描述符,失败返回-1
  • dup得使用
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    int fd = open("a.txt", O_CREAT | O_RDWR, 0664);

    int fd1 = dup(fd);

    if (fd1 == -1)
    {
        perror("dup");
        return -1;
    }

    printf("fd: %d, fd1: %d\n", fd, fd1);
    
    close(fd);

    char *str = "hello";

    int ret = write(fd1, str, strlen(str));

    if (ret == -1)
    {
        perror("write");
        return -1;
    }

    close(fd1);

    return 0;
}
2.dup2
  • dup2得介绍
    #include <unistd.h>
    int dup2(int oldfd, int newfd);
        作用:重定向文件描述符
            oldfd 指向a.txt, newfd 指向b.txt
            函数调用成功之后,newfd 和 b.txt做close,newfd指向a.txt
            oldfd 必须是一个有效得文件描述符
            oldfd 和 newfd 值相同,相当于什么都没有做
  • dup2得使用
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    int oldfd = open("1.txt", O_CREAT | O_RDWR, 0664);
    if (oldfd == -1)
    {
        perror("open1");
        return -1;
    }


    int newfd = open("2.txt", O_CREAT | O_RDWR, 0664);
    if (newfd == -1)
    {
        perror("open2");
        return -1;
    }

    printf("oldfd: %d, newfd: %d\n", oldfd, newfd);

    int fd = dup2(oldfd, newfd);
    if (fd == -1)
    {
        perror("dup2");
        return -1;
    }

    //通过newfd去写数据,实际操作得是1.txt,而不是2.txt
    char* str = "hello, dup2";
    int len = write(newfd, str, strlen(str));
    
    if (len == -1)
    {
        perror("write");
        return -1;
    }

    printf("oldfd: %d, newfd: %d, fd: %d, len: %d\n", oldfd, newfd, fd, len);

    close(oldfd);
    close(newfd);

    return 0;
}

1.30、fcntl函数

fcntl函数介绍

在这里插入图片描述

fcntl

  • fcntl的介绍
    #include <unistd.h>
    #include <fcntl.h>
    int fcntl(int fd, int cmd, ... arg );
        作用:主要看cmd得参数
        参数:
            - fd:表示需要操作文件的文件描述符
            - cmd:表示对文件描述符进行如何操作
                - F_DUPFD:复制文件描述符,复制的第一个参数fd,得到一个新的文件描述符
                    int ret = fcntl(fd, F_DUPFD), ret为复制出来的文件描述符

                - F_GETFL:获取指定文件描述符状态的flag
                    获取的flag和我们通过open函数传递的flag是一个东西
                - F_SETFL:设置文件描述符的文件状态flag
                    必选项:O_RDONLY, O_WRONLY, O_RDWR,不可以修改
                    可选项:O_APPEND, O_NONBLOCK
                        O_APPEND 表示追加数据
                        O_NONBLOK 设置成非阻塞
        阻塞和非阻塞:描述的是函数调用的行为。add()
  • fcntl的使用
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>

int main()
{
    //1.复制文件描述符
    int fd = open("1.txt", O_RDWR);

    if (fd == -1)
    {
        perror("open");
        return -1;
    }
    int ret = fcntl(fd, F_DUPFD);

    char* str = "hello, fcntl";
    write(ret, str, strlen(str));//(覆盖写入)

    //2.修改或者获取文件状态flag

    //获取文件描述符状态flag
    int flag = fcntl(fd, F_GETFD);
    flag |= O_APPEND;

    //修改我们文件的flag,给flag加入我们的O_APPEND
    int retSetFl = fcntl(fd, F_SETFD, flag);

    write(ret, str, strlen(str));//继续追加
    printf("fd: %d, ret: %d, flag: %d, retSetFl: %d\n", fd, ret, flag, retSetFl);

    //关闭文件
    close(fd);


    return 0;
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值