法大奥山研究室

 previous  contents

[練習問題]


  1. 次は,UNIX のシェルコマンド echo のソースファイルである。解読せよ。(Copyright は,UC Berkeley にあります。改良したものも含め,再配布するときは,copyright を必ず保持してください。)
    /* $NetBSD: echo.c,v 1.9 2001/07/29 22:36:11 wiz Exp $     */
    
    /*
     * Copyright (c) 1989, 1993
     *     The Regents of the University of California.  All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     * 1. Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     * 2. Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     * 3. All advertising materials mentioning features or use of this software
     *    must display the following acknowledgement:
     *     This product includes software developed by the University of
     *     California, Berkeley and its contributors.
     * 4. Neither the name of the University nor the names of its contributors
     *    may be used to endorse or promote products derived from this software
     *    without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     * SUCH DAMAGE.
     */
    
    #include <sys/cdefs.h>
    #ifndef lint
    __COPYRIGHT(
    "@(#) Copyright (c) 1989, 1993\n\
         The Regents of the University of California.  All rights reserved.\n");
    #endif /* not lint */
    
    #ifndef lint
    #if 0
    static char sccsid[] = "@(#)echo.c     8.1 (Berkeley) 5/31/93";
    #else
    __RCSID("$NetBSD: echo.c,v 1.9 2001/07/29 22:36:11 wiz Exp $");
    #endif
    #endif /* not lint */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(int, char *[]);
    
    /* ARGSUSED */
    int
    main(int argc, char *argv[])
    {
           int nflag;
    
           /* This utility may NOT do getopt(3) option parsing. */
           if (*++argv && !strcmp(*argv, "-n")) {
                  ++argv;
                  nflag = 1;
           }
           else
                  nflag = 0;
    
           while (*argv) {
                  (void)printf("%s", *argv);
                  if (*++argv)
                         (void)putchar(' ');
           }
           if (nflag == 0)
                  (void)putchar('\n');
           exit(0);
           /* NOTREACHED */
    }
    
  2. 次は,ヘッダファイル string.h にある strtok 関数のソースファイルである。解読せよ。但し,ソース中の _DIAGASSERT は,assert と置き換えてよい。(Copyright は,UC Berkeley にあります。改良したものも含め,再配布するときは,copyright を必ず保持してください。)
    /*     $NetBSD: strtok.c,v 1.10 1999/09/20 04:39:49 lukem Exp $     */
    
    /*
     * Copyright (c) 1988, 1993
     *     The Regents of the University of California.  All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     * 1. Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     * 2. Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     * 3. All advertising materials mentioning features or use of this software
     *    must display the following acknowledgement:
     *     This product includes software developed by the University of
     *     California, Berkeley and its contributors.
     * 4. Neither the name of the University nor the names of its contributors
     *    may be used to endorse or promote products derived from this software
     *    without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     * SUCH DAMAGE.
     */
    
    #include <sys/cdefs.h>
    #if defined(LIBC_SCCS) && !defined(lint)
    #if 0
    static char sccsid[] = "@(#)strtok.c     8.1 (Berkeley) 6/4/93";
    #else
    __RCSID("$NetBSD: strtok.c,v 1.10 1999/09/20 04:39:49 lukem Exp $");
    #endif
    #endif /* LIBC_SCCS and not lint */
    
    #include <assert.h>
    #include <string.h>
    
    char *
    strtok(s, delim)
           char *s;
           const char *delim;
    {
           const char *spanp;
           int c, sc;
           char *tok;
           static char *last;
    
           /* s may be NULL */
           _DIAGASSERT(delim != NULL);
    
           if (s == NULL && (s = last) == NULL)
                  return (NULL);
    
           /*
            * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
            */
    cont:
           c = *s++;
           for (spanp = delim; (sc = *spanp++) != 0;) {
                  if (c == sc)
                         goto cont;
           }
    
           if (c == 0) {              /* no non-delimiter characters */
                  last = NULL;
                  return (NULL);
           }
           tok = s - 1;
    
           /*
            * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
            * Note that delim must have one NUL; we stop if we see that, too.
            */
           for (;;) {
                  c = *s++;
                  spanp = delim;
                  do {
                         if ((sc = *spanp++) == c) {
                                if (c == 0)
                                       s = NULL;
                                else
                                       s[-1] = 0;
                                last = s;
                                return (tok);
                         }
                  } while (sc != 0);
           }
           /* NOTREACHED */
    }
    
  3. 次は,UNIX コマンド tee のソースファイルである。解読せよ。(Copyright は,UC Berkeley にあります。改良したものも含め,再配布するときは,copyright を必ず保持してください。)
    /*       $NetBSD: tee.c,v 1.6 1997/10/20 00:37:11 lukem Exp $       */
    
    /*
     * Copyright (c) 1988, 1993
     *       The Regents of the University of California.  All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     * 1. Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     * 2. Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     * 3. All advertising materials mentioning features or use of this software
     *    must display the following acknowledgement:
     *       This product includes software developed by the University of
     *       California, Berkeley and its contributors.
     * 4. Neither the name of the University nor the names of its contributors
     *    may be used to endorse or promote products derived from this software
     *    without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     * SUCH DAMAGE.
     */
    
    #include <sys/cdefs.h>
    #ifndef lint
    __COPYRIGHT("@(#) Copyright (c) 1988, 1993\n\
           The Regents of the University of California.  All rights reserved.\n");
    #endif /* not lint */
    
    #ifndef lint
    #if 0
    static char sccsid[] = "@(#)tee.c       8.1 (Berkeley) 6/6/93";
    #endif
    __RCSID("$NetBSD: tee.c,v 1.6 1997/10/20 00:37:11 lukem Exp $");
    #endif
    
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <signal.h>
    #include <errno.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <locale.h>
    #include <err.h>
    
    typedef struct _list {
           struct _list *next;
           int fd;
           char *name;
    } LIST;
    LIST *head;
    
    void       add __P((int, char *));
    int       main __P((int, char **));
    
    int
    main(argc, argv)
           int argc;
           char *argv[];
    {
           LIST *p;
           int n, fd, rval, wval;
           char *bp;
           int append, ch, exitval;
           char *buf;
    #define       BSIZE (8 * 1024)
    
           setlocale(LC_ALL, "");
    
           append = 0;
           while ((ch = getopt(argc, argv, "ai")) != -1)
                  switch((char)ch) {
                  case 'a':
                         append = 1;
                         break;
                  case 'i':
                         (void)signal(SIGINT, SIG_IGN);
                         break;
                  case '?':
                  default:
                         (void)fprintf(stderr, "usage: tee [-ai] [file ...]\n");
                         exit(1);
                  }
           argv += optind;
           argc -= optind;
    
           if ((buf = malloc((size_t)BSIZE)) == NULL)
                  err(1, "malloc");
    
           add(STDOUT_FILENO, "stdout");
    
           for (exitval = 0; *argv; ++argv)
                  if ((fd = open(*argv, append ? O_WRONLY|O_CREAT|O_APPEND :
                      O_WRONLY|O_CREAT|O_TRUNC, DEFFILEMODE)) < 0) {
                         warn("%s", *argv);
                         exitval = 1;
                  } else
                         add(fd, *argv);
    
           while ((rval = read(STDIN_FILENO, buf, BSIZE)) > 0)
                  for (p = head; p; p = p->next) {
                         n = rval;
                         bp = buf;
                         do {
                                if ((wval = write(p->fd, bp, n)) == -1) {
                                       warn("%s", p->name);
                                       exitval = 1;
                                       break;
                                }
                                bp += wval;
                         } while (n -= wval);
                  }
           if (rval < 0) {
                  warn("read");
                  exitval = 1;
           }
    
           for (p = head; p; p = p->next) {
                  if (close(p->fd) == -1) {
                         warn("%s", p->name);
                         exitval = 1;
                  }
           }
    
           exit(exitval);
    }
    
    void
    add(fd, name)
           int fd;
           char *name;
    {
           LIST *p;
    
           if ((p = malloc((size_t)sizeof(LIST))) == NULL)
                  err(1, "malloc");
           p->fd = fd;
           p->name = name;
           p->next = head;
           head = p;
    }
    

 previous  contents