00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <sys/types.h>
00035 #include <sys/stat.h>
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <unistd.h>
00040 #include <errno.h>
00041 #include <err.h>
00042
00043 #include "config.h"
00044 #include "test.h"
00045
00046 static
00047 void
00048 lseek_fd_device(void)
00049 {
00050 int fd, rv;
00051
00052 fd = open("null:", O_RDONLY);
00053 if (fd<0) {
00054 warn("UH-OH: opening null: failed");
00055 return;
00056 }
00057
00058 rv = lseek(fd, 309, SEEK_SET);
00059 report_test(rv, errno, ESPIPE, "lseek on device");
00060
00061 close(fd);
00062 }
00063
00064 static
00065 void
00066 lseek_file_stdin(void)
00067 {
00068 int fd, fd2, rv, status;
00069 const char slogan[] = "There ain't no such thing as a free lunch";
00070 size_t len = strlen(slogan);
00071 pid_t pid;
00072
00073
00074 pid = fork();
00075 if (pid<0) {
00076 warn("UH-OH: fork failed");
00077 return;
00078 }
00079 else if (pid!=0) {
00080
00081 rv = waitpid(pid, &status, 0);
00082 if (rv<0) {
00083 warn("UH-OH: waitpid failed");
00084 }
00085 if (WIFSIGNALED(status)) {
00086 warn("UH-OH: subprocess exited with signal %d",
00087 WTERMSIG(status));
00088 }
00089 else if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
00090 warn("UH-OH: subprocess exited with code %d",
00091 WEXITSTATUS(status));
00092 }
00093 return;
00094 }
00095
00096
00097
00098 fd = open_testfile(NULL);
00099 if (fd<0) {
00100 _exit(0);
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110 fd2 = dup2(fd, STDIN_FILENO);
00111 if (fd2<0) {
00112 warn("UH-OH: dup2 to stdin failed");
00113 close(fd);
00114 remove(TESTFILE);
00115 _exit(0);
00116 }
00117 if (fd2 != STDIN_FILENO) {
00118 warn("UH-OH: dup2 returned wrong file handle");
00119 close(fd);
00120 remove(TESTFILE);
00121 _exit(0);
00122 }
00123 close(fd);
00124
00125 rv = write(STDIN_FILENO, slogan, len);
00126 if (rv<0) {
00127 warn("UH-OH: write to %s (via stdin) failed", TESTFILE);
00128 remove(TESTFILE);
00129 _exit(0);
00130 }
00131
00132 if ((unsigned)rv != len) {
00133 warnx("UH-OH: write to %s (via stdin) got short count",
00134 TESTFILE);
00135 remove(TESTFILE);
00136 _exit(0);
00137 }
00138
00139 rv = lseek(STDIN_FILENO, 0, SEEK_SET);
00140 report_test(rv, errno, 0, "lseek stdin when open on file (try 1)");
00141
00142 rv = lseek(STDIN_FILENO, 0, SEEK_END);
00143 report_test(rv, errno, 0, "lseek stdin when open on file (try 2)");
00144
00145 remove(TESTFILE);
00146 _exit(0);
00147 }
00148
00149 static
00150 void
00151 lseek_loc_negative(void)
00152 {
00153 int fd, rv;
00154
00155 fd = open_testfile(NULL);
00156 if (fd<0) {
00157 return;
00158 }
00159
00160 rv = lseek(fd, -309, SEEK_SET);
00161 report_test(rv, errno, EINVAL, "lseek to negative offset");
00162
00163 close(fd);
00164 remove(TESTFILE);
00165 }
00166
00167 static
00168 void
00169 lseek_whence_inval(void)
00170 {
00171 int fd, rv;
00172
00173 fd = open_testfile(0);
00174 if (fd<0) {
00175 return;
00176 }
00177
00178 rv = lseek(fd, 0, 3594);
00179 report_test(rv, errno, EINVAL, "lseek with invalid whence code");
00180
00181 close(fd);
00182 remove(TESTFILE);
00183 }
00184
00185 static
00186 void
00187 lseek_loc_pasteof(void)
00188 {
00189 const char *message = "blahblah";
00190 int fd;
00191 off_t pos;
00192
00193 fd = open_testfile(message);
00194 if (fd<0) {
00195 return;
00196 }
00197
00198 pos = lseek(fd, 5340, SEEK_SET);
00199 if (pos == -1) {
00200 warn("FAILURE: lseek past EOF failed");
00201 goto out;
00202 }
00203 if (pos != 5340) {
00204 warnx("FAILURE: lseek to 5340 got offset %ld", (long) pos);
00205 goto out;
00206 }
00207
00208 pos = lseek(fd, -50, SEEK_CUR);
00209 if (pos == -1) {
00210 warn("FAILURE: small seek beyond EOF failed");
00211 goto out;
00212 }
00213 if (pos != 5290) {
00214 warnx("FAILURE: SEEK_CUR to 5290 got offset %ld", (long) pos);
00215 goto out;
00216 }
00217
00218 pos = lseek(fd, 0, SEEK_END);
00219 if (pos == -1) {
00220 warn("FAILURE: seek to EOF failed");
00221 goto out;
00222 }
00223
00224 if (pos != (off_t) strlen(message)) {
00225 warnx("FAILURE: seek to EOF got %ld (should be %d)",
00226 (long) pos, strlen(message));
00227 goto out;
00228 }
00229
00230 warnx("passed: seek past/to EOF");
00231
00232 out:
00233 close(fd);
00234 remove(TESTFILE);
00235 return;
00236 }
00237
00238 void
00239 test_lseek(void)
00240 {
00241 test_lseek_fd();
00242
00243 lseek_fd_device();
00244 lseek_file_stdin();
00245 lseek_loc_negative();
00246 lseek_loc_pasteof();
00247 lseek_whence_inval();
00248 }