In this tutorial, we'll be looking at the code structure of the 'echo' utility and will try to understand how it works, for those who are unfamilliar with the 'echo' utility, its one of the most basic and most useful utilities in a shell it prints out its arguments on the standard output, if you have some shell scripting experience, most probably you must have used it and actually most of output related shell scripts use this utility. The Code Source of Echo Code: /* $NetBSD: echo.c,v 1.18 2008/09/18 05:42:08 dholland 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. 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\ The Regents of the University of California. All rights reserved."); #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.18 2008/09/18 05:42:08 dholland Exp $"); #endif #endif /* not lint */ #include <locale.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int, char *[]); /* ARGSUSED */ int main(int argc, char *argv[]) { int nflag; setprogname(argv[0]); (void)setlocale(LC_ALL, ""); /* 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'); fflush(stdout); if (ferror(stdout)) exit(1); exit(0); /* NOTREACHED */ } More that 1/3rd the code is the liscense, copyright info etc. We can just ignore that part for now and focus on the real code. Code: int main(int argc, char *argv[]) The above code defines the main function (often the entry point of a C program), argc and argv are argument count and argument verctor respectively. Code: int nflag; “nflag” is used to indicate whether the program is given a “-n” as an argument or not. The next 2 lines are again configuration based and we'll not be digging into this for the scope of this tutorial. Code: if (*++argv && !strcmp(*argv, "-n")) { ++argv; nflag = 1; } else nflag = 0; Note we are pre-incremneting the argv before using as argv[0] is the name of the program itself i.e “./echo” in our case, basically we are checking if we have the first argument and if yes, then we check if its “-n” i.e nflag, if both the conditions evaluate to true we simply increment the argument vector and set the nflag, else we set it to 0. Now comes the main part, this is where the real meat of the program lies. Code: while (*argv) { (void)printf("%s", *argv); if (*++argv) (void)putchar(' '); } We loop through the arguent vector and keep printing it, with SPACES in between. Code: if (nflag == 0) (void)putchar('\n'); Then we simply print a newline if the "nflag" was not set, and the end we flush the output buffer and exit. Conclusion The motive of this tutorial was to provide a foundation to code reading and how to go about reading code written by other programmers. 'ECHO' was the utility with the most basic code-base i could find, which can serve as a good starting point for beginners.