SysIII/usr/src/man/docs/c_lib

.ds u \s-1UNIX\s+1
.ds t \s-1UNIX/TS\s+1
.ds g \s-1\GCOS\s+1
.CD -l~ -r~
.de CW
.DS I
.ps 9
.vs 10.5p
.ta 16m/3u 32m/3u 48m/3u 64m/3u 80m/3u 96m/3u 112m/3u 128m/3u 144m/3u 160m/3u
..
.de CN
.ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i
.ps
.vs
.DE
..
.de Ex
.ti 0
.I \s10Example:\s0
.P
..
.de Li
.br
.ne 3.6v
.SP 0.5v
.lg 0
.bd R 3
.LI "\&\\$1"
.br
.bd R
.sp -1v
.ft 2
.nf
..
.de IL
.fi
.lg
.ft 1
.P
..
.de HY
.ne 5.1v
.bd R 3
.bd S R 3
..
.de HZ
.bd R
.bd S
..
.ds HP 10 10 10 10 10 10 10
.ds HF 1 1 2 2 2 2 2
.nr Hu 1
.bd S 3 3
.PH "''''"
.br
.ds :? C Library
.OH "'\s9\f2\*(:?\fP''\\\\nP\s0'"
.EH "'\s9\\\\nP''\f2\*(:?\^\fP\s0'"
.rs
.ce 1000
.ps 12
.vs 14p
.bd R 3
A Guide to the C Library for U\s-2NIX\s+2 Users
.bd R
.ps
.vs
.sp .5v
.I "C.\ D.\ Perez"
.sp .5v
Bell Laboratories
Murray Hill, New Jersey 07974
.sp 1v
.ce 0
.P
.H 1 "INTRODUCTION"
The C language on the \*u\(dg
.FS \(dg
UNIX is a Trademark of Bell Laboratories.
.FE
system has been traditionally provided with a rich supply
of often-used routines formed into
libraries selectable at load time.
When the interest in portability heightened,
the C library kept pace with other software being modified,
and the library known as
.I /lib/libS\s+4.\s-4a\^
superseded the older attempts at portability [1].
This new library [2]
concentrated on input-output functions that removed the
user from close contact
with operating-system features.
It also introduced new string functions
and some memory-allocation routines.
The Bell Laboratories C Standards Task Force has been responsible for many of the ideas
incorporated into the C library and reflected in this document.
As the C compiler finds its way onto other hardware
and becomes available on different operating systems,
the C Task Force continues to provide a forum for the exchange of
information on the needs of the various users.
.P
It is to the advantage of the C programmer
to become acquainted with the C library functions
and to keep up-to-date with new versions.
To select routines from the C library is to choose available code that has
been tuned for portability and efficiency.
This document is meant to acquaint the programmer with
a selection of functions from the C library that are commonly
used and to point out differences among functions, special features,
and occasionally precautions about function usage.
The veteran user of the C library will find in this compendium an
update to previously published information about the library.
.P
Section\ 2 describes the current
changes and additions to
the contents of
.I /lib/libS\s+4.\s-4a\^
since the Ritchie document was published.
The bulk of the information appears in Attachment\ A, which is intended to be a
user's reference tool.
Function descriptions appear alphabetically
within logical groupings.
Where it seems helpful, examples are supplied.
The values returned by the functions are identified
in a way that suggests their use in portable code.
The content and form of the functions as described here match
the C library at the time of the distribution of \*t
Edition\ 1.1,
unless otherwise specified.
Attachment\ B contains the contents of the
header files used by many of the C library
functions.
Attachments\ C and D, the
.I printf (3S)
and
.I scanf (3S)
manual entries from the
.I "U\s-1NIX/TS\s+1 User's Manual\^"
[3],
are included for convenience.
.P
.H 1 "UPDATE INFORMATION"
.P
.H 2 "General"
The standard library
.I /lib/libS\s+4.\s-4a\^
no
longer exists separate from the rest of the C library;
these routines have been incorporated into
the standard \*u C library,
.I /lib/libc\s+4.\s-4a\^
This library encompasses
input-output functions, routines for character type
recognition
and translation,
space allocation, file status
and a few miscellaneous routines of general use
as well as many functions specific to the operating system.
.P
Three files exist with definitions of constants, and
macros that are used by many of the C library functions.
.I Stdio\s+4.\s-4h\^
contains the definitions of ~NULL~, ~EOF~, ~FILE~, and ~BUFSIZ~.
The standard input file (\f2stdin\fP), standard output
file (\f2stdout\fP), and standard error file (\f2stderr\fP)
are also defined there.
These are included in a program with
~#include <stdio.h>~.
The file
.I ctype\s+4.\s-4h\^
provides the macro definitions for the variety of character classifications that
is now possible.
Any program using those facilities must contain the line
~#include <ctype.h>~.
The functions that handle signals need to include the
signal definitions.
This can be done with
~#include <signal.h>~.
See Attachment\ B.
.H 2 "Space Allocation".
.I Calloc\^
was designed to be used for acquiring space initialized to zero;
.I malloc\^
is now available to allocate a chunk of uninitialized
space, and
.I realloc\^
to change the size of an
already allocated amount of space.
.I Cfree\^
has been renamed
.I free ,
and returns space acquired by any of the above three functions.
.H 2 "Input-Output Functions"
The function
.I fopen\^
may now be supplied with new options
that allow updating of a file (~r+~, ~w+~, ~a+~).
An added routine
.I fdopen\^
acts as a bridge between the low-level \*u
input-output functions and the ``standard'' technique of
opening a stream.
.I Printf\^
provides more versatile formatting.
For operating systems that support the concept of
.I pipes ,
and the
.I shell ,
the functions
.I popen\^
and
.I pclose\^
add a facility for creating a pipe between the calling process and
a command supplied as the argument.
.H 2 "Status"
To acquire information about a file,
.I feof ,
.I ferror ,
and
.I f\&ileno\^
have been available.
Now
a function named
.I clearerr\^
is added.
It resets the error condition
indicated by
.I ferror\^
while the stream remains open.
.H 2 "Character Types"
New macros added to the collection in
.I ctype\s+4.\s-4h\^
are
.I isalnum\^
(alphanumeric test),
.I ispunct\^
(for recognizing punctuation characters),
.I iscntrl\^
(to identify certain control characters)
.I isascii\^
(to find \s-1ASCII\s+1 characters)
and
.I isgraph\^
(having visible graphic representation).
.I Toascii\^
can be used to translate characters into \s-1ASCII\s+1;
.I toupper\^
and
.I tolower\^
are useful in changing the case of a letter.
.H 2 "Some Conventions"
When the overhead of a function call could be substantial, because
the routine suggests repetitive use, it is likely to have
been implemented as a macro.
.I Getchar\^
is an illustration of this.
Any ``function'' coded as a macro is noted in its description.
In these cases the user should beware of the hazards of
macro expansion on complex arguments.
Cases should be avoided where
arguments are automatically incremented or decremented,
are evaluated more than once, contain their own
macros or function calls,
or whose order of operations is unclear after expansion.
In short, only simple arguments are safe to use with macros.
In a few cases the C library provides both a
function call and a faster macro version
to perform a similar task.
.P
Some function names have changed in order to follow the established
convention.
To insure that the uniqueness of function names is preserved even if truncation occurs
on some systems, those functions
dealing with entire strings are named
.I str\|.\|.\|.\| ;
those functions that consider only the
first
.I n\^
characters of a string are named
.I strn\|.\|.\|.\| .
.H 2 "Other Additions"
Software signals are implemented by two functions,
.I gsignal\^
and
.I ssignal ,
to generate and catch error conditions respectively [4].
This facility allows the user to raise
signals to be handled in whatever
way seems useful;
the C Library code will eventually raise signals
so that calling programs, such as \*u commands,
might be enhanced to respond to such signals.
.P
.I Tmpnam\^
can be used to create a name for a temporary file.
.I Ctermid\^
retrieves the terminal identifier from the system, while
.I cuserid\^
retrieves the user \s-1ID\s+1.
In each of these three functions,
the user may choose to
supply space for the safe storage of that name, or accept an internal storage place
of suitable size.
.P
.I Tmpf\&ile\^
provides an unnamed temporary file that continues
in existence until the termination of the process that requested it.
This function is implemented in \*t Edition 1.2.
.H 1 "ACKNOWLEDGMENTS"
.P
The author is grateful to J. F. Maranzano and L. Rosler for their careful
reading of this document, and to A. R. Koenig for
his help during its preparation.
T. A. Dolotta helped to format this document.
.H 1 "REFERENCES"
.RL
.LI
Lesk, M. E.,
.I "The Portable C Library,\^"
Bell Laboratories (May 1975).
.LI
Ritchie, D. M.,
.I "A New Input/Output Package,\^"
Bell Laboratories (May 1977).
.LI
Dolotta, T. A., and Olsson, S. B. (eds.),
.I "U\s-1NIX/TS\s+1 User's Manual\*(EMEdition 1.1,\^"
Bell Laboratories (Jan. 1979).
.LI
Koenig, A. R.,
``A Proposal for Software Signals,''
private communication (Apr. 14, 1978).
.LE
.sp 1v
.I "May 1979"
.bp
.ce
.bd R 3
Attachment\ A
.sp 1.5v
.bd R
.ce
.I "COMMON\ \|C\ \|LIBRARY\ \|FUNCTIONS"
.sp .5v
.HU "FILE ACCESS"
.VL 11
.Li fclose
#include <stdio.h>
int fclose(stream)
FILE \(**stream;
.IL
.I Fclose\^
closes a file that was opened by
.I fopen ,
frees any buffers after emptying them, and returns zero on success,
non-zero on error.
.I Exit\^
calls
.I fclose\^
for all open files as part of its processing.
.Li fdopen
#include <stdio.h>
FILE \(**fdopen (fildes, type)
int fildes;
char \(**type;
.IL
.I Fdopen\^
is used strictly on \*u systems and therefore is not
a portable
function.
Its value is in providing a bridge between the low-level
input-output (\s-1I/O\s+1) facilities of \*u and the standard \s-1I/O\s+1 functions.
.I Fdopen\^
associates a stream with a valid file descriptor obtained from
a \*u system call
(e.g.,
.I open ).
~Type~ is the same mode (~r~, ~w~, ~a~, ~r+~, ~w+~, ~a+~) that was used in the original creation
of a file identified by ~fildes~.
.I Fdopen\^
returns a pointer to the associated stream,
or ~NULL~ if unsuccessful.
The update options (~r+~, ~w+~, ~a+~) are available
in \*t Edition 1.2.
.CW -t
.Ex
.CD +t
int fd;
char *name = "myfile";
FILE *strm;

fd = open(name,0);
.CD -t
.sp -.5v
.CD +t
	.
.CD -t
.sp -.5v
.CD +t
	.
.CD -t
.sp -.5v
.CD +t
	.
	if((strm = fdopen(fd,"r")) == NULL)
		fprintf(stderr,"Error on %d\n",fd);
.CN
.Li fileno
#include <stdio.h>
int fileno (stream)
FILE \(**stream;
.IL
Implemented as a macro on \*u, (and contained in the file
.I stdio\s+4.\s-4h ),
.I f\&ileno\^
returns an integer file descriptor
associated with a valid ~stream~.
Any existing non-\*u implementations
may have different meanings for the integer which is returned.
.I Fileno\^
is used by many other standard functions in the C library.
.Li fopen
#include <stdio.h>
FILE \(**fopen (filename, type)
char \(**filename, \(**type;
.IL
.I Fopen\^
opens a file named
~filename~
and returns a pointer to a structure
(hereafter referred to as ~stream~),
containing the data necessary to handle a stream
of data.
~Type~
is one of the following character strings:
.VL 10 5 1
.LI "~r ~"
used to open for reading.
.LI "~w ~"
used to open for writing,
which truncates an existing file to zero length or
creates a new file.
.LI "~a ~"
used to append, that is, open for writing at the end
of a file, or create a new file.
.LI "~r+ ~"
update reading, which means open for reading and allow writing,
positions the file pointer at the beginning of the file.
.LI "~w+ ~"
update writing, which means open for writing and allow reading,
truncates an existing file to zero length or creates a new file.
.LI "~a+ ~"
update appending, which means open for writing, positions to the end of the file, and
allows for subsequent reads and writes.
If the file does not exist, it will be created.
.LE
.P
For the update options,
.I fseek\^
or
.I rewind\^
can be used to trigger the change from reading to writing, or vice versa.
(Reaching ~EOF~ on input will also permit writing without further formality.)\ 
.I Fopen\^
returns a ~NULL~ pointer if ~filename~ cannot be opened.
On non-\*u implementations, file names may be something different
from a \*u-like name.
The update functions are particularly applicable to stream \s-1I/O\s+1
and allow for the possibility of creating temporary files
for both reading and writing.
The \*g and \s-1IBM\s+1 implementations contain many options other than those mentioned
above.
The update options are available in \*t Edition 1.2.
.CW -t
.Ex
.CD +t
FILE *fp;
char *file;

	if((fp = fopen(file,"r")) == NULL)
		fprintf(stderr, "Cannot open %s\n",file);
.CN
.Li freopen
#include <stdio.h>
FILE \(**freopen (newfile, type, stream)
char \(**newfile, \(**type;
FILE \(**stream;
.IL
.I Freopen\^
accepts a pointer, ~stream~,
to a previously opened file; the old file is closed, and then the new file is opened.
The principal motivation for
.I freopen\^
is the desire to attach the names
.I stdin ,
.I stdout ,
and
.I stderr\^
to specified files.
On a successful
.I freopen ,
the stream pointer is returned; otherwise
~NULL~ is returned,
indicating that, while the file closing took place,
the reopening failed.
.I Freopen\^
is of limited portability;
it can not be implemented in all environments.
.CW -t
.Ex
.CD +t
char *newfile;
FILE *nfile;

	if((nfile = freopen(newfile,"r",stdout)) == NULL)
		fprintf(stderr,"Cannot reopen %s\n",newfile);
.CN
.Li fseek
#include <stdio.h>
int fseek (stream, offset, ptrname)
FILE \(**stream;
long offset;
int ptrname;
.IL
.I Fseek\^
positions a stream
to a location ~offset~ distance from the beginning,
current position or end of a file, depending
on the values 0, 1, 2 respectively for
~ptrname~.
On \*u the offset unit is bytes;
other implementations are not necessarily the same.
(For example, on \*g the offset is
three 12-bit fields of block, logical-record number,
and offset-into-record number.)\ 
The return values are 0 on success and ~EOF~ on
failure.
Both buffered and unbuffered files
may make use of
.I fseek .
As implemented, the function cannot be ported to the \s-1OS\s+1/370
environment.
.CW -t
.Ex
.ti 0
\s10\f1To position to the end of a file:\fP\s0
.P
.CD +t
FILE *stream;

fseek(stream,0L,2);
.CN
.Li pclose
#include <stdio.h>
int pclose (stream)
FILE \(**stream;
.IL
.I Pclose\^
closes a stream opened by
.I popen .
It returns the exit status of the command
that was issued as the first argument of its
corresponding
.I popen ,
or \-1 if the stream was not opened by
.I popen .
The function name
.I pclose\^
means an entirely different thing in the \s-1OS\s+1/370 environment.
.Li popen
#include <stdio.h>
FILE \(**popen (command, type)
char \(**command, \(**type;
.IL
.I Popen\^
is used to create a pipe between the calling process and a command to be
executed.
The first argument is a shell command line;
.I type\^
is the \s-1I/O\s+1 mode for the pipe, and may be either
~r~ for reading or ~w~ for writing.
The function returns a stream pointer to be used for \s-1I/O\s+1 on the standard input
or output of the command.
A ~NULL~ pointer is returned if an error occurs.
.CW -t
.Ex
.CD +t
FILE *pstrm;

if((pstrm=popen("tr mvp MVP","w"))== NULL)
	 fprintf(stderr,"popen error\n");
fprintf(pstrm,"a message via the pipe...\n");
if(pclose(pstrm) == -1)
	fprintf(stderr,"Pclose error\n");
.CN
results in:
.CW
a Message Via the PiPe
.CN
.Li rewind
#include <stdio.h>
int rewind(stream)
FILE \(**stream;
.IL
.I Rewind\^
sets the position of the next operation at the beginning
of the file associated with
~stream~, retaining the current mode of the file.
It is the equivalent of
.I "fseek\ (stream,0L,0);" .
.Li setbuf
#include <stdio.h>
setbuf (stream, buf)
FILE \(**stream;
char \(**buf;
.IL
This function allows the user to choose his
own buffer for \s-1I/O\s+1 or to choose to have no
buffering at all.
Use it after opening and before reading or writing.
The function is often used to eliminate the
single character writes to a file that result from the execution
of
.I putc\^
to standard output that is not redirected.
The choice to buffer \s-1I/O\s+1 brings with it the responsibility for flushing
any data that may remain in a last, partially-filled buffer.
.I Ff\&lush\^
or
.I fclose\^
perform this task.
The constant \%~BUFSIZ~ in
.I stdio\s+4.\s-4h\^
tells how big the
character array ~buf~ is.
It is well-chosen for the machine on which \s-1UNIX\s+1 is running.
When ~buf~ is set to ~NULL~, the
\s-1I/O\s+1 is completely unbuffered.
(On \*g the function is implemented as a null macro, because that environment does not
need such a function.)\ 
.CW -t
.Ex
.CD +t
setbuf (stdout, malloc(BUFSIZ));
.CN
.LE
.HU "FILE STATUS"
.VL 11
.Li clearerr
#include <stdio.h>
clearerr(stream)
FILE \(**stream;
.IL
.I Clearerr\^
is used to reset the error condition on
~stream~.
The need for
.I clearerr\^
arises on \*u implementations
where the error indicator is not reset
after a query.
.Li feof
#include <stdio.h>
int feof (stream)
FILE \(**stream;
.IL
.I Feof ,
which is implemented as a macro on \s-1UNIX\s+1,
returns non-zero
if an input operation on
~stream~ has reached end of file;
otherwise a zero is returned.
.I Feof\^
should be used
in conjunction with any
\s-1I/O\s+1 function whose return value is not a clear indicator of an end-of-file
condition.
Such functions are
.I fread\^
and
.I getw .
.CW -t
.Ex
.CD +t
int *x;
FILE *stream;

do
	*x++ = getw(stream);
while(!feof(stream));
.CN
.Li ferror
#include <stdio.h>
int ferror (stream)
FILE *stream;
.IL
.I Ferror\^
tests for an indication of error on ~stream~.
It returns a non-zero value (true) when an error is found, and
a zero otherwise.
Calls to
.I ferror\^
do not clear the error condition,
hence the
.I clearerr\^
function is needed for that purpose.
The user should be aware that, after an error,
further use of the file may cause strange results.
On \*u
.I ferror\^
is implemented as a macro.
.CW -t
.Ex
.CD +t
FILE *stream;
int *x;

while(!ferror(stream))
	putw(*x++,stream);
.CN
.Li ftell
#include <stdio.h>
long ftell (stream)
FILE \(**stream;
.IL
.I Ftell\^
is used to determine the current offset relative to the
beginning of the file associated with
~stream~.
It returns the current value of the offset; in \*u it returns the offset value in bytes.
On error, a value of \-1 is returned.
This function is useful in obtaining an offset for subsequent
.I fseek\^
calls.
.LE
.br
.ne 8
.HU "INPUT FUNCTIONS"
.VL 11
.Li fgetc
#include <stdio.h>
int fgetc (stream)
FILE \(**stream;
.IL
This is the function version of the macro
.I getc\^
and acts identically to
.I getc .
Because
.I fgetc\^
is a function and not a macro,it can be used in debugging to set breakpoints on
.I fgetc\^
and when the side effects of macro processing of the argument is a problem.
Furthermore, it can be passed as an argument.
.Li fgets
#include <stdio.h>
char \(**fgets (s,n,stream)
char \(**s;
int n;
FILE \(**stream;
.IL
.I Fgets\^
reads from
~stream~
into the area pointed to by
~s~
either n\-1 characters or an entire string including
its new-line terminator, whichever comes first.
A final null character is affixed to the data read.
It returns the pointer
~s~
on success, and ~NULL~ on end-of-file or error.
.I Fgets\^
differs from the function
.I gets\^
in that it can read from other than
.I stdin ,
and that it appends the new-line at the end
of input when the size of the string is longer than
or equal to ~n~.
More importantly, it provides control over the size of the
string to be read that is not available with
.I gets .
.CW -t
.Ex
.CD +t
char msg[MAX];
FILE *myfile;

	while(fgets(msg,MAX,myfile) != NULL)
		printf("%s\n",msg);
.CN
.Li fread
#include <stdio.h>
int fread((char \(**)ptr, sizeof (\(**ptr), nitems, stream)
FILE \(**stream;
.IL
This function reads from
~stream~ the next ~nitems~
whose size is the same as the size of the item pointed to by ~ptr~,
into a sufficiently large area starting at
~ptr~.
It returns the number of items read.
In \*u,
.I fread\^
makes use of the function
.I getc .
It is often used in combination with
.I feof\^
and
.I ferror\^
to obtain a clear indication of the file status.
.CW -t
.Ex
.CD +t
FILE *pstm;
char mesg[100];

	while(fread((char *)mesg,sizeof(*mesg),1,pstm) == 1)
		printf("%s\n",mesg);
.CN
.Li fscanf
#include <stdio.h>
int fscanf (stream, format[, argptr]\|.\|.\|.\|)
char *format;
FILE \(**stream;
.IL
.I Fscanf\^
accepts input from the file
associated with
~stream~,
and deposits it into the storage area
pointed to by the respective
argument pointers according to the specified formats.
Format specifications are those that appear in Attachment\ D.
.I Fscanf\^
differs from
.I scanf\^
in that it can read from other than
.I stdin .
The function returns the number of successfully handled input arguments,
or ~EOF~ on end-of-input.
.CW -t
.Ex
.CD +t
FILE *file;
long pay;
char name[15];
char pan[7];

	fscanf(file,"%6s%14s%ld\n",pan,name,&pay);
	if(pay<50000)
		printf("$%ld raise for %s.\n",pay/10,name);
.CN
If the input data is:
.CW
020202MaryJones 15000
.CN
the resulting output is:
.CW
$1500 raise for MaryJones.
.CN
.Li getc
#include <stdio.h>
int getc (stream)
FILE \(**stream;
.IL
.I Getc\^
returns the next character from the named ~stream~.
On \*u it is implemented
as a macro to avoid the overhead of a function call.
On error or end-of-file it returns an ~EOF~.
.I Fgetc\^
should be used when it is necessary to avoid the side effects of argument processing
by the macro
.I getc .
.Li getchar
#include <stdio.h>
int getchar()
.IL
This is identical to
.I "getc\ (stdin)" .
.Li gets
#include <stdio.h>
char \(**gets(s)
char \(**s;
.IL
.I Gets\^
reads a string of characters up to a new-line from
.I stdin\^
and places them in the
area pointed to by ~s~.
The new-line character which ended the string is replaced by the null character.
The return values are ~s~ on success, ~NULL~ on error
or end-of-file.
The simple example below presumes the size of the string read into
~msg~ will not exceed ~SIZE~ in length.
If used in conjunction with
.I strlen ,
a dangerous overflow can be detected, though not prevented.
.CW -t
.Ex
.CD +t
char msg[SIZE];
char *s;
	s = msg;
	while (gets(s) != NULL)
		printf("%s\n",s);
.CN
.Li getw
#include <stdio.h>
int getw (stream)
FILE \(**stream;
.IL
.I Getw\^
reads the next word from
the file associated with
~stream~.
On success it returns the word;
on error or end of file, it returns ~EOF~.
However, because ~EOF~ could be a valid word,
this function is best used with
.I feof\^
and
.I ferror .
.CW -t
.Ex
.CD +t
FILE *stream;
int *x;
	do
		*x++ = getw(stream);
	while (!feof(stream));
.CN
.Li scanf
#include <stdio.h>
int scanf (format[, argptr]\|.\|.\|.\|)
char \(**format;
.IL
.I Scanf\^
reads input from
.I stdin ,
delivers
the input according
to the specified formats, and deposits the
input in the storage area pointed to by the respective
argument pointers.
The correct format specifications can be found in Attachment\ D.
For input from other streams than
.I stdin\^
use
.I fscanf ;
for input from a character array use
.I sscanf .
The return values are the number of successfully
handled input arguments, or ~EOF~ on end-of-input.
.CW -t
.Ex
.CD +t
long number;

	scanf("%ld",&number);
	(printf(number%2?"%ld is odd":"%ld is even",number));
.CN
.Li sscanf
#include <stdio.h>
sscanf (s, format [, pointer]\|.\|.\|.\|)
char \(**s;
char \(**format;
.IL
.I Sscanf\^
accepts input from a character string ~s~,
delivers the input according to the
specified formats, and deposits it into the storage
area pointed to by the respective
argument pointers.
Format specifications appear in Attachment\ D.
This function returns the number of successfully handled
input arguments.
.CW -t
.Ex
.CD +t
char datestr[] = {"THU MAR 29 11:04:40 EST 1979"};
char month[4];
char year[5];

	sscanf(datestr,"%*3s%3s%*2s%*8s%*3s%4s",month,year);
	printf("%s, %s\n",month,year);
.CN
The result is:
.CW
MAR, 1979
.CN
.Li ungetc
#include <stdio.h>
int ungetc (c, stream)
int c;
FILE \(**stream;
.IL
.I Ungetc\^
puts the character ~c~ back on the
file associated with ~stream~.
One character (but never ~EOF~) is assured of being put back.
If successful, the function returns ~c~, otherwise ~EOF~.
.CW -t
.Ex
.CD +t
while(isspace (c = getc(stdin)))
	;
ungetc(c,stdin);
.CN
This code puts the first character that is not white space back onto
the standard input stream.
.LE
.HU "OUTPUT FUNCTIONS"
.VL 11
.Li fflush
#include <stdio.h>
int fflush (stream)
FILE \(**stream;
.IL
.I Ff\&lush\^
takes action to guarantee that
any data contained in file buffers and not yet
written out will be written.
It is used by
.I fclose\^
to flush a stream.
No action is taken on files
not open for writing.
The return values are zero for success, ~EOF~ on error.
.Li fprintf
#include <stdio.h>
int fprintf (stream, format[, arg ]\|.\|.\|.\|)
FILE \(**stream;
char \(**format;
.IL
.I Fprintf\^
provides formatted output to a named stream.
The function
.I printf\^
may be used if the destination is
.I stdout .
Specifications for formats are available in Attachment\ C.
On error,
.I fprintf\^
returns non-zero, otherwise zero.
In later releases of the C library,
.I fprintf\^
will return the number of characters transmitted,
or a negative value on error.
.CW -t
.Ex
.CD +t
int *filename;
int c;

	if(c==EOF)
		fprintf(stderr,"EOF on %s\n",filename);
.CN
.Li fputc
#include <stdio.h>
int fputc (c,stream)
int c;
FILE \(**stream;
.IL
.I Fputc\^
performs the same task as
.I putc ;
that is, it writes the character ~c~
to the file associated with ~stream~,
but is implemented as a function rather than a macro.
It is preferred to
.I putc\^
when the side effects of macro processing
of arguments are a problem.
On success,
it returns the character written; on failure it returns ~EOF~.
.CW -t
.Ex
.CD +t
FILE *in, *out;
int c;

	while ((c = fgetc(in)) != EOF)
		fputc(c,out);
.CN
.Li fputs
#include <stdio.h>
int fputs(s,stream)
char \(**s;
FILE \(**stream;
.IL
.I Fputs\^
copies a string to the output file associated with
~stream~.
In \*u it
uses the function
.I putc\^
to do this.
It is different from
.I puts\^
in two ways:
it allows any output stream to be specified,
and it does not affix a new-line to the output.
For an example, see
.I puts .
.Li fwrite
#include <stdio.h>
int fwrite ((char \(**)ptr, sizeof (\(**ptr),nitems,stream)
FILE \(**stream;
.IL
Beginning at ~ptr~,
this function writes up to ~nitems~ of data of the type
pointed to by
~ptr~ into output ~stream~.
It returns the number of items actually written.
For the \*g implementation, ~ptr~ must be on a machine-word boundary.
Like
.I fread\^
this function should be used in conjunction with
.I ferror\^
to detect the error condition.
.CW -t
.Ex
.CD +t
char mesg[] ={"My message to write out\n"};
FILE *pstrm;

	if(fwrite(mesg,(sizeof(*mesg)-1),1,pstrm) != 1)
		fprintf(stderr,"Output error\n");
.CN
.Li printf
#include <stdio.h>
int printf(format[, arg]\|.\|.\|.\|)
char \(**format;
.IL
.I Printf\^
provides formatted output on
.I stdout .
The many format specifications are available in
Attachment\ C.
.I Fprintf\^
and
.I sprintf\^
are related functions that write output onto other than the
standard output device.
In case of error, implementations are not consistent in their output.
On error,
.I printf\^
returns non-zero, otherwise zero.
In later releases of the C library, 
.I printf\^
returns the number of characters transmitted,
or a negative value on error.
.CW -t
.Ex
.CD +t
int num = 10;
char msg[] = {"ten"};
printf("%d - %o - %s\n", num, num, msg);
.CN
results in the line:
.CW
10 - 12 - ten;
.CN
.Li putc
#include <stdio.h>
int putc (c,stream)
int c;
FILE \(**stream;
.IL
.I Putc\^
writes the character
.I c\^
to the file associated with
.I stream .
On success, it returns the character written; on error it returns ~EOF~.
Because it is implemented as a macro,
side effects may result from argument processing.
In such cases, the equivalent function
.I fputc\^
should be used.
.CW -t
.Ex
.CD +t
#define PROMPT()	putc('\7',stderr)	/* BEL */
.CN
.Li putchar
#include <stdio.h>
int putchar(c)
int c;
.IL
.I Putchar\^
is defined as
.I "putc\ (c,\ stdout)" .
It returns the character written on success, or ~EOF~ on error.
.CW -t
.Ex
.CD +t
char *cp;
char x[SIZE];

	for(cp=x;cp<(x+SIZE);cp++)
		putchar(*cp);
.CN
.Li puts
#include <stdio.h>
int puts(s)
char \(**s;
.IL
The function copies the string pointed to by ~s~ without
its terminating null character
to
.I stdout .
A new-line character is appended.
The \*u implementation uses the macro
.I putchar\^
(which calls
.I putc ).
.CW -t
.Ex
.CD +t
puts("I will append a new-line");
fputs("\tsome more data ", stdout);
puts("and now a new-line");
.CN
The resulting output is:
.CW
I will append a new-line
	some more data and now a new-line
.CN
.Li putw
#include <stdio.h>
int putw(w,stream)
FILE \(**stream;
int w;
.IL
.I Putw\^
appends word ~w~ to the output ~stream~.
As with
.I getw ,
the proper way to check for an error or end-of-file
is to use the
.I feof\^
and
.I ferror\^
functions.
.CW -t
.Ex
.CD +t
int info;

while(!feof(stream))
	putw(info,stream);
.CN
.Li sprintf
#include <stdio.h>
int sprintf(s, format, [, arg]\|.\|.\|.\|)
char \(**s;
char \(**format;
.IL
.I Sprintf\^
allows for formatted output to be
placed in a character array pointed to by ~s~.
.I Sprintf\^
adds a null at the end of the formatted output.
See Attachment\ C
for the specification of formats.
It is the user's responsibility to provide an array of sufficient length.
Other related functions
.I printf\^
and
.I fprintf\^
handle similar kinds of formatted output.
.I Sprintf\^
can be used to build formatted arrays
in memory, to be changed dynamically
before output, or to be
used to call other routines.
The comparable input function is
.I sscanf .
On error,
.I sprintf\^
returns non-zero, otherwise zero.
In later releases of the C library,
.I sprintf\^
returns the number of characters transmitted,
or a negative value on error.
.CW -t
.Ex
.CD +t
char cmd[100];
char *doc = "/usr/src/cmd/cp.c"
int width = 50;
int length = 60;

	sprintf(cmd,"pr -w%d -l%d %s\n",width,length,doc);
	system(cmd);
.CN
The above code executes the
.I pr\^
command to
print the source of the
.I cp\^
command.
.LE
.HU "STRING FUNCTIONS"
.VL 11
.Li strcat
char \(**strcat(dst,src)
char \(**dst, \(**src;
.IL
.I Strcat\^
appends characters in the string pointed to by ~src~ to the end of
the string pointed to by
~dst~, and places a null character after the last character copied.
It returns a pointer to ~dst~.
To concatenate strings up to a maximum number of characters, use
.I strncat .
.CW -t
.Ex
.CD +t
char *myfile;
char dir[L_cuserid+5] = "/usr/";
	myfile = (strcat(dir,cuserid(0)));
.CN
The result is the concatenation of the login name onto the end of the string ~dir~.
.Li strchr
char \(**strchr(s,c)
char \(**s;
int c;
.IL
.I Strchr\^
searches a string pointed to by ~s~,
for the leftmost occurrence of the character ~c~.
It returns a pointer to the character found, or
~NULL~ if ~c~ does not occur in the string.
.CW -t
.Ex
.CD +t
int length;
char *a;
register char *b;

length = ((b=strchr(a,' ')) == NULL?0:b - a);
.CN
The resulting ~length~ is the number of characters
up to the first blank
in the string pointed to by ~a~.
.Li strcmp
char \(**strcmp(s1,s2)
char \(**s1, \(**s2;
.IL
.I Strcmp\^
compares the characters in the string
~s1~ and ~s2~.
It returns an integer value, greater than, equal to, or less than zero,
depending on whether ~s1~ is lexicographically greater than,
equal to, or less than ~s2~.
.CW -t
.Ex
.CD +t
#define EQ(x,y)  !strcmp(x,y)
.CN
.Li strcpy
char \(**strcpy(dst, src)
char \(**dst, \(**src;
.IL
.I Strcpy\^
copies the characters (including the
null terminator)
from the string pointed to by
~src~ into the string pointed to by ~dst~.
A pointer to ~dst~ is returned.
.CW -t
.Ex
.CD +t
char dst[] = "UPPER CASE";
char src[] = "this is lower case";

	printf("%s\n",strcpy(dst,src+8));
.CN
results in:
.CW
lower case
.CN
.Li strlen
int strlen(s)
char \(**s;
.IL
.I Strlen\^
counts the number of characters
starting at the character pointed to by ~s~ up to,
but not including,
the first null character.
It returns the integer count.
.CW -t
.Ex
.CD +t
char nextitem[SIZE];
char series[MAX];

if(strlen(series)) strcat(series,",");
strcat(series,nextitem);
.CN
.Li strncat
char \(**strncat(dst, src, n)
char \(**dst, \(**src;
int n;
.IL
.I Strncat\^
appends a maximum of ~n~ characters
of the string pointed to by ~src~
and then a null character to the string pointed to by ~dst~.
It returns a pointer to ~dst~.
.CW -t
.Ex
.CD +t
char dst[] = "cover";
char src[] = "letter";

	printf("%s\n",strncat(dst,src,3));
.CN
The output is:
.CW
coverlet
.CN
.Li strncmp
int strncmp(s1,s2,n)
char \(**s1, \(**s2;
int n;
.IL
.I Strncmp\^
compares two strings for at most
~n~ characters and returns
an integer greater than, equal to, or less than zero
as ~s1~ is lexicographically greater than, equal to or
less than ~s2~.
.CW -t
.Ex
.CD +t
char filename [] = "/dev/ttyx";

if(strncmp (filename+5, "tty",3) == 0)
	printf("success\n");
.CN
.Li strncpy
char \(**strncpy(dst,src,n)
char \(**dst, \(**src;
int n;
.IL
.I Strncpy\^
copies ~n~ characters of the string pointed to by ~src~ into
the string pointed to by ~dst~.
Null padding or truncation of ~src~ occurs as necessary.
A pointer to ~dst~ is returned.
.CW -t
.Ex
.CD +t
char buf [MAX];
char date [29] = {"Fri Jun 29 09:35:44 EDT 1979"};
char *day = buf;

	strncpy(day,date,3);
.CN
After executing this code, ~day~ points to the string
~Fri~.
.Li strrchr
char \(**strrchr(s,c)
char \(**s;
int c;
.IL
.I Strrchr\^
searches a string pointed to by ~s~,
for the rightmost occurrence of the character ~c~.
It returns a pointer to the character found,
or ~NULL~ if ~c~ does not occur in the string.
.CW -t
.Ex
.CD +t
char reverse[] = "NAME NO ONE MAN";

	printf(strrchr (reverse,'M'));
.CN
results in:
.CW
MAN
.CN
.LE
.HU "CHARACTER CLASSIFICATION"
.VL 11
.Li isalnum
#include <ctype.h>
int isalnum(c)
int c;
.IL
This macro determines whether or not the character ~c~ is an
alphanumeric character
(~[A-Za-z0-9]~).
It returns zero for false and non-zero for true.
.Li isalpha
#include <ctype.h>
int isalpha(c)
int c;
.IL
This macro determines whether or not the character ~c~ is an
alphabetic character (~[A-Za-z]~).
It returns zero for false and non-zero for true.
.Li isascii
#include <ctype.h>
int isascii(c)
int c;
.IL
This macro determines whether or not the
integer value supplied is an \s-1ASCII\s+1 character; that is, a character
whose octal value ranges from 000 to 177.
It returns zero for false and non-zero for true.
.Li iscntrl
#include <ctype.h>
int iscntrl(c
int c;
.IL
This macro determines whether or not the character ~c~ when mapped to \s-1ASCII\s+1 is a
control character (that is, octal 177 or 000-037).
It returns zero for false and non-zero for true.
.Li isdigit
#include <ctype.h>
int isdigit(c)
int c;
.IL
This macro determines whether or not the character ~c~ is a
digit.
It returns zero for false and non-zero for true.
.Li isgraph
#include <ctype.h>
int isgraph(c)
int c;
.IL
This macro determines whether or not the character ~c~
has a graphic representation
(that is, is an \s-1ASCII\s+1 code between octal 041 and 176 inclusive).
.Li islower
#include <ctype.h>
int islower(c)
int c;
.IL
This macro determines whether or not the character ~c~ is a
lower-case letter.
It returns zero for false and non-zero for true.
.Li isprint
#include <ctype.h>
int isprint(c)
int c;
.IL
This macro determines whether or not the character ~c~ is a
printable character.
(This includes spaces.)\ 
It returns zero for false and non-zero for true.
.Li ispunct
#include <ctype.h>
int ispunct(c)
int c;
.IL
This macro determines whether or not the character ~c~ is a
punctuation character (neither a control character nor an alphanumeric).
It returns zero for false and non-zero for true.
.Li isspace
#include <ctype.h>
int isspace(c)
int c;
.IL
This macro determines whether or not the character ~c~ is a
form of white space
(that is, a blank, horizontal
or vertical tab, carriage return, form-feed or new-line).
It returns zero for false and non-zero for true.
.Li isupper
#include <ctype.h>
int isupper(c)
int c;
.IL
This macro determines whether or not the character ~c~ is an
upper-case letter.
It returns zero for false and non-zero for true.
.LE
.HU "CHARACTER TRANSLATION"
.VL 11
.Li toascii
#include <ctype.h>
int toascii (c)
int c;
.IL
The macro
.I toascii\^
usually does nothing in the \*u environment.
Its purpose is to map the input character into its \s-1ASCII\s+1
equivalent.
In a non-\s-1ASCII\s+1 environment it is beneficial for users of character
indices into tables ordered in \s-1ASCII\s+1 collating sequence.
.CW -t
.Ex
.CD +t
FILE *oddstrm;

	if(!isdigit (toascii(getw(oddstrm))))
		fprintf(stderr,"bad data\n");
.CN
.Li tolower
#include <ctype.h>
int tolower (c)
int c;
.IL
If the argument ~c~ passed to the function
.I tolower\^
is an upper-case letter, the lower-case representation of
~c~ is returned, otherwise ~c~ is returned unchanged.
For a faster routine,
use
.I _tolower ,
which is implemented as a macro;
however, the argument
.I must\^
already be an upper-case letter.
.CW -t
.Ex
.CD +t
if(tolower(getchar()) != 'y')
	exit(0);
.CN
.Li toupper
#include <ctype.h>
int toupper (c)
int c;
.IL
If the argument ~c~ passed to the function
.I toupper\^
is a lower-case letter, the upper-case representation of ~c~ is returned,
otherwise ~c~ is returned unchanged.
For a faster routine, use
.I _toupper ,
however, the
argument
.I must\^
already be a lower-case letter.
.CW -t
.Ex
.CD +t
if(toupper (getchar()) != 'Y')
	exit(0);
.CN
.LE
.HU "SPACE ALLOCATION"
.VL 11
.Li calloc
char \(**calloc(n, size)
unsigned n, size;
.IL
.I Calloc\^
allocates enough storage for an array of
~n~ items aligned for any use, each of ~size~ bytes.
The space is initialized to zero.
.I Calloc\^
returns a pointer to the beginning of the allocated space, or
a ~NULL~ pointer on failure.
.CW -t
.Ex
.CD +t
char *t;
int n;
unsigned size;

	if(t=calloc((unsigned)n, size) == NULL)
		fprintf(stderr,"Out of space.\n");
.CN
.Li free
free(ptr)
char \(**ptr;
.IL
.I Free\^
is used in conjunction with the space allocating functions
.I malloc ,
.I calloc ,
or
.I realloc .
~Ptr~ is
a pointer supplied by one of these routines.
The effect is to free the space previously allocated.
.Li malloc
char \(**malloc(size)
unsigned size;
.IL
.I Malloc\^
allocates ~size~ bytes of storage
beginning on a word boundary.
It returns a pointer to the beginning of the allocated space, or
a ~NULL~ pointer on failure to
acquire space.
For space initialized to zero, see
.I calloc .
.CW -t
.Ex
.CD +t
int n;
char *t;
unsigned size;

	if(t=malloc((unsigned)n) == NULL)
		fprintf(stderr,"Out of space.\n");
.CN
.Li realloc
char \(**realloc (ptr, size)
char \(**ptr;
unsigned size;
.IL
Given ~ptr~ which was supplied by a call to
.I malloc\^
or
.I calloc ,
and a new byte size,
~size~,
.I realloc\^
returns a pointer to the block of space of ~size~ bytes.
This function is useful to do storage compacting along with
.I malloc\^
and
.I free .
.LE
.HU "MISCELLANEOUS FUNCTIONS"
.VL 11
.Li ctermid
#include <stdio.h>
char \(**ctermid(s)
char \(**s;
.IL
.I Ctermid\^
provides a string that can be used as a file name, (~/dev/tty~),
to identify the controlling terminal for the
running process.
Unlike the function
.I ttyname\^
it is disassociated from the machine-dependent concept
of a file descriptor.
If an argument of zero is supplied,
the string is stored internally and will be overwritten on the next call
to
.I ctermid .
A non-zero argument is treated as a pointer to a sufficiently large storage area where the
string is placed.
.Li cuserid
#include <stdio.h>
char \(**cuserid(s)
char \(**s;
.IL
.I Cuserid\^
composes a string representation of the login name of the owner of the
current process.
A zero argument results in the string being stored in an internal
area; in this case a pointer to that area is returned on success, and
a ~NULL~ on failure.
A non-zero argument is assumed to be a pointer to
a repository of size ~L_cuserid~ (contained in
.I ctype\s+4.\s-4h ).
On failure a null character
will be inserted in place of a string
and a ~NULL~ is returned.
.CW -t
.Ex
.CD +t
puts (cuserid((char *) NULL));
.CN
.Li gsignal
#include <signal.h>
int gsignal (sig)
int sig;
.IL
Along with
.I ssignal ,
.I gsignal\^
implements a facility for software signals.
A software signal is raised by a call to
.I gsignal .
Raising a software signal causes the action established by
.I ssignal\^
to be taken.
The argument ~sig~ identifies the signal to be set.
If ~sig~ is a value defined in
.I signal\s+4.\s-4h ,
then
.I gsignal\^
returns that value.
If an action function was established for
~sig~,
then the action is reset to the default value,
the action function is performed with argument ~sig~,
and the return value is the return value of the action function.
In any abnormal case,
.I gsignal\^
returns the value ~0~
and takes no other action.
.CW -t
.Ex
.CD +t
char *buf;
	if((buf = gets(string))==NULL) gsignal(2);
.CN
.Li ssignal
#include <signal.h>
int (\(** ssignal (sig,action))()
int sig, (\(**action)();
.IL
.I Ssignal\^
along with
.I gsignal\^
implements a software signal facility.
An action for a software signal is established by a call to
.I ssignal .
~Sig~ is the number identifying
the type of signal
for which an action is to be established.
The numbers currently defined are found
in
.I signal\s+4.\s-4h .
~Action~ is either the name of a user-defined action
function or one of the constants defined in
.I signal\s+4.\s-4h .
.I Ssignal\^
returns the action previously established
for that signal type;
in abnormal circumstances
.I ssignal\^
returns
a default of zero.
.CW -t
.Ex
.CD +t
main() {
int error();
ssignal(2, error);
.CD -t
.sp -.5v
.CD +t
	.
.CD -t
.sp -.5v
.CD +t
	.
.CD -t
.sp -.5v
.CD +t
	.
}
error(x) {
int x;
printf("Software signal %d has been caught.\n",x);
}
.CN
.Li system
#include <stdio.h>
system(string)
char \(**string;
.IL
.I System\^
passes the argument ~string~ to the
operating system
as a command line.
It returns the exit status of the command executed.
.CW -t
.Ex
.CD +t
if(!system ("cmp -s file1 file2"))
	printf("The two files are identical.\n");
.CN
.Li tmpnam
#include <stdio.h>
char \(**tmpnam(s)
char \(**s;
.IL
.I Tmpnam\^
generates a file name that can be used for a temporary file.
If ~s~ is zero, it returns a pointer to a character string containing
that name in an internal storage area.
For a non-zero value in ~s~, the file name is stored in a
sufficiently large
area pointed to by ~s~
(see
~L_tmpnam~
in
.I ctype\s+4.\s-4h )
and ~s~ is the return value as well.
.Li tmpfile
#include <stdio.h>
FILE \(**tmpfile ()
.IL
.I Tmpf\&ile\^
creates a scratch file opened for update.
It stays in existence only during the life of the
process issuing
the function call and is inherited across forks.
It returns a pointer to the ~FILE~
associated with the opened stream.
On error, it returns ~NULL~.
This function is implemented in \*t Edition 1.2.
.LE
.bp
.de CW
.DS
.ps 8
.vs 9p
.ta 16m/3u 32m/3u 48m/3u 64m/3u 80m/3u 96m/3u 112m/3u 128m/3u 144m/3u 160m/3u
..
.ce
.bd R 3
Attachment\ B
.sp 1.5v
.bd R
.S +1
.ce
.I ctype.h
.sp .5v
.S -1
.CW
#define _U      01
#define _L      02
#define _N      04
#define _S     010
#define _P     020
#define _C     040
#define _B    0100

extern	char	_ctype_[];

#define isalpha(c)      ((_ctype_+1)[c]&(_U|_L))
#define isupper(c)      ((_ctype_+1)[c]&_U)
#define islower(c)      ((_ctype_+1)[c]&_L)
#define isdigit(c)      ((_ctype_+1)[c]&_N)
#define isspace(c)      ((_ctype_+1)[c]&(_S|_B))
#define ispunct(c)      ((_ctype_+1)[c]&_P)
#define isalnum(c)      ((_ctype_+1)[c]&(_U|_L|_N))
#define isprint(c)      ((_ctype_+1)[c]&(_P|_U|_L|_N|_B))
#define isgraph(c)      ((_ctype_+1)[c]&(_P|_U|_L|_N))
#define iscntrl(c)      ((_ctype_+1)[c]&_C)
#define isascii(c)      ((unsigned)(c)<=0177)
#define _toupper(c)     ((c)-'a'+'A')
#define _tolower(c)     ((c)-'A'+'a')
#define toascii(c)      ((c)&0177)
.CN
.sp 1.5v
.S +1
.ce
.I signal.h
.sp .5v
.S -1
.CW
#define     NSIG       16

#define     SIGHUP      1   /* hangup */
#define     SIGINT      2   /* interrupt */
#define     SIGQUIT     3   /* quit */
#define     SIGILL      4   /* illegal instruction (not reset when caught) */
#define     SIGTRAP     5   /* trace trap (not reset when caught) */
#define     SIGIOT      6   /* IOT instruction */
#define     SIGEMT      7   /* EMT instruction */
#define     SIGFPE      8   /* floating point exception */
#define     SIGKILL     9   /* kill (cannot be caught or ignored) */
#define     SIGBUS     10   /* bus error */
#define     SIGSEGV    11   /* segmentation violation */
#define     SIGSYS     12   /* bad argument to system call */
#define     SIGPIPE    13   /* write on a pipe with no one to read it */
#define     SIGALRM    14   /* alarm clock */
#define     SIGTERM    15   /* software termination signal from kill */

int         (*signal())();
#define     SIG_DFL    (int (*)())0
#define     SIG_IGN    (int (*)())1
.CN
.bp
.S +1
.ce
.I stdio.h
.sp .5v
.S -1
.CW
#define		BUFSIZ		 512
#define		_NFILE		  20
# ifndef FILE
extern	struct	_iobuf {
	char	*_ptr;
	int	_cnt;
	char	*_base;
	char	_flag;
	char	_file;
} _iob[_NFILE];
# endif

#define		_IOREAD		  01
#define		_IOWRT		  02
#define		_IONBF		  04
#define		_IOMYBUF	 010
#define		_IOEOF		 020
#define		_IOERR		 040
#define		_IOSTRG		0100
#define		_IORW		0200

#define		NULL		   0
#define		FILE		struct	_iobuf
#define		EOF		(-1)

#define		L_ctermid	   9
#define		L_cuserid	   9
#define		L_tmpnam	  19

#define		stdin		(&_iob[0])
#define		stdout		(&_iob[1])
#define		stderr		(&_iob[2])
#define		getc(p)		(--(p)->_cnt>=0?\
				*(p)->_ptr++&0377:_filbuf(p))
#define		getchar()	getc(stdin)
#define		putc(x,p)	(--(p)->_cnt>=0?\
				((int)(*(p)->_ptr++=(unsigned)(x))):\
				_flsbuf((unsigned)(x),p))
#define		putchar(x)	putc(x,stdout)
#define		feof(p)		(((p)->_flag&_IOEOF)!=0)
#define		ferror(p)	(((p)->_flag&_IOERR)!=0)
#define		fileno(p)	p->_file

FILE	*fopen();
FILE	*freopen();
FILE	*fdopen();
long	ftell();
char	*fgets();
.CN
.bp
.ce
.bd R 3
Attachment\ C
.br
.bd R
.sp 20v
.ce
\(rh  Paste in page 1 of PRINTF(3S) here  \(lh
.bp
.rs
.sp 20v
.ce
\(rh  Paste in page 2 of PRINTF(3S) here  \(lh
.bp
.ce
.bd R 3
Attachment\ D
.br
.bd R
.sp 20v
.ce
\(rh  Paste in page 1 of SCANF(3S) here  \(lh
.bp
.rs
.sp 20v
.ce
\(rh  Paste in page 2 of SCANF(3S) here  \(lh