os161-1.99
 All Data Structures
bad_lseek.c
00001 /*
00002  * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
00003  *      The President and Fellows of Harvard College.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the University nor the names of its contributors
00014  *    may be used to endorse or promote products derived from this software
00015  *    without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  */
00029 
00030 /*
00031  * lseek
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         /* fork so we don't affect our own stdin */
00074         pid = fork();
00075         if (pid<0) {
00076                 warn("UH-OH: fork failed");
00077                 return;
00078         }
00079         else if (pid!=0) {
00080                 /* parent */
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         /* child */
00097 
00098         fd = open_testfile(NULL);
00099         if (fd<0) {
00100                 _exit(0);
00101         }
00102 
00103         /* 
00104          * Move file to stdin.
00105          * Use stdin (rather than stdout or stderr) to maximize the
00106          * chances of detecting any special-case handling of fds 0-2.
00107          * (Writing to stdin is fine as long as it's open for write,
00108          * and it will be.)
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 }
 All Data Structures