cechew@bruce.OZ (Earl Chew) (09/04/89)
#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 3 (of 7)." # Contents: exercise.c fclose.c fdopen.c fflush.c fgetc.c # Wrapped by cechew@bruce on Mon Sep 4 12:50:14 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'exercise.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'exercise.c'\" else echo shar: Extracting \"'exercise.c'\" \(11973 characters\) sed "s/^X//" >'exercise.c' <<'END_OF_FILE' X/* E x e r c i s e X * X * This program exercises the stdio routines. It does not validate the X * routines but provides a convenient way to quickly check the functionality X * of the code. X */ X X#include <stdio.h> X X#if defined(BSD) X# include <strings.h> X#else X# include <string.h> X#endif X X#define D -123 X#define I 255 X#define U (~0) X#define TESTFILE "test.dat" X#define LARGEBUFS 16 X#if defined(MSDOS) X# define TTY "con" Xvoid (*__cleanup)() = 0; X#else X# define TTY "/dev/tty" X#endif X Xextern void sleep(); /* sleep routine */ X XFILE *fp; /* per test file pointer */ X X/* X * Line Buffered Write Test X * X * Write to a terminal. This tests that the output buffer is X * flushed on receipt of a \n. X */ X Xvoid lbw_test() X X{ X int i; X X puts("\nLine buffered write test"); X if ((fp = fopen(TTY, "w")) != NULL) { X puts("<pause>ABCDEFGH"); X puts("<pause>ABCD<pause>EFGH"); X for (i = 0; i < 8; i++) X putc('A'+i, fp), sleep(1); X putc('\n', fp); X for (i = 0; i < 8; i++) { X putc('A'+i, fp); X if (i == 3) X fflush(fp); X sleep(1); X } X fclose(fp); X puts(""); X } X} X X/* X * Unbuffered Write Test X * X * Test that characters are written directly to the output device X * when the stream is unbuffered. X */ X Xvoid ubw_test() X X{ X int i; X X puts("\nUnbuffered write test"); X if ((fp = fopen(TTY, "w")) != NULL) { X setbuf(fp, (char *) 0); X puts("A<pause>B<pause>C<pause>D<pause>E<pause>F<pause>G<pause>H<pause>"); X puts("A<pause>B<pause>C<pause>D<pause>E<pause>F<pause>G<pause>H<pause>"); X for (i = 0; i < 8; i++) X putc('A'+i, fp), sleep(1); X putc('\n', fp); X for (i = 0; i < 8; i++) X putc('A'+i, fp), sleep(1); X fclose(fp); X puts(""); X } X} X X/* X * Buffered Write Test X * X * Test that the data is written to the terminal on a per buffer X * basis. X */ X Xvoid bw_test() X X{ X int i; X X puts("\nFully buffered write test"); X if ((fp = fopen(TTY, "w")) != NULL) { X setvbuf(fp, (char *) 0, _IOFBF, 4); X puts("<pause>ABCD<pause>EFGH<pause>"); X puts("ABC<pause>DEFG<pause>H"); X for (i = 0; i < 8; i++) X putc('A'+i, fp), sleep(1); X putc('\n', fp); X for (i = 0; i < 8; i++) X putc('A'+i, fp), sleep(1); X fclose(fp); X puts(""); X } X} X X/* Formatted Output Test X * X * This exercises the output formatting code. X */ X Xvoid fp_test() X X{ X int i, j, k, l; X char buf[7]; X char *prefix = buf; X char tp[20]; X X puts("\nFormatted output test"); X printf("prefix 6d 6o 6x 6X 6u\n"); X strcpy(prefix, "%"); X for (i = 0; i < 2; i++) { X for (j = 0; j < 2; j++) { X for (k = 0; k < 2; k++) { X for (l = 0; l < 2; l++) { X strcpy(prefix, "%"); X if (i == 0) strcat(prefix, "-"); X if (j == 0) strcat(prefix, "+"); X if (k == 0) strcat(prefix, "#"); X if (l == 0) strcat(prefix, "0"); X printf("%5s |", prefix); X strcpy(tp, prefix); X strcat(tp, "6d |"); X printf(tp, D); X strcpy(tp, prefix); X strcat(tp, "6o |"); X printf(tp, I); X strcpy(tp, prefix); X strcat(tp, "6x |"); X printf(tp, I); X strcpy(tp, prefix); X strcat(tp, "6X |"); X printf(tp, I); X strcpy(tp, prefix); X strcat(tp, "6u |"); X printf(tp, U); X printf("\n"); X } X } X } X } X} X X/* X * String Output Test X * X * Test the string printf code. X */ X Xvoid sw_test() X X{ X int i; X char buf[80]; X X puts("\nTest sprintf functionality"); X puts("13 bytes in 'Testing 1 2 3'"); X i = sprintf(buf, "Testing %d %d %d", 1, 2, 3); X printf("%d bytes in '%s'\n", i, buf); X} X X/* X * String Input Test X * X * Test the string scanf code. X */ X Xvoid sr_test() X X{ X int i, j; X char buf[80]; X X puts("\nTest sscanf functionality"); X puts("2 items yielding 25 and 'thompson'"); X i = sscanf("25 thompson", "%d%s", &j, buf); X printf("%d items yielding %d and '%s'\n", i, j, buf); X} X X/* X * File Write and Read Test X * X * Test that a file can be written to and read from. X */ X Xvoid frw_test() X X{ X int i, j, k; X char buf[80]; X X puts("\nFile write and read check"); X if ((fp = fopen(TESTFILE, "w")) != NULL) { X puts("3 items yielding 56, 789 and '56'"); X puts("1 item yielding 'a72'"); X fprintf(fp, "56789 0123 56a72"); X if (freopen(TESTFILE, "r", fp) != fp) X puts("Cannot open file for reading"); X else { X i = fscanf(fp, "%2d%d%*d %[0-9]", &j, &k, buf); X printf("%d items yielding %d, %d and '%s'\n", i, j, k, buf); X i = fscanf(fp, "%s", buf); X printf("%d item yielding '%s'\n", i, buf); X fclose(fp); X } X } X} X X/* X * File Seek Test X * X * Test that seek operations within files work. X */ X Xvoid fs_test() X X{ X int i, j; X X puts("\nFile seek test"); X if ((fp = fopen(TESTFILE, "w")) != NULL) { X for (i = 0; i < 256; i++) X putc(i, fp); X if (freopen(TESTFILE, "r", fp) != fp) X puts("Cannot open file for reading"); X else { X for (i = 1; i <= 255; i++) { X printf("\r%3d ", i); X fflush(stdout); X fseek(fp, (long) -i, SEEK_END); X if ((j = getc(fp)) != 256-i) { X printf("SEEK_END failed %d\n", j); X break; X } X if (fseek(fp, (long) i, SEEK_SET)) { X puts("Cannot SEEK_SET"); X break; X } X if ((j = getc(fp)) != i) { X printf("SEEK_SET failed %d\n", j); X break; X } X if (fseek(fp, (long) i, SEEK_SET)) { X puts("Cannot SEEK_SET"); X break; X } X if (fseek(fp, (long) (i >= 128 ? -128 : 128), SEEK_CUR)) { X puts("Cannot SEEK_CUR"); X break; X } X if ((j = getc(fp)) != (i >= 128 ? i-128 : i+128)) { X printf("SEEK_CUR failed %d\n", j); X break; X } X } X if (i > 255) X puts("ok"); X fclose(fp); X } X } X} X X/* X * Test gets() X * X * Checks that gets() works. X */ X Xvoid gets_test() X X{ X char buf[80]; X X puts("\nGets functionality"); X puts("... Type a line and have it echoed ..."); X gets(buf); X puts(buf); X} X X/* X * Fgets Test X * X * Check that fgets() works. X */ X Xvoid fgets_test() X X{ X char buf[80]; X X puts("\nFgets functionality"); X puts("a"); X puts("<pause>ab"); X puts("<pause>abc"); X puts("<pause>abcd"); X puts("<pause>abcde"); X puts("<pause>abcdef"); X puts("<pause>abcdefg<pause>"); X puts("<pause>abcdefg<pause>h"); X if ((fp = fopen(TESTFILE, "w")) != NULL) { X fputs("a\n", fp); X fputs("ab\n", fp); X fputs("abc\n", fp); X fputs("abcd\n", fp); X fputs("abcde\n", fp); X fputs("abcdef\n", fp); X fputs("abcdefg\n", fp); X fputs("abcdefgh\n", fp); X fclose(fp); X if ((fp = fopen(TESTFILE, "r")) != NULL) { X while (fgets(buf, 8, fp) != NULL) { X fputs(buf, stdout); X fflush(stdout); X sleep(1); X } X fclose(fp); X } X } X} X X/* X * Word Read and Write Test X * X * Check that putw and getw work. X */ X Xvoid word_test() X X{ X int i, j; X X puts("\nPutw and Readw Test"); X if ((fp = fopen(TESTFILE, "w")) != NULL) { X for (i = 0; i < 256; i++) X putw(i, fp); X putc(0, fp); X fclose(fp); X if ((fp = fopen(TESTFILE, "r")) != NULL) { X for (i = 0; i < 256; i++) { X printf("\r%3d", i); X fflush(stdout); X if ((j = getw(fp)) != i) { X printf(" failed %d", j); X break; X } X } X if (i == 256 /* && getw(fp) == EOF && feof(fp)*/) X fputs(" ok", stdout); X puts(""); X fclose(fp); X } X } X} X X/* X * Write and Read Update Test X * X * Write a file in update mode, then try to read it. X */ X Xvoid uwr_test() X X{ X int i, j; X X puts("\nWrite and Read Update Test"); X if ((fp = fopen(TESTFILE, "w+")) != NULL) { X for (i = 0; i < (3*BUFSIZ)/2; i++) X putc(i, fp); X rewind(fp); X for (i = 0; i < (3*BUFSIZ)/2; i++) { X printf("\r%4d", i); X fflush(stdout); X j = getc(fp); X if (j != (unsigned char) i) { X printf(" failed %d\n", j); X break; X } X } X if (i == (3*BUFSIZ)/2) X puts(" ok"); X if (getc(fp) != EOF) X puts(" failed to find eof"); X else { X for (i = 0; i < BUFSIZ/2; i++) X putc(i, fp); X fseek(fp, (long) (3*BUFSIZ)/2, SEEK_SET); X for (i = 0; i < BUFSIZ/2; i++) { X printf("\r%4d", i); X fflush(stdout); X j = getc(fp); X if (j != (unsigned char) i) { X printf(" failed %d\n", j); X break; X } X } X if (i == BUFSIZ/2) X puts(" ok"); X } X fclose(fp); X } X} X X/* X * Write, Append and Read Update Test X * X * Write a file in update mode, close it, append to it and read it. X */ X Xvoid uawr_test() X X{ X int i, j; X X puts("\nWrite, Append and Read Update Test"); X if ((fp = fopen(TESTFILE, "w")) != NULL) { X for (i = 0; i < (3*BUFSIZ)/2; i++) X putc(i, fp); X fclose(fp); X if ((fp = fopen(TESTFILE, "a+")) != NULL) { X for (i = 0; i < BUFSIZ/2; i++) X putc(i, fp); X fseek(fp, (long) (3*BUFSIZ)/2, SEEK_SET); X for (i = 0; i < BUFSIZ/2; i++) { X printf("\r%4d", i); X fflush(stdout); X j = getc(fp); X if (j != (unsigned char) i) { X printf(" failed %d\n", j); X break; X } X } X if (i == BUFSIZ/2) X puts(" ok"); X rewind(fp); X for (i = 0; i < (3*BUFSIZ)/2; i++) { X printf("\r%4d", i); X fflush(stdout); X j = getc(fp); X if (j != (unsigned char) i) { X printf(" failed at %d\n", j); X break; X } X } X if (i == (3*BUFSIZ)/2) X puts(" ok"); X } X fclose(fp); X } X} X X/* X * Write, Read, Write and Read Update Test X * X * Write a file in update mode, read it, write it and read it. X */ X Xvoid uwrwr_test() X X{ X int i, j; X X puts("\nWrite and Read Update Test"); X if ((fp = fopen(TESTFILE, "w")) != NULL) { X for (i = 0; i < (3*BUFSIZ)/2; i++) X putc(i, fp); X fclose(fp); X if ((fp = fopen(TESTFILE, "r+")) != NULL) { X for (i = 0; i < (3*BUFSIZ)/2; i++) { X printf("\r%4d", i); X fflush(stdout); X j = getc(fp); X if (j != (unsigned char) i) { X printf(" failed %d\n", j); X break; X } X } X if (i == (3*BUFSIZ)/2) X puts(" ok"); X if (getc(fp) != EOF) X puts(" failed to find eof"); X else { X for (i = 0; i < BUFSIZ/2; i++) X putc(i, fp); X rewind(fp); X for (i = 0; i < (3*BUFSIZ)/2; i++) X putc((3*BUFSIZ)/2-i, fp); X fseek(fp, (long) (3*BUFSIZ)/2, SEEK_SET); X for (i = 0; i < BUFSIZ/2; i++) { X printf("\r%4d", i); X fflush(stdout); X j = getc(fp); X if (j != (unsigned char) i) { X printf(" failed %d\n", j); X break; X } X } X if (i == BUFSIZ/2) X puts(" ok"); X rewind(fp); X for (i = 0; i < (3*BUFSIZ)/2; i++) { X printf("\r%4d", i); X fflush(stdout); X j = getc(fp); X if (j != (unsigned char) ((3*BUFSIZ)/2-i)) { X printf(" failed %d\n", j); X break; X } X } X if (i == (3*BUFSIZ)/2) X puts(" ok"); X } X fclose(fp); X } X } X} X X/* X * Fwrite Test X * X * Test fwrite with small loads and large loads. X */ X Xvoid fwrite_test() X X{ X int i, j; X char buf[1023]; X char bbuf[3071]; X double sqrt(); X void *malloc(); X X puts("\nFwrite Test"); X if ((fp = fopen(TESTFILE, "w+")) != NULL) { X X for (i = 0; i < sizeof(buf); i++) X buf[i] = i; X for (i = 0; i < sizeof(bbuf); i++) X bbuf[i] = 19-i; X X for (i = 0; i < 256; i++) { X printf("\r%4d", i); X fflush(stdout); X if (fwrite(buf, 1, sizeof(buf), fp) != sizeof(buf)) { X puts(" failed\n"); X return; X } X putc(0, fp); X } X puts(" small write ok"); X rewind(fp); X for (i = 0; i < 256; i++) { X printf("\r%4d", i); X fflush(stdout); X for (j = 0; j < sizeof(buf); j++) { X if (getc(fp) != (unsigned char) j) { X puts(" failed\n"); X return; X } X } X if (getc(fp) != 0) { X puts(" failed\n"); X return; X } X } X puts(" verified ok"); X X rewind(fp); X for (i = 0; i < 256; i++) { X printf("\r%4d", i); X fflush(stdout); X if (fwrite(bbuf, 1, sizeof(bbuf), fp) != sizeof(bbuf)) { X puts(" failed\n"); X return; X } X putc(0, fp); X } X puts(" large write ok"); X rewind(fp); X for (i = 0; i < 256; i++) { X printf("\r%4d", i); X fflush(stdout); X for (j = 0; j < sizeof(bbuf); j++) { X if (getc(fp) != (unsigned char) (19-j)) { X puts(" failed\n"); X return; X } X } X if (getc(fp) != 0) { X puts(" failed\n"); X return; X } X } X puts(" verified ok"); X } X} X Xint main() X X{ X lbw_test(); X ubw_test(); X bw_test(); X fp_test(); X sw_test(); X sr_test(); X frw_test(); X fs_test(); X gets_test(); X fgets_test(); X word_test(); X fwrite_test(); X uwr_test(); X uawr_test(); X uwrwr_test(); X return 0; X} END_OF_FILE if test 11973 -ne `wc -c <'exercise.c'`; then echo shar: \"'exercise.c'\" unpacked with wrong size! fi # end of 'exercise.c' fi if test -f 'fclose.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'fclose.c'\" else echo shar: Extracting \"'fclose.c'\" \(1110 characters\) sed "s/^X//" >'fclose.c' <<'END_OF_FILE' X/* f c l o s e X * X * This function will flush any buffered data for the specified X * stream, then close it. Buffers that have been allocated X * to the stream by the stdio library will be freed. Buffers X * that have been allocated explicitly by the user will not X * be freed. It is the user's responsibility to free these X * if so required. This function is called automagically from X * exit(). X * X * The function returns 0 on success and EOF if an error was X * detected. X * X * Patchlevel 1.0 X * X * Edit History: X */ X X#include "stdiolib.h" X X/*LINTLIBRARY*/ X Xint fclose(fp) X XFILE *fp; /* stream */ X X{ X FILE **sp; /* slot */ X int close(); /* close a channel */ X void free(); /* free allocated memory */ X X/* Free slot occupied by this stream */ X if ((sp = _slot(fp)) == NULL) X return EOF; X if (sp - _iop > 2) X *sp = NULL; X X/* Flush any pending buffers */ X (void) fflush(fp); X X/* Close this channel */ X if (close(fp->_file)) X return EOF; X X/* Free allocated buffer */ X if (TESTFLAG(fp, _IOMYBUF)) X free((void *) fp->_base); X if (*sp == NULL) X free((void *) fp); X X return 0; X} END_OF_FILE if test 1110 -ne `wc -c <'fclose.c'`; then echo shar: \"'fclose.c'\" unpacked with wrong size! fi # end of 'fclose.c' fi if test -f 'fdopen.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'fdopen.c'\" else echo shar: Extracting \"'fdopen.c'\" \(785 characters\) sed "s/^X//" >'fdopen.c' <<'END_OF_FILE' X/* f d o p e n X * X * Open a stream and associate it with a file descriptor. The X * file descriptor would typically have been obtained from either X * a call to open(), dup(), creat() or pipe(). The type of stream X * (read, write or append) must agree with the mode of the open X * file. X * X * The function returns a pointer to the stream on success and X * NULL on failure. X * X * Patchlevel 1.0 X * X * Edit History: X */ X X#include "stdiolib.h" X X/*LINTLIBRARY*/ X XFILE *fdopen(fd, mode) X Xint fd; /* channel */ Xchar *mode; /* mode to open */ X X{ X FILE **sp; /* slot in table */ X short flags; /* flag settings */ X X return (sp = _slot((FILE *) NULL)) == NULL || X fd != _fopen((char *) NULL, mode, fd, &flags) X ? NULL X : (*sp = _file((FILE *) NULL, fd, flags)); X} END_OF_FILE if test 785 -ne `wc -c <'fdopen.c'`; then echo shar: \"'fdopen.c'\" unpacked with wrong size! fi # end of 'fdopen.c' fi if test -f 'fflush.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'fflush.c'\" else echo shar: Extracting \"'fflush.c'\" \(899 characters\) sed "s/^X//" >'fflush.c' <<'END_OF_FILE' X/* f f l u s h X * X * Flush a stream. The contents of the buffer are written to the X * file if the stream was opened for writing. The buffer pointers X * are reset to indicate an empty buffer. X * X * The function returns zero on success and EOF on failure. X * X * Patchlevel 1.0 X * X * Edit History: X * 03-Sep-1989 Flush input buffer only if it exists. X */ X X#include "stdiolib.h" X X/*LINTLIBRARY*/ X Xint fflush(fp) X XFILE *fp; /* stream */ X X{ X int length; /* amount to flush */ X int write(); /* write to channel */ X X if (TESTFLAG(fp, _IOERR)) X return EOF; X X if (! TESTFLAG(fp, _IOWRITE)) { X if (HASBUFFER(fp)) X INITREADBUFFER(fp, 0); X } X else { X if (! TESTFLAG(fp, _IONBF) && X (length = fp->_ptr - fp->_base) != 0 && X write(fp->_file, (char *) fp->_base, length) != length) X return EOF; X if (HASBUFFER(fp)) X INITWRITEBUFFER(fp); X } X X return 0; X} END_OF_FILE if test 899 -ne `wc -c <'fflush.c'`; then echo shar: \"'fflush.c'\" unpacked with wrong size! fi # end of 'fflush.c' fi if test -f 'fgetc.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'fgetc.c'\" else echo shar: Extracting \"'fgetc.c'\" \(377 characters\) sed "s/^X//" >'fgetc.c' <<'END_OF_FILE' X/* f g e t c X * X * This is the getc() macro wrapped inside a function. This behaves X * similarly to getc() but runs more slowly. It takes up less X * space per invocation and its name can be passed as an argument X * to other functions. X * X * Patchlevel 1.0 X * X * Edit History: X */ X X#include "stdiolib.h" X X/*LINTLIBRARY*/ X Xint fgetc(iop) X XFILE *iop; X X{ X return getc(iop); X} X END_OF_FILE if test 377 -ne `wc -c <'fgetc.c'`; then echo shar: \"'fgetc.c'\" unpacked with wrong size! fi # end of 'fgetc.c' fi echo shar: End of archive 3 \(of 7\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 4 5 6 7 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 7 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0