• 第八章 异常控制流


    练习题 8.6:编写一个叫做myecho的程序,它打印出它的命令行参数和环境变量。

    #include <unistd.h>
    #include <sys/types.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    int main(int argc, char *argv[], char *envp[])
    {
        printf("Command line arguments:
    ");
        for (int i = 0; i < argc; ++ i)
            printf("     argv[%d]: %s
    ", i, argv[i]);
    
        printf("Enviroment variables:
    ");
        for (int i = 0; envp[i]; ++ i)
            printf("     envp[%d]: %s
    ", i, envp[i]);
        return 0;
    }

    练习题 8.7:编写名为snooze的程序,有一个命令行参数,使用该参数调用练习题8.5中的snooze函数,然后终止。编写程序,使得用户可以通过在键盘上输入 crtl-c

                   中断snooze函数。

    // snooze.c
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <signal.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    
    extern int errno;
    unsigned int snooze(unsigned int secs);
    void handler(int sig);
    
    int main(int argc, char *argv[])
    {
        unsigned int rest_seconds = 0;
        unsigned int secs = argv[1][0] - '0';
    
    
        if (signal(SIGINT, handler) == SIG_ERR)
        {
            fprintf(stderr, "signal error: %s
    ", strerror(errno));
            exit(0);
        }
    
        rest_seconds = snooze(secs);
        printf("User hits crtl-c after %u seconds
    ", secs - rest_seconds);
    
        return 0;
    }
    
    unsigned int snooze(unsigned int secs)
    {
        int rest_seconds = sleep(secs);
    
        printf("Sleep for %u of %u seconds
    ", secs - rest_seconds, secs);
        return rest_seconds;
    }
    
    void handler() {}

    练习题8.20:使用execve编写一个名为myls的程序,该程序的行为和 /bin/ls 程序一样。

    // myls.c
    #include <unistd.h>
    #include <sys/types.h>
    #include <stdlib.h>
    
    extern char **environ;
    
    int main(int argc, char *argv[])
    {
        execve("/bin/ls", argv, environ);
    
        exit(0);
    }

    练习题 8.22

    // mysystem.c
    #include <unistd.h>
    #include <sys/types.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    
    extern int erron;
    extern char **environ;
    extern int EINTP;
    
    int mysystem(char *command)
    {
        pid_t pid;
        int status;
    
        if (command == NULL)
            return -1;
    
        if ((pid = fork()) == -1)
            return -1;
    
        if (pid == 0)
        {
            char *argv[4];
    
            argv[0] == "sh";
            argv[1] == "-c";
            argv[2] == command;
            argv[3] == NULL;
    
            execve("bin/sh", argv, environ);
            exit(-1); // control should never come here
        }
    
        while (1)
        {
            if (waitpid(pid, &status, 0) == -1)
            {
                if (errno != EINTR)
                    exit(-1);
            }
            else
            {
                if (WIFEXITED(status))
                    return WEXITSTATUS(status);
                else
                    return status;
            }
        }
    }


    习题8.24

    // 8.24.h
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <error.h>
    #include <signal.h>
    
    extern int errno;
    extern int ECHILD;
    extern void psignal(int signal, const char *str);
    #define NCHILDREN 2
    #define MAXLINE 80
    char buf[MAXLINE];
    
    int main()
    {
        int status;
        pid_t pid;
    
        for (int i = 0; i < NCHILDREN; ++ i)
        {
            pid = fork();
            if (pid == 0)
                *(char *)main = 1;
        }
    
        while (pid = wait(&status) > 0)
        {
            if (WIFEXITED(status))
                printf("child %d terminated normally with exit status = %d
    ", pid, WEXITSTATUS(status));
            else
                if (WIFSIGNALED(status))
                {
                    sprintf(buf, "child %d terminated by signal %d: ", pid, WTERMSIG(status));
                    psignal(WTERMSIG(status), buf);
                }
        }
    
        if (errno != ECHILD)
        {
            fprintf(stderr, "%s: %s
    ", "wait error", strerror(errno));
            exit(0);
        }
        return 0;
    }

    习题8.25 编写fgets函数的一个版本tfgets,他5秒中后就会超时。tfgets 函数接收和 fgets 相同的参数。如果用户在5秒内不键入一个输入行,tfgets返回NULL。

                否则,返回一个指向输入行的指针。

    // tfgets.c
    #include <unistd.h>
    #include <sys/types.h>
    #include <signal.h>
    #include <string.h>
    #include <setjmp.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    static sigjmp_buf env;
    
    void handler(int signal)
    {
        alarm(0);
        longjmp(env, 1);
    }
    
    char *tfgets(char *buffer, int buffer_size, FILE *stream)
    {
    
        signal(SIGALRM, handler);
    
        alarm(5);
        if (!sigsetjmp(env, 1))
            return fgets(buffer, buffer_size, stream);
        else
            return NULL;
    }
    
    int main()
    {
        char *str;
        char buffer[100];
    
        while (1)
        {
            if (tfgets(buffer, sizeof(buffer),stdin) != NULL)
                printf("read: %s", buffer);
            else
                printf("time out
    ");
        }
    
        exit(0);
    }
  • 相关阅读:
    someThink
    快捷键
    typedef 的本质
    读取配置文件
    stl file
    摘自CSDNhttp://blog.csdn.net/gnuhpc/archive/2009/11/13/4808405.aspx
    thread demo
    B/S和C/S区别 java程序员
    上传文件 java程序员
    (八)VS的操作和使用技巧 java程序员
  • 原文地址:https://www.cnblogs.com/tallisHe/p/4419512.html
Copyright © 2020-2023  润新知