第八章 异常控制流

练习题 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:\n");
    for (int i = 0; i < argc; ++ i)
        printf("     argv[%d]: %s\n", i, argv[i]);

    printf("Enviroment variables:\n");
    for (int i = 0; envp[i]; ++ i)
        printf("     envp[%d]: %s\n", 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\n", strerror(errno));
        exit(0);
    }

    rest_seconds = snooze(secs);
    printf("User hits crtl-c after %u seconds\n", secs - rest_seconds);

    return 0;
}

unsigned int snooze(unsigned int secs)
{
    int rest_seconds = sleep(secs);

    printf("Sleep for %u of %u seconds\n", 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\n", 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\n", "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\n");
    }

    exit(0);
}
posted @ 2015-04-12 14:47  Leptus  阅读(548)  评论(0编辑  收藏  举报