os161-1.99
 All Data Structures
common_fds.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  * Calls with invalid fds
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 <limits.h>
00041 #include <errno.h>
00042 #include <err.h>
00043 
00044 #include "config.h"
00045 #include "test.h"
00046 
00047 
00048 static
00049 int
00050 read_badfd(int fd)
00051 {
00052         char buf[128];
00053         return read(fd, buf, sizeof(buf));
00054 }
00055 
00056 static
00057 int
00058 write_badfd(int fd)
00059 {
00060         char buf[128];
00061         memset(buf, 'a', sizeof(buf));
00062         return write(fd, buf, sizeof(buf));
00063 }
00064 
00065 
00066 static
00067 int
00068 close_badfd(int fd)
00069 {
00070         return close(fd);
00071 }
00072 
00073 static
00074 int
00075 ioctl_badfd(int fd)
00076 {
00077         return ioctl(fd, 0, NULL);
00078 }
00079 
00080 static
00081 int
00082 lseek_badfd(int fd)
00083 {
00084         return lseek(fd, 0, SEEK_SET);
00085 }
00086 
00087 static
00088 int
00089 fsync_badfd(int fd)
00090 {
00091         return fsync(fd);
00092 }
00093 
00094 static
00095 int
00096 ftruncate_badfd(int fd)
00097 {
00098         return ftruncate(fd, 60);
00099 }
00100 
00101 static
00102 int
00103 fstat_badfd(int fd)
00104 {
00105         struct stat sb;
00106         return fstat(fd, &sb);
00107 }
00108 
00109 static
00110 int
00111 getdirentry_badfd(int fd)
00112 {
00113         char buf[32];
00114         return getdirentry(fd, buf, sizeof(buf));
00115 }
00116 
00117 static
00118 int
00119 dup2_badfd(int fd)
00120 {
00121         /* use the +1 to avoid doing dup2(CLOSED_FD, CLOSED_FD) */
00122         return dup2(fd, CLOSED_FD+1);
00123 }
00124 
00125 static
00126 void
00127 dup2_cleanup(void)
00128 {
00129         close(CLOSED_FD+1);
00130 }
00131 
00132 ////////////////////////////////////////////////////////////
00133 
00134 static
00135 void
00136 any_badfd(int (*func)(int fd), void (*cleanup)(void), const char *callname,
00137           int fd, const char *fddesc)
00138 {
00139         char fulldesc[128];
00140         int rv;
00141 
00142         snprintf(fulldesc, sizeof(fulldesc), "%s using %s", callname, fddesc);
00143         rv = func(fd);
00144         report_test(rv, errno, EBADF, fulldesc);
00145         if (cleanup) {
00146                 cleanup();
00147         }
00148 }
00149 
00150 static
00151 void
00152 runtest(int (*func)(int fd), void (*cleanup)(void), const char *callname)
00153 {
00154         /*
00155          * If adding cases, also see bad_dup2.c
00156          */
00157 
00158         /* basic invalid case: fd -1 */
00159         any_badfd(func, cleanup, callname, -1, "fd -1");
00160 
00161         /* also try -5 in case -1 is special somehow */
00162         any_badfd(func, cleanup, callname, -5, "fd -5");
00163 
00164         /* try a fd we know is closed */
00165         any_badfd(func, cleanup, callname, CLOSED_FD, "closed fd");
00166 
00167         /* try a positive fd we know is out of range */
00168         any_badfd(func, cleanup, callname, IMPOSSIBLE_FD, "impossible fd");
00169 
00170         /* test for off-by-one errors */
00171 #ifdef OPEN_MAX
00172         any_badfd(func, cleanup, callname, OPEN_MAX, "fd OPEN_MAX");
00173 #else
00174         warnx("Warning: OPEN_MAX not defined, test skipped");
00175 #endif
00176 }
00177 
00178 ////////////////////////////////////////////////////////////
00179 
00180 #define T(call) \
00181   void                                          \
00182   test_##call##_fd(void)                        \
00183   {                                             \
00184         runtest(call##_badfd, NULL, #call);     \
00185   }
00186 
00187 #define TC(call) \
00188   void                                          \
00189   test_##call##_fd(void)                        \
00190   {                                             \
00191         runtest(call##_badfd, call##_cleanup, #call);\
00192   }
00193 
00194 T(read);
00195 T(write);
00196 T(close);
00197 T(ioctl);
00198 T(lseek);
00199 T(fsync);
00200 T(ftruncate);
00201 T(fstat);
00202 T(getdirentry);
00203 TC(dup2);
 All Data Structures