Professional Documents
Culture Documents
Prog I
Prog I
command which:
automates program construction and linking
tracks dependencies
keeps things up-to-date after changes
to use it:
construct a file with rules in it
you can call it anything, but makefile is the default
run make itself
make target
(uses the default makefile)
make -f myfile target
(uses the rule file myfile)
either rebuilds the program target if necessary
each makefile consists of:
definitions
rules
rules say how one thing depends on another
they are either:
specific e.g. to make mail-client do this ...
generic e.g. to make any .o from its .c ...
make is also available in many other programming environments
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/22
makefile format
Definitions
general form:
variable = value
example:
SDIR = tcp
MYLIBS = $(SDIR)/lib
N.B. one variable used in another's definition
make variables are referred to later using $
e.g. $(SDIR), $(MYLIBS)
expanded like #defines or shell variables
(some versions of make will expand shell variables also)
Rules (just specific rules)
general form:
target : dependent1 dependent2 ...
command-line
N.B. this must be a tab
example:
myprog: myprog.o another.o
cc -o myprog myprog.o another.o $(MYLIBS)
this says:
to make myprog you need myprog.o and another.o
if either of them is newer than myprog rebuild it using the
then rebuild it using the command: cc -o myprog ...
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/23
argc & argv
int main( int argc, char **argv ) ...
or: int main( int argc, char *argv[] ) ...
one of the ways to get information into a C program
in UNIX you type:
myprog a "b c" d
the program gets:
argc = 4 length of argv
argv[0] = "myprog" program name
argv[1] = "a"
argv[2] = "b c" single second argument
argv[3] = "d"
argv[4] = NULL terminator
N.B. DOS is identical (except argv[0] is NULL early versions)
argc is one less than the number of arguments!
other ways to get information in (UNIX & DOS):
configuration file (known name)
standard input
environment variables using getenv()
or (UNIX only) third arg to main:
main(int argc, char **argv, char **envp)
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/24
environment variables
set of name=value mappings
most created during start-up (.profile, .login etc.)
setting a variable from the shell:
myvar=hello
var2=" a value with spaces needs to be quoted"
export myvar
no spaces before or after '=' sign
variables need to be exported to be seen
by other programs run from the shell
in C shell: "set name=val" and no export
listing all variables from the shell:
$ set
HOME=/home/staff2/alan
myvar=hello
PATH=/local/bin:/bin:/local/X/bin
USER=alan
. . .
$
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/25
environment variables 2
accessing from a program 3 methods
' extra argument to main
main(int argc,char **argv,char **envp)
Z global variable
extern char **environ
system function
char *value = getenv(name);
both ' and Z give you a structure similar to argv
a null terminated array of strings
but environment strings are of the form
name=value
the getenv function rather different
fetches the value associated with name
returns NULL if name not defined
also a putenv function
only available to this process and its children
not visible to the shell that invoked it
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/26
Hands on
write a program to produce a list of arguments as in
the 'argc & argv' slide
the core of your program will look something like:
for(i=0; i<argc; i++)
printf("argv[%d] = %s\n",argv[i]);
if you use cc then the main program begins:
main(argc,argv)
int argc;
char **argv;
the slide shows the ANSI C declaration
do a similar program for environment variables
UNIX
Systems
ProgrammingI \Short Course Notes Alan Dix 1996 I/27
UNIX
Systems
Programming
I
Session 4
file manipulation
creating new files
deleting files
linking to existing files
symbolic links
renaming files
creating/removing directories
using it
UNIX
Systems
ProgrammingI \Short Course Notes Alan Dix 1996 I/28
creating files
int fd = creat(path,mode)
char *path the name/path of the (new) file
int mode permissions for the new file
int fd returns a file descriptor
file is created if it doesnt exist
if it already exists, acts like an open for writing
negative return on failure
mode sets the initial permissions, e.g.
mode = S_RWXUSR | S_IRGRP | S_IXGRP | S_IXOTH
read/write/execute for user (S_RWXUSR)
read/execute for group (S_IRGRP | S_IXGRP)
execute only for others (S_IXOTH)
when created, file descriptor is open for writing
+ even if permissions do not include write access
alternative use open with special flags:
int fd = open( path, O_WRONLY|O_CREAT|O_TRUNC, mode )
O_CREAT flag says create if it doesnt exist
note extra mode parameter
UNIX
Systems
ProgrammingI \Short Course Notes Alan Dix 1996 I/29
deleting files
UNIX rm command deletes files
it uses the unlink system call
int res = unlink(path)
char *path the name/path of the file to remove
int mode permissions for the new file
int res returns an integer 0 OK
-1 fail
doesnt necessarily delete file!
but neither does rm
UNIX filenames are pointers to the file
there may be more than one pointer
UNIX
Systems
ProgrammingI \Short Course Notes Alan Dix 1996 I/30
hard links
linking to an existing file:
shell ln tom fred
system call link("tom","fred")
file tom must already exist
fred points to the same file as tom
tom fred
unlink simply removes a pointer
file destroyed only when last link goes
UNIX
Systems
ProgrammingI \Short Course Notes Alan Dix 1996 I/31
symbolic links
hard links are limited:
cannot link to a different disk
only one link to a directory
(actually not quite true as there are all the .. links)
symbolic links are more flexible
shell ln -s tom fred
system call symlink("tom","fred")
tom need not exist
fred points to the name tom an alias
tom fred
UNIX
Systems
ProgrammingI \Short Course Notes Alan Dix 1996 I/32
links and updates
cp fred tom ln fred tom ln -s fred tom
fred tom
tom fred tom fred
update file tom
fred tom
tom fred
tom fred
delete file tom unlink("tom")
fred tom
tom fred tom fred
what is in fred?
fred
fred
? fred
UNIX
Systems
ProgrammingI \Short Course Notes Alan Dix 1996 I/33
renaming files
int res = rename(path1,path2)
char *path the name/path of the (new) file
int fd returns a file descriptor
system call used by UNIX mv command
only possible within a file system
' path2 is unlinked
Z path2 is linked to the file pointed to by path1
path1 is unlinked
result: path2 points to the file path1 used to point to
e.g. rename("fred","tom")
fred tom fred tom
UNIX
Systems
ProgrammingI \Short Course Notes Alan Dix 1996 I/34
directories
special system calls
to create and remove directories
int res = mkdir(path,mode)
char *path the path of the new directory
int mode permissions for the new directory
int res returns an integer 0 OK
-1 fail
mkdir rather like creat
int res = rmdir(path)
char *path the path of the directory to remove
int res returns an integer 0 OK
-1 fail
unlike unlink does delete directory!
but only when empty
UNIX
Systems
ProgrammingI \Short Course Notes Alan Dix 1996 I/35
Hands on
rm has various options
so it is hard to delete files with strange names
such as -b I know I got one once!
write a program raw-rm.c which has one command
line argument, a file to delete, and performs an
unlink system call on it
modify raw-rm so that it can take a list of files:
raw-rm tom dick harry
write a version of mv that doesnt use the rename
system call, but only link and unlink
N.B. if you get the order wrong youll loose the file!
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/36
UNIX
Systems
Programming
I
Session 5
terminal I/O
terminals are just files?
tty drivers
stty and gtty
handling input
the termcap database
toolkits
using it
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/37
terminals are easy?
terminal is default input/output
read and write just like any file
use read/write system calls
or stdio
interactive programs a doddle
printf("what is your name? ");
gets(buff);
printf("hello %s how are you today\n",buff);
v get line editing for free
paper-roll model of interaction
only see user input in whole lines
terminals not quite like other files:
write anywhere on screen
cursor movement
special effects (flashing, colours etc.)
non-standard keys: ctrl, alt, F3 etc.
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/38
tty drivers
never connected directly to terminal
tty driver sits between
does line editing
handles break keys and flow control
(ctrl-C, ctrl-\, ctrl-S/ctrl-Q)
translates delete/end-of-line chars
not always wanted!
your
program
tty driver
UNIX kernal
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/39
stty command
control the tty driver from the shell
$ stty everything
$ stty -echo
$ < type something no echo>
$ reset
stty differs between UNIXs!
can control
echoing
parity, stop bits etc. for modems
carriage return / newline mapping
delete key mapping (delete/backspace)
break key activity
line editing
. . . and more
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/40
gtty & stty functions
you can do the same from a program
#include <sgtty.h>
int echo_off(tty_fd)
int tty_fd;
{
struct sgttyb buf;
gtty(tty_fd,&buf);
buf.sg_flags &= ~ECHO;
return stty(tty_fd,&buf);
}
sg_flags a bitmap of option flags
the sgttyb structure has other fields
line speeds ( sg_ispeed, sg_ospeed )
erase and kill chars ( sg_erase, sg_kill )
(word and line delete)
gtty and stty depreciated now
more options available through ioctl
but they are the traditional UNIX calls
and simpler!
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/41
raw, cbreak and cooked
normal tty processing
echoing of all input
some output translation
line editing
break characters
called cooked mode
visual programs do not want this
use stty or ioctl to control
raw mode
buf.sg_flags |= RAW;
suppress all input and output processing
echoing still occurs use ECHO bit
cbreak (half-cooked) mode
buf.sg_flags |= CBREAK;
as for raw
but break key (ctrl-C) enabled
remember to save and reset the mode!
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/42
handling input
with raw & cbreak
dont have to wait for a line end
get characters as they are typed
including delete key
key input mapping?
simple for ascii keys: A key a etc.
others single char: backspace 0x8
some lots i key ESC [A
prefixes
one key may be a prefix of another!
e.g. function key F3 ESC[19~
escape key ESC
you read ESC
? how do you know which key
solutions
' wait for next character
could wait a long time!
Z assume that the whole code is read at once
not always true
as ' but with timeout
best solution
introduces delays
may still fail (swopped out)
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/43
termcap
different kinds of terminals
different screen sizes (80x25?)
different capabilities (flashing, underline, ...)
different keyboards
different screen control characters
how do you know what to do?
write terminal specific code
v use termcap
' environment variable TERM
gives terminal type e.g. vt100, vt52 etc.
Z /etc/termcap database
gives capabilities and codes for each type
d0|vt100|vt100-am|vt100am|dec vt100:\
:do=^J:co#80:li#24:cl=50\E[;H\E[2J:sf=5\ED:\
:le=^H:bs:am:cm=5\E[%i%d;%dH:nd=2\E[C:up=2\E[A:\
< 7 more lines! >
each item gives a code/capability
e.g. do=^J send ctrl-J to move cursor down
co#80 80 columns
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/44
termcap library
read /etc/termcap directly?
termcap library has functions to help
cc -o my-vis my-vis.c -ltermcap
tgetent(val,tname)
get the info for terminal tname
tgetnum(id)
return the number for capability id
tgetflag(id)
test for capability id
tgetstr(id)
return the string value for id
tgoto(code,col,line)
generate a cursor addressing string
tputs(str,lines_affected,output_f)
outputs with appropriate padding
not exactly a high-level interface
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/45
curses and toolkits
various high-level toolkits available
e.g. curses, C-change
curses is the UNIX old-timer!
cc -o my-cur my-cur.c -lcurses -ltermcap
many functions including:
initscr() & endwin()
start and finish use
move(line,col)
cursor positioning
printw(fmt, ...)
formatted output
mvprintw(line,col,fmt, ...)
both together!
mvgetch(l,c), mvgetstr(l,c,buf)
read user input
mvinch()
read screen
clear(), refresh()
clear and refresh screen
cbreak(), nocbreak(), echo(), raw(),
setting terminal mode
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/46
Hands on
use stty at the shell to set echo, cbreak and raw
$ cat
< type a few lines to see what it normally does >
^D
$ stty cbreak
$ cat
< type a bit >
^D
$ stty raw
$ echo hello
use cat to see what codes your terminal produces
$ cat
< type lots of keys and things >
^D
$
try entering and running the following:
#include <curses.h>
main()
{
initscr();
clear();
mvprintw(10,30,"hello world!");
move(20,5);
refresh();
endwin();
}
what happens if you leave out the refresh() call
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/47
UNIX
Systems
Programming
I
Session 6
signals and time
what are signals
the signal system call
problems of concurrency
finding the time
going to sleep
using it
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/48
signals
interacting with the world
file/tty input what
signals when
signals happen due to:
errors
SIGFPE floating point error
SIGSEGV segment violation
(usually bad pointer!)
interruptions
SIGKILL forces process to die
SIGINT break key (ctrl-C)
things happen
SIGALRM timer expires
SIGCHLD child process has died
I/O event
SIGURG urgent data from network
SIGPIPE broken pipe
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/49
catching signals
default action for signals
some abort the process
some ignored
you can do what you like
so long as you catch the signal
and its not SIGKILL (signal 9)
' write the code that you want run
int my_handler()
{
my_flag = 1\n;
}
Z use the signal system call to tell UNIX about it
signal(SIGQUIT,my_handler);
when the signal occurs UNIX calls my_handler
J when you no longer require a signal to be caught
signal(SIGQUIT,SIG_IGN);
signal(SIGFPE,SIG_DFL);
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/50
care with signals
signal handlers can run at any time
int i = 0;
int my_handler()
{
i = i + 1;
}
main()
{
signal(SIGINT,my_handler);
for(;;)
if ( i > 0 ) {
do_something();
i = i - 1;
}
}
intention:
execute do_something once per interrupt
what actually happens:
' interrupt processed (i=1)
Z do_something executes
main calculates i-1 gets result 0
J before it stores the result . . .
. . . another interrupt (i=2)
main stores result (i=0)
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/51
working with time
processes need to tell the time
absolute time: 15:17 on Thursday 21st March
elapsed time: that took 3.7 seconds
and time their actions
delays: wait for 5 seconds
alarms: at 11.15pm do the backup
delays easy
sleep(t) system call
waits for t seconds
at least!
sleep(5); /* waits for at least 5 seconds */
cannot guarantee time
other processes may be running
not a real-time operating system
alarms covered in UNIX Systems Programming II
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/52
finding the time
UNIX time started on 1st January 1970!
time system call returns seconds 1/1/1970
#include <sys/types.h>
#include <sys/time.h>
time_t t = time(NULL);
ftime gives you milliseconds and timezone too
#include <sys/timeb.h>
struct timeb tmb;
int res = ftime(&tmb);
the process does not run all the time
clock gives cpu time used in secs
long cpu_t = clock();
N.B. times gives you more information about cpu usage
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/53
telling the time
users dont measure time in seconds since 1/1/1970!
collection of functions to do conversions
between four time formats
' seconds since 1/1/1970
Z struct timeb (from ftime)
struct tm (gives year, day, hour etc.)
J ascii representation as C string:
"Sun Sep 16 01:03:52 1973\n"
' localtime, gmtime
J asctime
' J ctime
' timelocal, timegm
also dysize(yr) number of days in year yr
local variants give local time
gm variants give Greenwich Mean Time
see man 3 ctime for more details
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/54
Hands on
write a program to see how lazy sleep is!
it should:
' get the time using both clock and time
Z print both
do a sleep(5)
J get the times again
and print them
run it several times and record the results
printing at Z adds a delay,
modify the above plan to make it right
and also get it to print the time elapsed as
measured by clock and time
run this version and compare results with the first
try the program in the care with signals slide
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/55
UNIX
Systems
Programming
I
Session 7
mixing C and scripts
shell scripts
what are they good for?
information shell C
results C shell
example
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/56
shell
the shell is a programming language
data:
environment variables (character strings)
whole files
control flow:
similar + special features
procedures:
shell scripts
shell and C:
shell:
v good at manipulating files and programs
slow for intensive calculation
C:
v fast and flexible
longer development cycle
use them together
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/57
shell scripts
shell scripts are files:
' starting with:
#!/bin/sh
Z containing shell commands
made executable by
chmod a+x
executed using a copy of the shell
$ cat >my-first-script
#!/bin/sh
echo hello world
$ chmod a+x my-first-script
$ my-first-script
hello world
$
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/58
its good to talk
shell and C need to communicate
shell C
standard input:
large amounts of data
command line arguments:
file names, options
environment variables:
long-term preferences & settings
C shell
standard output:
large amounts of data
standard error:
normally only to the user
exit code:
success/failure or single number
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/59
shell C
standard input
not just files!
single line use echo and pipe
echo hello | myprog
lots of lines use HERE file
my-prog <<HERE
this is two lines
> of text
> HERE
command line arguments
shell pattern matching is great
let it check and pass good args in
environment variables
inwards only!
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/60
C shell
standard output
redirect to file
my-prog some-args > fred.out
pipe it
my-prog some-args | more-progs
or use backquotes!
myvar=`my-prog some-args`
exit code
remember: 0 = success
use if, while etc.
if my-prog some-args
then
echo OK
else
echo failed
fi
or use $?
my-prog some-args
echo returned $?
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/61
example
the following numc.c is a filter for numbering lines
#include <stdio.h>
char buff[256];
main()
{
int lineno;
for ( lineno=1; gets(buff); lineno++ )
printf("%4d: %s\n",lineno,buff);
}
we would like to give it arguments
$ numc fred
1: freds first line
2: the second line of fred
too much work!
v use a shell script
well call it num
#!/bin/sh
case $# in
0) numc; exit 0;; # filter mode
esac
for i # loops through all arguments
do
echo; echo "---- $i ----"
numc <$i
done
UNIX
Systems
ProgrammingI Short Course Notes Alan Dix 1996 I/iii
random access