C基础常用代码

1. 写文件

复制代码
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

//write ASCII value
int file_write(char *fn, int val)
{
    int fd, ret;
    char buff[16] = {0};
    
    sprintf(buff, "%d", val); //change int to ASCII string val

    fd = open(fn, O_RDWR);
    if (fd < 0) {
        fprintf(stderr,"my_debug: open %s failed: %s\n", fn, strerror(errno));
        return -1;
    }
    ret = write(fd, buff, strlen(buff));
    if (ret < 0) {
        fprintf(stderr,"my_debug: write %s failed: %s\n", fn, strerror(errno));
        return -1;
    }
    close(fd);

    return 0;
}

void main()
{
    file_write("tmp.txt", 111);
}
复制代码

 

2. 读文件

复制代码
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

int file_read(char *fn)
{
    int fd, ret;
    ssize_t count = 0;
    char buff[257];

    fd = open(fn, O_RDWR);
    if (fd < 0) {
        fprintf(stderr,"open %s failed: %s\n", fn, strerror(errno));
        return -1;
    }

    do {
        int ret = read(fd, buff, sizeof(buff)-1);
        if (!ret) break;
        count += ret;
        buff[ret] = 0;
        printf("%s", buff);
    } while (ret);
    printf("data count=%ld\n", count);
    
}

int main()
{
    file_read("tmp.txt");
    return 0;
}
复制代码

 

3. 使用信号

复制代码
#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void sig_handler(int sig)
{
    printf("sig=%d\n", sig);
    return;
}

int main() {
    if (signal(SIGCHLD, sig_handler) == SIG_ERR) {
        printf("signal error");
    }
    printf("Parent loop\n"); 
    while (1) sleep(1); 
}
复制代码

 

3.1 监控信号

复制代码
/*
 * kill -l 可查看各个信号的值。
 * kill -9 还是可杀掉,且信号值打印不出来,不可捕捉。
 */
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>

int smenu[] = {
    1,       2,  3,  4,  5,  6,  7,  8,  9, 10,
    11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
    21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
    31, 34, 35, 36, 37, 38, 39, 40, 41, 42,
    43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
    53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
    63, 64
};

#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))

int g_choice;

void sig_handler(int sig) {
    printf("Ham: Caught signal %d\n", sig);
    if (g_choice == 0) {
        exit(1);
    }
}

int main(int argc, char *argv) {
    int i;

    if (argc > 1)
        g_choice = 1;

    for (i = 0; i < ARRAY_SIZE(smenu); i++) {
        signal(smenu[i], sig_handler);
    }

    while(1) {
        sleep(1);
    }

    return 0;
}
复制代码

 

4. dup()&execv()实验

4.1. dup_test.c

复制代码
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

int main()
{
    int fd_1, fd_2;
    pid_t pid;
    
    fd_1 = open("tmp.txt", O_RDWR);
    if (fd_1 < 0) {
        fprintf(stderr,"my_debug: open failed: %s\n", strerror(errno));
        return -1;
    }
    fprintf(stderr,"1: fd_1=%d\n", fd_1);
    
    /* dup fd */
    fd_2 = fcntl(fd_1, F_DUPFD_CLOEXEC, 0); 
    fprintf(stderr,"2: fd_2=%d\n", fd_2);

    pid = fork();
    if (pid == 0) {
        /* must null terminal */
        char *args[] = {"600", NULL};
        pid_t child = getpid();
        fprintf(stderr, "child pid=%d\n", child); //注: child同样存在两个fd
#if 1
        /* 这里若不执行会提前退出,所有者会变成系统,但是打开的文件还是不会关闭 */
        if(execv("./execv_test", args) < 0) {
            fprintf(stderr,"execv failed: %s\n", strerror(errno));
            return -1;
        }
#endif
    } else {
        pid_t parent = getpid();
        fprintf(stderr,"parent pid=%d\n", parent);
    }
    sleep(600);
    return 0;
}
复制代码

4.2. execv_test.c

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>  

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

    printf("execv: I am execv child process.\n");

    /* execv: argc=1, argv[0]=600, argv[1]=(null). 不同于命令行,这个argv[0]就是参数 */
    printf("execv: argc=%d, argv[0]=%s, argv[1]=%s.\n", argc, argv[0], argv[1]);

    if (argc == 1) {
        sleep_time = atoi(argv[0]);
        printf("execv: enter sleep %ds.\n", sleep_time);
        sleep(sleep_time);
    }
}
复制代码


4.3. 打印内容

(1) 只fork:

/proc$ ls 1307/fd -l //parent
lrwx------ 1 ham ham 64 1月   7 14:20 3 -> /data/ham/file_161/4.c_test/15.dup_test/tmp.txt
lrwx------ 1 ham ham 64 1月   7 14:20 4 -> /data/ham/file_161/4.c_test/15.dup_test/tmp.txt
/proc$
/proc$ ls 1308/fd -l  //child
lrwx------ 1 ham ham 64 1月   7 14:20 3 -> /data/ham/file_161/4.c_test/15.dup_test/tmp.txt
lrwx------ 1 ham ham 64 1月   7 14:20 4 -> /data/ham/file_161/4.c_test/15.dup_test/tmp.txt

可以看到 fork() 后子进程继承父进程所有打开的文件,且文件fd不会自动关闭。


(2) fork后执行execv:

/proc$ ls 47209/fd -l
lrwx------ 1 ham ham 64 1月   7 14:45 3 -> /data/ham/file_161/4.c_test/15.dup_test/tmp.txt
lrwx------ 1 ham ham 64 1月   7 14:45 4 -> /data/ham/file_161/4.c_test/15.dup_test/tmp.txt
/proc$ 
/proc$ ls 47210/fd -l  
lrwx------ 1 ham ham 64 1月   7 14:45 3 -> /data/ham/file_161/4.c_test/15.dup_test/tmp.txt

可以看到 execv() 后子进程继承父进程的通过 fcntl(fd_1, F_DUPFD_CLOEXEC, 0) dump出来的fd已经自动关闭了,只剩下一个没有关闭。进一步实验,即使父进程中执行execv(),其dup出来的fd也会自动关闭。

 

posted on   Hello-World3  阅读(52)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2021-12-08 调度器19—/proc/sched_debug文件
2021-12-08 调度器18—/proc/schedstat文件
2021-12-08 VFS虚拟文件系统
2021-12-08 给Linux内核提交代码
2018-12-08 selinux操作
2018-12-08 /proc/sys/vm/drop_caches 清理缓存
2018-12-08 aircrack-ng 工具集学习

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示