PAGEFLOP
FORWARD
SELECTOR
SELAGAIN
WRONGSEL
YOUR SELECTION IS NOT IN THE 0 - #SELIMIT RANGE Please try again
AANVANG
Copyright CourseWare Technologies Inc., 1985-88
Lesson - 11
THE UNIX SYSTEM INTERFACE
P1
UNIX System Interface|Topics to Learn|11-0|10,45
# Topic
--- -------
1 - The UNIX System interface
2 - Using Binary I/O Functions
3 - First Review
4 - More Binary I/O Functions
5 - Performing Random Access
6 - Performing Binary (Standard) I/O
7 - Second Review
0 - Return to the Main Menu
P2
UNIX System Interface|The UNIX System Interface|11-1.1|13,50
Under UNIX the pathname of the standard C library
is included automatically during linking and is:
/lib/libc.a
The standard I/O library has the pathname:
/usr/include/stdio.h
and must be included explicitly in your program with:
#include <stdio.h>
P3
UNIX System Interface|The UNIX System Interface|11-1.2|9,54
Until now, all of the I/O functions we have
discussed performed operations on objects of type
char only (or we used conversion specifiers).
With buffered or high level I/O, the operating
system accesses or buffers the data from the files
in single blocks, rather than in the number of bytes
allocated for the specified variable.
P4
UNIX System Interface|The UNIX System Interface|11-1.3|17,54
Using binary I/O, one refers to the object by
specifying its size rather than its type. Files
that contain these objects may be referred to as
binary files.
All buffered I/O functions use binary I/O
functions.
In binary I/O there is no data buffering.
* Data is written directly into a file.
* The number of bytes requested = the number of bytes accessed.
Under a UNIX operating system, the physical
format of all files is alike. It is the treatment of
the data in the files that may be different.
P5
UNIX System Interface|Binary I/O Functions|11-2.1|16,54
Most binary I/O under UNIX is performed using
the following calls or functions:
open() opens a disk file for binary I/O
close() closes a file opened for binary I/O
creat() creates a file
unlink() deletes a file
read() reads a specified number of bytes from a file
write() writes a specified number of bytes to a file
lseek() random file access function
P6
UNIX System Interface|Binary I/O Functions|11-2.2|5,46
Prior to using a file, it must be opened.
The binary analog to fopen() is open().
open() - Returns a -1 on a failure
P7
UNIX System Interface|Binary I/O Functions|11-2.3|14,54
Syntax: f_d = open(file_name, rwmode);
where:
f_d is the value (of type int) that open()
returns. It is referred to as the file descriptor.
file_name is a character string constant which is the
name of the file to be opened.
rwmode is the access mode which may have a value of:
0 - read access only
1 - write access only
2 - read and write access
P8
UNIX System Interface|Binary I/O Functions|11-2.4|7,48
The complement to function open() is the
function close(f_d), which closes the file with
file descriptor f_d.
close() returns 0 on success and -1 if it
failed to close the file.
P9
UNIX System Interface|Binary I/O Functions|11-2.5| 12 , 52
To create a new file or rewrite an old one, use
the function creat(), the syntax for which is:
f_d = creat(file_name, p_mode);
where:
f_d is the file descriptor of type int
file_name is the name of file to be created
p_mode is the protection mode for the file made
up of octal specifier "0" plus nine bits
P10
UNIX System Interface|More Binary I/O Functions|11-4.1|15,54
OCTAL OWNER GROUP OTHERS
0 XXX XXX XXX
RWE RWE RWE
In the table above, X = '0' OR '1'
On failure, creat() returns -1.
A successfully created file need not be opened
explicitly for write.
A file must be explicitly opened for read().
P11
UNIX System Interface|More Binary I/O Functions|11-4.2|13,54
The complement of creat() is the function
unlink(file_name), which removes file_name from
the system.
Reading and writing is performed with the
functions read() and write(), which return the
number of bytes read or written on success and
-1 on failure.
A 0 returned on read indicates the end of
the file.
P12
UNIX System Interface|More Binary I/O Functions|11-4.3|7,54
Syntax for the read() and write() functions:
n_read = read(f_d, rec_buf, size);
n_write = write(f_d, rec_buf, size);
where: rec_buf is the address of the buffer.
size is the number of bytes to be read
or written.
P13
UNIX System Interface|More Binary I/O Functions|11-4.4|14,57
The following example shows a typical way to copy files
using the system calls read() and write() rather than
the character buffering functions we saw in Lesson 8.
Note that the buffer size is 512 characters or bytes, which
is assumed to be the block size for the system. This
number varies and is usually 1024 bytes or more on the
systems under the Berkeley (BSD) version of UNIX. The
type of the buffer in this case is really irrelevant;
however, type char is the most logical since the size of
a character normally corresponds to 1 byte. In situations
where you will be reading an explicit structure, you
should use the address of the structure as the address
of the buffer. All structure elements will get loaded
with their values automatically.
P14
UNIX System Interface|More Binary I/O Functions|11-4.5|7,54
NOTE: The destination file data_out was created with
protection 0110100100, i.e., -rw-r--r--. The while
statement controls the copying process. Notice that
BUFSIZE bytes are always requested. BUFSIZE bytes may
or may not be read. Since read() does return the
number of bytes read, i.e., bytes, only that number
of bytes is written into the destination file.
P15
UNIX System Interface|More Binary I/O Functions|11-4.6|13,55
/* Copying the input file data_in to the output
file data_out. The data will be specified
by size (binary) rather than type */
#define BUFSIZE 512 /* 1 block of data */
main()
{
int bytes; /* byte counter */
char buf[BUFSIZE]; /* data buffer */
int fd_in, fd_out; /* file descriptors */
/* OPEN INPUT FILE FOR READ */
if ((fd_in = open("data_in", 0)) != -1) {
P16
UNIX System Interface|More Binary I/O Functions|11-4.7|15,57
/* Create output file for writing */
if ((fd_out = creat("data_out", 0644)) != -1) {
/* Transfer data from the input file
to the output file in 512 byte blocks */
while((bytes = read(fd_in, buf, bufsize)) > 0)
write(fd_out, buf, bytes);
close(fd_out); /* close the output file */
}
close (fd_in); /* close the input file */
}
}
P17
UNIX System Interface|Performing Random Access|11-5.1|16,60
Sequential file traversal is not very efficient. Under
UNIX, the function call used for random access is lseek().
Syntax: long lseek();
lseek(f_d, offset, origin);
where: f_d is the file descriptor
offset is a signed long integer which specifies whether
the seek is to be done from the beginning of the
file (origin = 0), the end of the file (origin = 2),
or the current position in the file (origin = 1)
Upon successful completion, lseek() will return the
resulting pointer location as measured in bytes from the
beginning of the file.
P18
UNIX System Interface|Performing Random Access|11-5.2|14,51
/* Random access arithmetic */
long int displacement;
int f_d;
lseek(f_d, 0L, 0); /* move 0 bytes from the
begining of the file */
lseek(f_d, 0L, 2); /* move 0 bytes from the
end of the file */
lseek(f_d, -27L, 1); /* move 27 bytes backward from
the current position in the file */
lseek(f_d, displacement, 1); /* move displacement bytes
from the current position in the file */
P19
UNIX System Interface|Performing Random Access|11-5.3|6,56
The following operations produce incorrect results:
lseek(f_d, -10L,0); /* trying to go backward from
the beginning of the file */
lseek(f_d, 7L, 2); /* trying to go forward from
the end of the file */
P20
UNIX System Interface|Performing Random Access|11-5.4|16,57
The following is a file version of an example we saw in
Lesson 10. Please note the following points. The call
lseek(f_d, 0L,2) will return the size of the file in
bytes, (the number of bytes from the beginning to the
end of the file). When this number is divided by the
structure size, ACCT_SIZE, that will give us the number
of structures in the file. The index limit is n-1,
which is the upper limit for the binary search. All
displacements are scaled by ACCT_SIZE. The read()
statement uses a pointer to a structure as a pointer
to a buffer - which makes all structure elements pop
into the right place, eliminating any conversions or
temporary buffering. The binary search algorithm is
otherwise identical to the simplest case with an array
of integers. Also note the advantage of binary I/O
when one is dealing with large data objects.
P21
UNIX System Interface|Performing Random Access|11-5.5|13,54
/* Random access example */
/* Assume that one must supply a user id and a password
in order to log on to a system. This system has a
file called userpass which contains the data on valid
accounts. This file is made up of records of the
following form: */
typedef struct {
char user_id[21]; /* user id */
char password[16]; /* encrypted password */
long date; /* encoded expiration date */
} account;
P22
UNIX System Interface|Performing Random Access|11-5.6|7,57
/* Random Access Example (continued) */
/* The records are sorted using "user_id" as the keyword
and are stored in the file in ascending order. The
following function will search the file for a matching
account and return TRUE if account exists, FALSE if it
doesn't. NOTE: The binary search algorithm is used.*/
P23
UNIX System Interface|Performing Random Access|11-5.7|17,54
/* Random Access Example (continued) */
#define TRUE 1
#define FALSE 0
#define ACCT_SIZE sizeof (account)
validate(acct_rec, f_d)
account *acct_rec; /* pointer to user's acct */
int f_d; /* account file descriptor */
{
account buffer; /* account rec. buffer */
long displ; /* file displacement */
int low, high, mid, cond;
long lseek(); /* random seeking function */
low = 0;
P24
UNIX System Interface|Performing Random Access|11-5.8|13,45
/* Random Access Example (continued) */
/* determine the number of accounts */
high = ((lseek(f_d, 0L, 2))/(ACCT_SIZE)) - 1;
while (low <= high) {
mid = (low + high) / 2;
displ = mid * ACCT_SIZE;
/* Move file descriptor to next rec. */
if ((lseek(f_d, displ, 0)) == -1)
break;
P25
UNIX System Interface|Performing Random Access|11-5.9|13,49
/* Random Access Example (continued) */
/* Read the current acct. record */
if ( read(f_d, &buffer, acct_size)
== acct_size) {
/* check validity */
if ((cond = strcmp(buffer.user_id,
acct_rec->user_id)) < 0)
high = mid - 1;
else if (cond > 0)
low = mid + 1;
else{ /* Check if password and date match */
P26
UNIX System Interface|Performing Random Access|11-5.10|16,49
/* Random Access Example (continued) */
if ((strcmp(buffer.password,
acct_rec->password) == 0) &&
buffer.date >= acct_rec->date)
return(TRUE);
else
return(FALSE);
}
} /* read a record of wrong size, => error */
else
return(false);
}
/* no match found return error code */
return(false);
}
P27
UNIX System Interface|Performing Binary Standard I/O|11-6.1|16,54
Standard I/O files may be treated as binary files.
The UNIX shell opens three files for every program it
runs:
file descriptor
* The standard input file 0
* The standard output file 1
* The standard error file 2
Therefore, terminal I/O may as well be performed
in binary format.
P28
UNIX System Interface|Performing Binary Standard I/O|11-6.2|17,58
The following is a binary version of the previous example.
The primary difference is the way the data is read. All
data is referred to by size. The variables of type other
than char must be converted prior to being stored
in the corresponding variable. The C library function
atoi() does ascii-to-integer conversion; therefore, its
argument must be properly terminated with a '\0'. A
subtle point which may cause some headaches is the reading
of a the newline character, read(0,buffer,1), in the function
read_client(). Since the program assumes that there will be
6 specialties, then 6 specialties columns must have data in
them (blanks or X's). A newline after the 3rd specialty
or blanks after the 6th specialty will confuse the program
and produce incorrect results. It is a project for the
student to improve the program and make it robust so it
does not matter after which column the '\n' character
is placed.
P29
UNIX System Interface|Performing Binary Standard I/O|11-6.3|11,54
/* Professional Search Agency Problem
Binary Standard I/O Version */
#include <stdio.h>
/* External declarations */
struct candidate {
char id[51]; /* name and tel. no */
short salary; /* salary in $Ks */
short experience; /* years of experience */
char specialties[6]; /* areas of specialization */
};
P30
UNIX System Interface|Performing Binary Standard I/O|11-6.4|15,57
/* Search Agency Problem--Binary Version (continued) */
main()
{
struct candidate request, person;
printf("\n\nThe following candidates meet");
printf("The Requirements\n");
if ((read_client(&request) != EOF))
while ((read_client(&person) != eof))
if (compatible(&request, &person)) {
write(1,person.id, 50);
write(1,"\n",1);
}
}
P31
UNIX System Interface|Performing Binary Standard I/O|11-6.5|18,54
/* Search Agency Problem--Binary Version (continued) */
read_client(client) /* read client info. */
struct candidate *client;
{ char buffer[3];
/* READ IDENTITY */
if (read(0, client->id,50) == 50) {
/* THEN THERE IS A FULL RECORD */
client->id[50] = '\0';
/* READ CLIENT'S SALARY */
read(0, buffer,2); buffer[2] = '\0';
client->salary = atoi(buffer);
/* READ YEARS OF EXPERIENCE */
read(0, buffer,2); buffer[2] = '\0';
client->experience = atoi(buffer);
/* READ IN CLIENT'S SPECIALTIES */
read(0,client->specialties,6);
read(0,buffer,1); /* read new line */
return(1); return(EOF); } }
P32
UNIX System Interface|Performing Binary Standard I/O|11-6.6|18,58
/* Search Agency Problem--Binary Version (continued) */
#define TRUE 1
#define FALSE 0
compatible(request, client)
struct candidate *request, *client;
{
int compat=false, i;
if (((client->salary - request->salary) <= 3) &&
((request->experience - client->experience) <= 2)){
for (i=0; i < 6; i++)
client->specialties[i] == 'X') {
compat = TRUE;
break;
}
}
return compat;
}
P33
UNIX System Interface|Performing Binary Standard I/O|11-6.7|14,57
/* Search Agency Problem--Binary Version (continued) */
/* Note that the input must contain an entry for each
specialty, a blank or an "x", followed immediately
by a newline.
/*** THE INPUT ****/
REQUEST 4810 X
Alex Anderson (818) 279-1436 4408X X X
Alice Jordan (202) 347-9245 3604 XX
Michele Hopkins (213) 319-3400 5214X X X
John Holdridge (617) 236-1746 4711 X X X
Judy Boston (619) 362-9867 4509X X
Richard Wilson (408) 988-5249 4810XX
P34
UNIX System Interface|Performing Binary Standard I/O|11-6.8|8,54
/* Search Agency Problem--Binary Version (continued) */
/*** The OUTPUT ***/
The following candidates meet the requirements:
Alex Anderson (818) 279-1436
Judy Boston (619) 362-9867