?? p4
字號:
.NHLOW-LEVEL I/O.PPThis section describes the bottom level of I/O on the.UC UNIXsystem.The lowest level of I/O in.UC UNIXprovides no buffering or any other services;it is in fact a direct entry into the operating system.You are entirely on your own,but on the other hand,you have the most control over what happens.And since the calls and usage are quite simple,this isn't as bad as it sounds..NH 2File Descriptors.PPIn the.UC UNIXoperating system,all input and output is doneby reading or writing files,because all peripheral devices, even the user's terminal,are files in the file system.This means that a single, homogeneous interfacehandles all communication between a program and peripheral devices..PPIn the most general case,before reading or writing a file,it is necessary to inform the systemof your intent to do so,a process called``opening'' the file.If you are going to write on a file,it may also be necessary to create it.The system checks your right to do so(Does the file exist?Do you have permission to access it?),and if all is well,returns a small positive integercalled a.ulfile descriptor.Whenever I/O is to be done on the file,the file descriptor is used instead of the name to identify the file.(This is roughly analogous to the use of.UC READ(5,...)and.UC WRITE(6,...)in Fortran.)Allinformation about an open file is maintained by the system;the user program refers to the fileonlyby the file descriptor..PPThe file pointers discussed in section 3are similar in spirit to file descriptors,but file descriptors are more fundamental.A file pointer is a pointer to a structure that contains,among other things, the file descriptor for the file in question..PPSince input and output involving the user's terminalare so common,special arrangements exist to make this convenient.When the command interpreter (the``shell'')runs a program,it opensthree files, with file descriptors 0, 1, and 2,called the standard input,the standard output, and the standard error output.All of these are normally connected to the terminal,so if a program reads file descriptor 0and writes file descriptors 1 and 2,it can do terminal I/Owithout worrying about opening the files..PPIf I/O is redirected to and from files with.UL < and.UL > ,as in.P1prog <infile >outfile.P2the shell changes the default assignments for file descriptors0 and 1from the terminal to the named files.Similar observations hold if the input or output is associated with a pipe.Normally file descriptor 2 remains attached to the terminal,so error messages can go there.In all cases,the file assignments are changed by the shell,not by the program.The program does not need to know where its inputcomes from nor where its output goes,so long as it uses file 0 for input and 1 and 2 for output..NH 2Read and Write.PPAll input and output is done bytwo functions called.UL readand.UL write .For both, the first argument is a file descriptor.The second argument is a buffer in your program where the data is tocome from or go to.The third argument is the number of bytes to be transferred.The calls are.P1n_read = read(fd, buf, n);n_written = write(fd, buf, n);.P2Each call returns a byte countwhich is the number of bytes actually transferred.On reading,the number of bytes returned may be less thanthe number asked for,because fewer than.UL nbytes remained to be read.(When the file is a terminal,.UL readnormally reads only up to the next newline,which is generally less than what was requested.)A return value of zero bytes implies end of file,and.UL -1indicates an error of some sort.For writing, the returned value is the number of bytesactually written;it is generally an error if this isn't equalto the number supposed to be written..PPThe number of bytes to be read or written is quite arbitrary.The two most common values are 1,which means one character at a time(``unbuffered''),and512,which corresponds to a physical blocksize on many peripheral devices.This latter size will be most efficient,but even character at a time I/Ois not inordinately expensive..PPPutting these facts together,we can write a simple program to copyits input to its output.This program will copy anything to anything,since the input and output can be redirected to any file or device..P1#define BUFSIZE 512 /* best size for PDP-11 UNIX */main() /* copy input to output */{ char buf[BUFSIZE]; int n; while ((n = read(0, buf, BUFSIZE)) > 0) write(1, buf, n); exit(0);}.P2If the file size is not a multiple of.UL BUFSIZE ,some .UL readwill return a smaller number of bytesto be written by.UL write ;the next call to .UL readafter thatwill return zero..PPIt is instructive to see how.UL readand.UL writecan be used to constructhigher level routines like.UL getchar ,.UL putchar ,etc.For example,here is a version of.UL getcharwhich does unbuffered input..P1#define CMASK 0377 /* for making char's > 0 */getchar() /* unbuffered single character input */{ char c; return((read(0, &c, 1) > 0) ? c & CMASK : EOF);}.P2.UL c.ulmustbe declared.UL char ,because.UL readaccepts a character pointer.The character being returned must be masked with.UL 0377to ensure that it is positive;otherwise sign extension may make it negative.(The constant.UL 0377is appropriate for the.UC PDP -11but not necessarily for other machines.).PPThe second version of.UL getchardoes input in big chunks,and hands out the characters one at a time..P1#define CMASK 0377 /* for making char's > 0 */#define BUFSIZE 512getchar() /* buffered version */{ static char buf[BUFSIZE]; static char *bufp = buf; static int n = 0; if (n == 0) { /* buffer is empty */ n = read(0, buf, BUFSIZE); bufp = buf; } return((--n >= 0) ? *bufp++ & CMASK : EOF);}.P2.NH 2Open, Creat, Close, Unlink.PPOther than the defaultstandard input, output and error files,you must explicitly open files in order toread or write them.There are two system entry points for this,.UL openand.UL creat [sic]..PP.UL openis rather like the.UL fopendiscussed in the previous section,except that instead of returning a file pointer,it returns a file descriptor,which is just an.UL int ..P1int fd;fd = open(name, rwmode);.P2As with.UL fopen ,the.UL nameargumentis a character string corresponding to the external file name.The access mode argumentis different, however:.UL rwmodeis 0 for read, 1 for write, and 2 for read and write access..UL openreturns.UL -1if any error occurs;otherwise it returns a valid file descriptor..PPIt is an error to try to.UL opena file that does not exist.The entry point.UL creatis provided to create new files,or to re-write old ones..P1fd = creat(name, pmode);.P2returns a file descriptorif it was able to create the filecalled.UL name ,and.UL -1if not.If the filealready exists,.UL creatwill truncate it to zero length;it is not an error to.UL creata file that already exists..PPIf the file is brand new,.UL creatcreates it with the.ulprotection mode specified bythe.UL pmodeargument.In the.UC UNIXfile system,there are nine bits of protection informationassociated with a file,controlling read, write and execute permission forthe owner of the file,for the owner's group,and for all others.Thus a three-digit octal numberis most convenient for specifying the permissions.For example,0755specifies read, write and execute permission for the owner,and read and execute permission for the group and everyone else..PPTo illustrate,here is a simplified version ofthe.UC UNIXutility.IT cp ,a program which copies one file to another.(The main simplification is that our versioncopies only one file,and does not permit the second argumentto be a directory.).P1#define NULL 0#define BUFSIZE 512#define PMODE 0644 /* RW for owner, R for group, others */main(argc, argv) /* cp: copy f1 to f2 */int argc;char *argv[];{ int f1, f2, n; char buf[BUFSIZE]; if (argc != 3) error("Usage: cp from to", NULL); if ((f1 = open(argv[1], 0)) == -1) error("cp: can't open %s", argv[1]); if ((f2 = creat(argv[2], PMODE)) == -1) error("cp: can't create %s", argv[2]); while ((n = read(f1, buf, BUFSIZE)) > 0) if (write(f2, buf, n) != n) error("cp: write error", NULL); exit(0);}.P2.P1error(s1, s2) /* print error message and die */char *s1, *s2;{ printf(s1, s2); printf("\n"); exit(1);}.P2.PPAs we said earlier,there is a limit (typically 15-25)on the number of files which a programmay have open simultaneously.Accordingly, any program which intends to processmany files must be prepared to re-usefile descriptors.The routine.UL closebreaks the connection between a file descriptorand an open file,and frees thefile descriptor for use with some other file.Termination of a programvia.UL exitor return from the main program closes all open files..PPThe function.UL unlink(filename)removes the file.UL filenamefrom the file system..NH 2Random Access \(em Seek and Lseek.PPFile I/O is normally sequential:each.UL reador.UL writetakes place at a position in the fileright after the previous one.When necessary, however,a file can be read or written in any arbitrary order.Thesystem call.UL lseekprovides a way to move around ina file without actually readingor writing:.P1lseek(fd, offset, origin);.P2forces the current position in the filewhose descriptor is.UL fdto move to position.UL offset ,which is taken relative to the locationspecified by.UL origin .Subsequent reading or writing will begin at that position..UL offsetisa.UL long ;.UL fdand.UL originare.UL int 's..UL origincan be 0, 1, or 2 to specify that .UL offsetis to bemeasured fromthe beginning, from the current position, or from theend of the file respectively.For example,to append to a file,seek to the end before writing:.P1lseek(fd, 0L, 2);.P2To get back to the beginning (``rewind''),.P1lseek(fd, 0L, 0);.P2Notice the.UL 0Largument;it could also be written as.UL (long)\ 0 ..PPWith .UL lseek ,it is possible to treat files more or less like large arrays,at the price of slower access.For example, the following simple function reads any number of bytesfrom any arbitrary place in a file..P1get(fd, pos, buf, n) /* read n bytes from position pos */int fd, n;long pos;char *buf;{ lseek(fd, pos, 0); /* get to pos */ return(read(fd, buf, n));}.P2.PPIn pre-version 7.UC UNIX ,the basic entry point to the I/O systemis called.UL seek ..UL seekis identical to.UL lseek ,except that its.UL offset argument is an.UL intrather than a.UL long .Accordingly,since.UC PDP -11integers have only 16 bits,the.UL offsetspecifiedfor.UL seekis limited to 65,535;for this reason,.UL originvalues of 3, 4, 5 cause.UL seekto multiply the given offset by 512(the number of bytes in one physical block)and then interpret.UL originas if it were 0, 1, or 2 respectively.Thus to get to an arbitrary place in a large filerequires two seeks, first one which selectsthe block, then one whichhas.UL originequal to 1 and moves to the desired byte within the block..NH 2Error Processing.PPThe routines discussed in this section,and in fact all the routines which are direct entries into the systemcan incur errors.Usually they indicate an error by returning a value of \-1.Sometimes it is nice to know what sort of error occurred;for this purpose all these routines, when appropriate,leave an error number in the external cell.UL errno .The meanings of the various error numbers arelistedin the introduction to Section IIof the.I.UC UNIXProgrammer's Manual,.Rso your program can, for example, determine ifan attempt to open a file failed because it did not existor because the user lacked permission to read it.Perhaps more commonly,you may want to print out thereason for failure.The routine.UL perrorwill print a message associated with the valueof.UL errno ;more generally,.UL sys\_errnois an array of character strings which can be indexedby.UL errnoand printed by your program.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -