Appendix C Complex Makefile Example
Here is the makefile for the GNU tar program. This is a moderately complex makefile.
Because it is the first target, the default goal is `all'. An interesting feature of this makefile is that testpad.h is a source file automatically created by the testpad program, itself compiled from testpad.c.
If you type `make' or `make all', then make creates the tar executable, the rmt daemon that provides remote tape access, and the tar.info Info file.
If you type `make install', then make not only creates tar, rmt, and tar.info, but also installs them.
If you type `make clean', then make removes the `.o' files, and the tar, rmt, testpad, testpad.h, and core files.
If you type `make distclean', then make not only removes the same files as does `make clean' but also the TAGS, Makefile, and config.status files. (Although it is not evident, this makefile (and config.status) is generated by the user with the configure program, which is provided in the tar distribution, but is not shown here.)
If you type `make realclean', then make removes the same files as does `make distclean' and also removes the Info files generated from tar.texinfo.
In addition, there are targets shar and dist that create distribution kits.
# Generated automatically from Makefile.in by configure.
# Un*x Makefile for GNU tar program.
# Copyright (C) 1991 Free Software Foundation, Inc.
# This program is free software; you can redistribute
# it and/or modify it under the terms of the GNU
# General Public License ...
...
...
SHELL = /bin/sh
#### Start of system configuration section. ####
srcdir = .
# If you use gcc, you should either run the
# fixincludes script that comes with it or else use
# gcc with the -traditional option. Otherwise ioctl
# calls will be compiled incorrectly on some systems.
CC = gcc -O
YACC = bison -y
INSTALL = /usr/local/bin/install -c
INSTALLDATA = /usr/local/bin/install -c -m 644
# Things you might add to DEFS:
# -DSTDC_HEADERS If you have ANSI C headers and
# libraries.
# -DPOSIX If you have POSIX.1 headers and
# libraries.
# -DBSD42 If you have sys/dir.h (unless
# you use -DPOSIX), sys/file.h,
# and st_blocks in `struct stat'.
# -DUSG If you have System V/ANSI C
# string and memory functions
# and headers, sys/sysmacros.h,
# fcntl.h, getcwd, no valloc,
# and ndir.h (unless
# you use -DDIRENT).
# -DNO_MEMORY_H If USG or STDC_HEADERS but do not
# include memory.h.
# -DDIRENT If USG and you have dirent.h
# instead of ndir.h.
# -DSIGTYPE=int If your signal handlers
# return int, not void.
# -DNO_MTIO If you lack sys/mtio.h
# (magtape ioctls).
# -DNO_REMOTE If you do not have a remote shell
# or rexec.
# -DUSE_REXEC To use rexec for remote tape
# operations instead of
# forking rsh or remsh.
# -DVPRINTF_MISSING If you lack vprintf function
# (but have _doprnt).
# -DDOPRNT_MISSING If you lack _doprnt function.
# Also need to define
# -DVPRINTF_MISSING.
# -DFTIME_MISSING If you lack ftime system call.
# -DSTRSTR_MISSING If you lack strstr function.
# -DVALLOC_MISSING If you lack valloc function.
# -DMKDIR_MISSING If you lack mkdir and
# rmdir system calls.
# -DRENAME_MISSING If you lack rename system call.
# -DFTRUNCATE_MISSING If you lack ftruncate
# system call.
# -DV7 On Version 7 Unix (not
# tested in a long time).
# -DEMUL_OPEN3 If you lack a 3-argument version
# of open, and want to emulate it
# with system calls you do have.
# -DNO_OPEN3 If you lack the 3-argument open
# and want to disable the tar -k
# option instead of emulating open.
# -DXENIX If you have sys/inode.h
# and need it 94 to be included.
DEFS = -DSIGTYPE=int -DDIRENT -DSTRSTR_MISSING \
-DVPRINTF_MISSING -DBSD42
# Set this to rtapelib.o unless you defined NO_REMOTE,
# in which case make it empty.
RTAPELIB = rtapelib.o
LIBS =
DEF_AR_FILE = /dev/rmt8
DEFBLOCKING = 20
CDEBUG = -g
CFLAGS = $(CDEBUG) -I. -I$(srcdir) $(DEFS) \
-DDEF_AR_FILE=\"$(DEF_AR_FILE)\" \
-DDEFBLOCKING=$(DEFBLOCKING)
LDFLAGS = -g
prefix = /usr/local
# Prefix for each installed program,
# normally empty or `g'.
binprefix =
# The directory to install tar in.
bindir = $(prefix)/bin
# The directory to install the info files in.
infodir = $(prefix)/info
#### End of system configuration section. ####
SRC1 = tar.c create.c extract.c buffer.c \
getoldopt.c update.c gnu.c mangle.c
SRC2 = version.c list.c names.c diffarch.c \
port.c wildmat.c getopt.c
SRC3 = getopt1.c regex.c getdate.y
SRCS = $(SRC1) $(SRC2) $(SRC3)
OBJ1 = tar.o create.o extract.o buffer.o \
getoldopt.o update.o gnu.o mangle.o
OBJ2 = version.o list.o names.o diffarch.o \
port.o wildmat.o getopt.o
OBJ3 = getopt1.o regex.o getdate.o $(RTAPELIB)
OBJS = $(OBJ1) $(OBJ2) $(OBJ3)
AUX = README COPYING ChangeLog Makefile.in \
makefile.pc configure configure.in \
tar.texinfo tar.info* texinfo.tex \
tar.h port.h open3.h getopt.h regex.h \
rmt.h rmt.c rtapelib.c alloca.c \
msd_dir.h msd_dir.c tcexparg.c \
level-0 level-1 backup-specs testpad.c
.PHONY: all
all: tar rmt tar.info
.PHONY: tar
tar: $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
rmt: rmt.c
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ rmt.c
tar.info: tar.texinfo
makeinfo tar.texinfo
.PHONY: install
install: all
$(INSTALL) tar $(bindir)/$(binprefix)tar
-test ! -f rmt || $(INSTALL) rmt /etc/rmt
$(INSTALLDATA) $(srcdir)/tar.info* $(infodir)
$(OBJS): tar.h port.h testpad.h
regex.o buffer.o tar.o: regex.h
# getdate.y has 8 shift/reduce conflicts.
testpad.h: testpad
./testpad
testpad: testpad.o
$(CC) -o $@ testpad.o
TAGS: $(SRCS)
etags $(SRCS)
.PHONY: clean
clean:
rm -f *.o tar rmt testpad testpad.h core
.PHONY: distclean
distclean: clean
rm -f TAGS Makefile config.status
.PHONY: realclean
realclean: distclean
rm -f tar.info*
.PHONY: shar
shar: $(SRCS) $(AUX)
shar $(SRCS) $(AUX) | compress \
> tar-`sed -e '/version_string/!d' \
-e 's/[^0-9.]*\([0-9.]*\).*/\1/' \
-e q
version.c`.shar.Z
.PHONY: dist
dist: $(SRCS) $(AUX)
echo tar-`sed \
-e '/version_string/!d' \
-e 's/[^0-9.]*\([0-9.]*\).*/\1/' \
-e q
version.c` > .fname
-rm -rf `cat .fname`
mkdir `cat .fname`
ln $(SRCS) $(AUX) `cat .fname`
tar chZf `cat .fname`.tar.Z `cat .fname`
-rm -rf `cat .fname` .fname
tar.zoo: $(SRCS) $(AUX)
-rm -rf tmp.dir
-mkdir tmp.dir
-rm tar.zoo
for X in $(SRCS) $(AUX) ; do \
echo $$X ; \
sed 's/$$/^M/' $$X \
> tmp.dir/$$X ; done
cd tmp.dir ; zoo aM ../tar.zoo *
-rm -rf tmp.dir
As I mentioned earlier, you must be root to edit the /etc/hosts file. It is possible to log on to the machine directly as root, but it is safer to log in as a normal user first, then execute the superuser command
su
in your shell and enter the root password.
If I wanted to add a new static IP to my /etc/hosts file, which looks like
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1 localhost.localdomain centaur localhost
192.168.0.100 groucho
192.168.0.101 harpo
at present, I would go down below the last line and enter the new IP address, then press
Directories
The bin Directory
When the programs has been compiled,it is translated into what's called a Binary format.The bin directory is where all the executables binaries were kept in early Unix.Over time, as more and more executables were added to Unix, it became quite unmanageable to keep all the executables in one place and the bin directory split into multiple parts(/bin/sbin, /usr/bin)
The dev Directory
Among the most important portions of any computer are its device drivers.Without them, you would not have any information on your screen. You would not be able to enter information (the information is read and given to the system by the keyboard device driver).
The etc Directory
Unix adminstration can be quite a complex, invovling management of user accounts, the file system,security,device drivers and more.Unix designates the etc directory as the storage place for all the adminstrative files and information.
The lib Directory
If programs want to include certain features,they can reference just the shared copy of that utility in the Unix library rather than having a new unique copy.Many of the recent Unix systems also support what's called Dynamic Linking, here library of functions are included on- the-fly as you start up the program.
The mnt directory
The mnt directory is an empty directory reserved for mounting removable filesystems like hard disks,removable cartridge drives, and so on.
The tmp Directory
The tmp directory contains temporary files created by Unix system programs. The files are normally present when the corresponding program is running, but may also be left in the directory if the program is prematurely stopped. You can remove any temporary file that does not belong to a running program.
The usr Directory
The usr directory consists of several subdirectories that contain additional Unix commands and data files. It is also the default location of user home directories.
The /usr/bin directory contains more Unix commands. These commands are used less frequently or are considered nonessential to Unix system operation.
The /usr/include directory contains header files for compiling C programs.
The /usr/lib directory contains more libraries and data files used by various Unix commands.
The /usr/spool directory contains various directories for storing files to be printed, mailed, or passed through networks.
The /usr/tmp directory contains more temporary files.
The /usr/adm directory contains data files associated with system administration and accounting. In particular, the /usr/adm/messages and /usr/adm/syslog files contain a record of system error messages, including those sent to the system console. These files are especially useful for locating system problems, including hardware problems. For example, an unusual number of disk errors on a drive indicates a defective or misaligned drive. Because messages in the file can accumulate rapidly, these files must be deleted periodically. See ``Checking and clearing system log files'' for more information.
Hidden Files
A hidden file is any file with a dot as the first character of the filename.They are known as hidden files because they do not show up in a regular ls command and you do not get rid of them with a rm* command. It is common for Unix tools to create "dot" files for temporary files and to maintain control and history information.Users are also expected to create them as configuration files.
These are few files which are hidden :
.profile : this is a configuration file
.login : This is C shell termination file.
.cshrc : This is C shell configuration file.
.history : This is shell command history file.
.mailrc : This is mail configuration file
top of the page
The env Command
System remembers specifics about you using user enviornment.The user environment is a collection of specially named variables that have specific values.
To view your environment type
%env
Commands below are used for various tasks in computer networks.
ftp
file transfer program, anonymous and user-ID versions.ftp stands for File Transfer Protocol. File transfer provides a means for you to obtain computer files (text, image, sound, etc.) from other computers over the network. ftp can also be used to send (upload) files from your computer to another computer, providing you have write permission or a real account on the machine you are uploading. FTP runs on TCP/IP port 21 .
top of the page
telnet
establish a remote connection. Telnet is a utility that allows a computer user at one site to make a connection, login and then conduct work on a computer at another site. For example, you can use the telnet command to run a program in your directory on a supercomputer thousands of miles away. Telnet runs on TCP/IP port 23
top of the page.
ping
Ping command is used to test and time a route to other computer.This sends an echo request to a network host. It is useful for determining the status of the network and various foreign hosts. The ping command sends one datagram per second and prints one line of output for every response received. Round-trip times and packet loss statistics are calculated and displayed. Ping uses the ICMP protocol. This is an IP protocol, so it does not have a port number.
top of the page
traceroute x
Main purpose of traceroute is to test routes to x (address).This is a utility that records the route (the specific gateway computers at each hop) through the Internet between your computer and a specified destination computer. It also calculates and displays the amount of time each hop took. Traceroute also uses the ICMP protocol.
rlogin : remote login
irc : real-time text conversation with other irc users
who : display information on users logged in
ruser : display remote users (old)
dnslookup : display user information from DNS server
ypcat : display user or group information from NIS/YP server
id : display user's ID, name, group and group name
finger : enquire information (.plan) about a user or a node
rup: display information about network machines
nslookup x : look up or set address information
Directories are used to organize your files.Here is the list of directory commands :
mkdir || rmdir || pwd || ls ||cd ||
Ls with options
type % ls -a ls is an example of a command which can take options: -a is an example of an option. The options change the behaviour of the command.
Command flags for ls are as following :
Flag Meaning
-1 Force single-column output on listings.
-a List all files, including any dot files.
-C Force multiple-column output on listings.
-l Generate a long listing of files and directories.
-r Reverse the order of any file sorting.
-R Recursively show directories and their contents.
-s Show size of files, in blocks
-t Sort output in most-recently-modified order.
-x Sort output in row-first order.
Commands to find out where you are
pwd
Prints current directory.Use to check directory in which you are working.
whoami
For people who use multiple IDs, tells you which ID you are using.
ls : Commands to get information about contents of current directory
Use options -l, -a, -t, -g in any combination or order as shown in examples.
ls : Lists files and directories in current directory.
ls -l : Lists files and directories and details about them.
ls -a : Lists files and directories and hidden files.
ls -t : Lists files and directories in order by last modified date.
ls -g : Lists files and directories and which group owns them.
ls -la : Lists files and directories, including hidden files, and gives information about them.
ls -latg :Lists files and directories showing all options.
ls p* :Lists any files in the current directory that begin with the letter p. The asterisk (*) is used as a wild card. It replaces one or more characters in a file name. For example, *p* looks for any file with the letter p anywhere in the name.
Commands to add or delete directories or files
mkdir directory1 : Makes a directory and names it directory1.
rmdir directory1 : Removes the directory named directory1. (Note: You cannot remove a directory unless it is empty.)
mv file1 file2 : Moves file1 into file2. If file2 has not been created, it creates file2 and moves the contents of file1 into it. If file2 exists, its contents are replaced by the contents of file1. In all cases, file1 no longer exists. mv file1 directory_name Moves the file named file1 into the directory named.
cp file1 file2 : Copies the contents of file1 into file2. Leaves file1 as is.
Permissions and Ownerships
There are three primary types of permission for files: read,write and execute.If no letter is present then it is substituted by a dash -. The dash means that this type of permission is not granted whether it be in the r, w or x position.The first column is broken down into four sub columns. The first sub column is one character long the second, third and fourth are all three characters long for a total of ten characters.The table below is a reflection of the four columns.
File/Directory User Group Other
d rwx r-x r--
The most common file permissions are
Permission Meaning
--- No access is allowed
r-- Read only access
r-x Read and execute access, for programs and shell scripts
rw- Read and write access, for files
rwx All access allowed, for programs
If the permission of the directory is write then you can add new items and remove items in the directory.
chmod command enables you to specify permissions in two different ways.
type %chmod [permission level] name_of _file.
Check option buttons
Common permissions and their numeric equivalents
Permission Numeric Used with
---|---|--- 000 All types
r--|---|--- 400 Files
r--|r--|r-- 444 Files
rw-|---|--- 600 Files
rw-|r--|r-- 644 Files
rw-|rw-|r-- 664 Files
rw-|rw-|rw- 666 Files
rwx|---|--- 700 Programs and Directories
rwx|r-x|--- 750 Programs and Directories
rwx|r-x|r-x 755 Programs and Directories
%grep 'jon' /etc/passwd
to search the /etc/passwd file for any lines containing the string "jon".
Type the command
% grep '^jon' /etc/passwd
to see the lines in /etc/passwd that begin with the character string "jon".
Ls -l | grep ‘jon’
Compiling C Programs:
Compiling single source C Programs
The easiest case of compilation is when you have all your source code set in a single file.Let us illustrate with an example test.c program:
#include
int main(int argc, char* argv[]) {
printf ("hello world\n");
return 0; }
There is a file named 'test.c' that we want to compile. We will do so using a command line similar to this:
%gcc test.c
We are using a GNU compiler, you'll write 'gcc' instead. If you program complies well you should get a file 'a.out' as a result.
Suppose that you want the resulting program to be called "test_output". In that case, you could use the following line to compile it:
%gcc test.c -o test_output
Here -o flag indicates name of the resulting executable file(test_output).
Running the resulting program
Once we created the program, we wish to run it. This is usually done by simply typing its name, as in: test_output.
If we define a function (or a variable) in one file, and try to access them from a second file, we need to declare them as external symbols in that second file. This is done using the C "extern" keyword. The order of presenting the source files on the command line may be altered. The compiler (actually, the linker) will know how to take the relevant code from each file into the final program, even if the first source file tries to use a function defined in the second or third source file.
%gcc -c a.c
%gcc main.o a.o b.o -o hello_world
In our small example, it's hard to notice the speed-up, but in a case of having few tens of files each containing a few hundred lines of source-code, the time saving is significant; not to mention even larger projects
Getting a Deeper Understanding - Compilation steps
Now that we've learned that compilation is not just a simple process, lets try to see what is the complete list of steps taken by the compiler in order to compile a C program.
Driver -
what we invoked as "cc". This is actually the "engine", that drives the whole set of tools the compiler is made of. We invoke it, and it begins to invoke the other tools one by one, passing the output of each tool as an input to the next tool.
C Pre-Processor -
normally called "cpp". It takes a C source file, and handles all the pre-processor definitions (#include files, #define macros, conditional source code inclusion with #ifdef, etc.) You can invoke it separately on your program, usually with a command like:
%gcc -E single_source.c
The C Compiler -
normally called "cc1". This is the actual compiler, that translates the input file into assembly language. As you saw, we used the "-c" flag to invoke it, along with the C Pre-Processor, (and possibly the optimizer too, read on), and the assembler.
Optimizer -
sometimes comes as a separate module and sometimes as the found inside the compiler module. This one handles the optimization on a representation of the code that is language-neutral. This way, you can use the same optimizer for compilers of different programming languages.
Assembler -
sometimes called "as". This takes the assembly code generated by the compiler, and translates it into machine language code kept in object files. With gcc, you could tell the driver to generated only the assembly code, by a command like: cc -S single_source.c
Linker-Loader -
This is the tool that takes all the object files (and C libraries), and links them together, to form one executable file, in a format the operating system supports. A Common format these days is known as "ELF". On SunOs systems, and other older systems, a format named "a.out" was used. This format defines the internal structure of the executable file - location of data segment, location of source code segment, location of debug information and so on. As you see, the compilation is split in to many different phases. Not all compiler employs exactly the same phases, and sometimes (e.g. for C++ compilers) the situation is even more complex. But the basic idea is quite similar - split the compiler into many different parts, to give the programmer more flexibility, and to allow the compiler developers to re-use as many modules as possible in different compilers for different languages (by replacing the preprocessor and compiler modules), or for different architectures (by replacing the assembly and linker-loader parts).
Compiling Single-Source C++ Program
All we need to do is use a C++ compiler, in place of the C compiler . So, if our program source is in a file named 'test.cpp' .
#include
int main(int argc, char* argv[]) {
cout << "hello world" << endl;
return 0; }
We will use a command such as the following
% g++ test.cpp -o test_output
SHELL
Whenever you login to a Unix system you are placed in a program called the shell. You can see its prompt at the bottom left of your screen.(i.e Paris).To get your work done, you enter commands at this prompt. The shell acts as a command interpreter; it takes each command and passes it to the operating system kernel to be acted upon. It then displays the results of this operation on your screen.
Following are few of the features of the shell :
Create an enviornment
Working environment is defined whenever you login or start another shell. This environment is set using the values that the shell finds in initialisation files which it always reads as it starts up. You can change your working environment by editing these files and setting new values for variables. Each shell handles its initialisation files in a different way.
Frequently used Environment Variables
Name Description
EDITOR Sets the editor that will be used by other programs such as the mail program.
PATH Specifies the directories that the shell is to look through to find a command. These directories are searched in the order in which they appear.
HOME The HOME variable contains the name of your home directory. When you issue the cd command with no directory argument, you will be placed in the directory defined in the HOME environment variable. The HOME variable is also where the shell will look for the user login scripts
PRINTER Sets the printer to which all output is sent by the lpr command
SHELL Sets your default shell.
MAIL The MAIL variable contains the name of the directory where your incoming mail is stored. When you start a mail program, the program will look in the directory stored in the MAIL environment variable for your incoming mail messages.
TERM Sets your terminal type for programs such as the editor and pager.
USER The USER variable contains your username. Any time you access a file or directory, the access permissions are checked against the value of USER
TZ Sets the time zone you are in.
Finding out which shell you are using
Information about which shell you are using is held in the SHELL environment variable.The command
echo $SHELL
displays the value of this variable. You can identify which shell you are presently using from the last part of the pathname.
Pathname Shell
/.../sh Bourne shell
/.../csh C shell
/.../tcsh TC shell
/.../ksh Korn shell
/.../bash Bourne Again shell
To view all the environment variables,use the command printenv
Changing your environment :Bourne shell
At login the Bourne shell reads the initialisation files /etc/profile and $HOME/.profile. You cannot change the content of /etc/profile, but you have permission to edit the contents of .profile, which is in your home directory and is owned by you.
Useful tip : Make a copy of your shell start up file before editing it to change environment or shell variables. You can always return to using this copy if you find that the modified file is not working and you are unable to fix the problem.
For example:
cd
cp .profile old_profile
pico .profile
The first command changes you to your home directory, where a copy of the file .profile is made in old_profile. You can then edit the .profile.
To revert to using the original .profile you simply copy it back. For example:
cp old_profile .profile
Displaying current variables
You can use the echo command to display the value of an environment variable. For example:
echo $PATH
This displays the value of the environment variable PATH. The name of an environment variable is given in UPPER CASE. The $ sign is a shell metacharacter that uses the value of the variable instead of its name. The method for displaying the value of every variable varies according to which shell you are using.
For the Bourne shell use the command set to display the value of environment variables.
For the C and TC shell use the command printenv or env to display the value of environment variables and the command set to display the value of local shell variables.
If the list of variables is so long that it scrolls off the screen and you want to display the information one screenful at a time, pipe the output through a pager. For example:
set | more
Setting environment and shell variables
csh
To set an environment variable in csh, use the setenv command. The command has the syntax: setenv VARIABLE value. To set the EDITOR variable to the value emacs in csh, use the command: setenv EDITOR emacs.
sh, or ksh
To set an environment variable in sh or ksh, use the syntax VAR=value;export VAR, where VAR is the name of the environment variable and value is the value you wish to assign. Do not put spaces on either side of the equals sign. The export command instructs the shell to propagate the value of the variable to all programs that are run by the shell. If an environment variable is reset, but not exported, the change will only apply to the shell itself. To set the EDITOR variable to the value emacs in ksh or sh, use the command:
EDITOR=emacs;export EDITOR
It is also possible to unset environment variables, with the unset command. Unsetting an environment variable removes the definition of the variable.
Command to enter vi edit mode
vi filename (press Enter/Return key) : Opens the named file if it exists, or creates new file and opens it.
Commands to move the cursor
k j l h (lowercase)
These keys move the cursor one line above, one line below, one space right, or one space left respectively.
Commands to put you in text insert mode
Note: After inserting text, press Esc (escape) key to return to command mode.
a (lowercase)
Use to insert (append) text to the right of cursor.
A (uppercase)
Use to insert (append) text at the end of the current line.
i (letter i (eye) lowercase)
Use to insert text to the left of cursor.
I (letter I (eye) uppercase)
Use to insert text at the beginning of the current line.
o (letter o lowercase)
Use to open a new line for inserting text below cursor line.
O (letter O uppercase)
Use to open a new line for inserting text above cursor line.
Commands to delete text
x (lowercase)
Removes the character under the cursor.
dd (lowercase)
Deletes the cursor line.
Command to join two lines
J (uppercase)
Joins next line to the end of the cursor line.
n (lowercase)
Searches in direction of original /keyword, ?keyword, /string, or ?string command. Locates next instance of keyword or string.
N (uppercase)
Searches in opposite direction of original /keyword, ?keyword, /string, or ?string command. Locates next instance of keyword or string.
Y (uppercase)
Yanks (copies) line the cursor is on.
p (lowercase)
Puts last word or line yanked or deleted after cursor.
P (uppercase)
Puts last word or line yanked or deleted before cursor.
Command to recover from last change
u (lowercase)
Undoes last change.
Commands to save changes or leave vi editing session
:w (colon and lowercase w)
Saves changes, but does not leave vi editing session.
:wq (colon and lowercase wq)
Saves changes, and leaves vi editing session.
ZZ (uppercase)
Saves changes, and leaves vi editing session.
:q! (colon, lowercase q, and exclamation)
Does not save changes made. Just leaves vi editing session.
