| lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame] | 1 | #include <errno.h> | 
|  | 2 | #include <stdio.h> | 
|  | 3 | #include <stdlib.h> | 
|  | 4 | #include <unistd.h> | 
|  | 5 |  | 
|  | 6 |  | 
|  | 7 | static char fname[] = "/tmp/rndseek.XXXXXX"; | 
|  | 8 | static char tempdata[65 * 1024]; | 
|  | 9 |  | 
|  | 10 |  | 
|  | 11 | static int do_test (void); | 
|  | 12 | #define TEST_FUNCTION do_test () | 
|  | 13 | #define TIMEOUT 10 | 
|  | 14 |  | 
|  | 15 | #include "../test-skeleton.c" | 
|  | 16 |  | 
|  | 17 |  | 
|  | 18 | static int | 
|  | 19 | fp_test (const char *name, FILE *fp) | 
|  | 20 | { | 
|  | 21 | int result = 0; | 
|  | 22 | int rounds = 10000; | 
|  | 23 |  | 
|  | 24 | do | 
|  | 25 | { | 
|  | 26 | int idx = random () % (sizeof (tempdata) - 2); | 
|  | 27 | char ch1; | 
|  | 28 | char ch2; | 
|  | 29 |  | 
|  | 30 | if (fseek (fp, idx, SEEK_SET) != 0) | 
|  | 31 | { | 
|  | 32 | printf ("%s: %d: fseek failed: %m\n", name, rounds); | 
|  | 33 | result = 1; | 
|  | 34 | break; | 
|  | 35 | } | 
|  | 36 |  | 
|  | 37 | ch1 = fgetc_unlocked (fp); | 
|  | 38 | ch2 = tempdata[idx]; | 
|  | 39 | if (ch1 != ch2) | 
|  | 40 | { | 
|  | 41 | printf ("%s: %d: character at index %d not what is expected ('%c' vs '%c')\n", | 
|  | 42 | name, rounds, idx, ch1, ch2); | 
|  | 43 | result = 1; | 
|  | 44 | break; | 
|  | 45 | } | 
|  | 46 |  | 
|  | 47 | ch1 = fgetc (fp); | 
|  | 48 | ch2 = tempdata[idx + 1]; | 
|  | 49 | if (ch1 != ch2) | 
|  | 50 | { | 
|  | 51 | printf ("%s: %d: character at index %d not what is expected ('%c' vs '%c')\n", | 
|  | 52 | name, rounds, idx + 1, ch1, ch2); | 
|  | 53 | result = 1; | 
|  | 54 | break; | 
|  | 55 | } | 
|  | 56 | } | 
|  | 57 | while (--rounds > 0); | 
|  | 58 |  | 
|  | 59 | fclose (fp); | 
|  | 60 |  | 
|  | 61 | return result; | 
|  | 62 | } | 
|  | 63 |  | 
|  | 64 |  | 
|  | 65 | static int | 
|  | 66 | do_test (void) | 
|  | 67 | { | 
|  | 68 | int fd; | 
|  | 69 | FILE *fp; | 
|  | 70 | size_t i; | 
|  | 71 | int result; | 
|  | 72 |  | 
|  | 73 | fd = mkstemp (fname); | 
|  | 74 | if (fd == -1) | 
|  | 75 | { | 
|  | 76 | printf ("cannot open temporary file: %m\n"); | 
|  | 77 | return 1; | 
|  | 78 | } | 
|  | 79 | /* Make sure the file gets removed.  */ | 
|  | 80 | add_temp_file (fname); | 
|  | 81 |  | 
|  | 82 | /* Repeatability demands this.  */ | 
|  | 83 | srandom (42); | 
|  | 84 |  | 
|  | 85 | /* First create some temporary data.  */ | 
|  | 86 | for (i = 0; i < sizeof (tempdata); ++i) | 
|  | 87 | tempdata[i] = 'a' + random () % 26; | 
|  | 88 |  | 
|  | 89 | /* Write this data to a file.  */ | 
|  | 90 | if (TEMP_FAILURE_RETRY (write (fd, tempdata, sizeof (tempdata))) | 
|  | 91 | != sizeof (tempdata)) | 
|  | 92 | { | 
|  | 93 | printf ("cannot wrote data to temporary file: %m\n"); | 
|  | 94 | return 1; | 
|  | 95 | } | 
|  | 96 |  | 
|  | 97 | /* Now try reading the data.  */ | 
|  | 98 | fp = fdopen (dup (fd), "r"); | 
|  | 99 | if (fp == NULL) | 
|  | 100 | { | 
|  | 101 | printf ("cannot duplicate temporary file descriptor: %m\n"); | 
|  | 102 | return 1; | 
|  | 103 | } | 
|  | 104 |  | 
|  | 105 | rewind (fp); | 
|  | 106 | for (i = 0; i < sizeof (tempdata); ++i) | 
|  | 107 | { | 
|  | 108 | int ch0 = fgetc (fp); | 
|  | 109 | char ch1 = ch0; | 
|  | 110 | char ch2 = tempdata[i]; | 
|  | 111 |  | 
|  | 112 | if (ch0 == EOF) | 
|  | 113 | { | 
|  | 114 | puts ("premature end of file while reading data"); | 
|  | 115 | return 1; | 
|  | 116 | } | 
|  | 117 |  | 
|  | 118 | if (ch1 != ch2) | 
|  | 119 | { | 
|  | 120 | printf ("%zd: '%c' vs '%c'\n", i, ch1, ch2); | 
|  | 121 | return 1; | 
|  | 122 | } | 
|  | 123 | } | 
|  | 124 |  | 
|  | 125 | result = fp_test ("fdopen(\"r\")", fp); | 
|  | 126 |  | 
|  | 127 | fp = fopen (fname, "r"); | 
|  | 128 | result |= fp_test ("fopen(\"r\")", fp); | 
|  | 129 |  | 
|  | 130 | fp = fopen64 (fname, "r"); | 
|  | 131 | result |= fp_test ("fopen64(\"r\")", fp); | 
|  | 132 |  | 
|  | 133 | /* The "rw" mode will prevent the mmap-using code from being used.  */ | 
|  | 134 | fp = fdopen (fd, "rw"); | 
|  | 135 | result = fp_test ("fdopen(\"rw\")", fp); | 
|  | 136 |  | 
|  | 137 | fp = fopen (fname, "rw"); | 
|  | 138 | result |= fp_test ("fopen(\"rw\")", fp); | 
|  | 139 |  | 
|  | 140 | fp = fopen64 (fname, "rw"); | 
|  | 141 | result |= fp_test ("fopen64(\"rw\")", fp); | 
|  | 142 |  | 
|  | 143 | return result; | 
|  | 144 | } |