/*1* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 20092* The President and Fellows of Harvard College.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12* 3. Neither the name of the University nor the names of its contributors13* may be used to endorse or promote products derived from this software14* without specific prior written permission.15*16* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND17* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE18* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE19* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE20* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL21* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS22* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)23* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT24* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY25* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF26* SUCH DAMAGE.27*/2829/*30* Calls with invalid fds31*/3233#include <sys/types.h>34#include <sys/stat.h>35#include <stdio.h>36#include <stdlib.h>37#include <string.h>38#include <unistd.h>39#include <limits.h>40#include <errno.h>41#include <err.h>4243#include "config.h"44#include "test.h"454647static48int49read_badfd(int fd)50{51char buf[128];52return read(fd, buf, sizeof(buf));53}5455static56int57write_badfd(int fd)58{59char buf[128];60memset(buf, 'a', sizeof(buf));61return write(fd, buf, sizeof(buf));62}636465static66int67close_badfd(int fd)68{69return close(fd);70}7172static73int74ioctl_badfd(int fd)75{76return ioctl(fd, 0, NULL);77}7879static80int81lseek_badfd(int fd)82{83return lseek(fd, 0, SEEK_SET);84}8586static87int88fsync_badfd(int fd)89{90return fsync(fd);91}9293static94int95ftruncate_badfd(int fd)96{97return ftruncate(fd, 60);98}99100static101int102fstat_badfd(int fd)103{104struct stat sb;105return fstat(fd, &sb);106}107108static109int110getdirentry_badfd(int fd)111{112char buf[32];113return getdirentry(fd, buf, sizeof(buf));114}115116static117int118dup2_badfd(int fd)119{120/* use the +1 to avoid doing dup2(CLOSED_FD, CLOSED_FD) */121return dup2(fd, CLOSED_FD+1);122}123124static125void126dup2_cleanup(void)127{128close(CLOSED_FD+1);129}130131////////////////////////////////////////////////////////////132133static134void135any_badfd(int (*func)(int fd), void (*cleanup)(void), const char *callname,136int fd, const char *fddesc)137{138char fulldesc[128];139int rv;140141snprintf(fulldesc, sizeof(fulldesc), "%s using %s", callname, fddesc);142rv = func(fd);143report_test(rv, errno, EBADF, fulldesc);144if (cleanup) {145cleanup();146}147}148149static150void151runtest(int (*func)(int fd), void (*cleanup)(void), const char *callname)152{153/*154* If adding cases, also see bad_dup2.c155*/156157/* basic invalid case: fd -1 */158any_badfd(func, cleanup, callname, -1, "fd -1");159160/* also try -5 in case -1 is special somehow */161any_badfd(func, cleanup, callname, -5, "fd -5");162163/* try a fd we know is closed */164any_badfd(func, cleanup, callname, CLOSED_FD, "closed fd");165166/* try a positive fd we know is out of range */167any_badfd(func, cleanup, callname, IMPOSSIBLE_FD, "impossible fd");168169/* test for off-by-one errors */170#ifdef OPEN_MAX171any_badfd(func, cleanup, callname, OPEN_MAX, "fd OPEN_MAX");172#else173warnx("Warning: OPEN_MAX not defined, test skipped");174#endif175}176177////////////////////////////////////////////////////////////178179#define T(call) \180void \181test_##call##_fd(void) \182{ \183runtest(call##_badfd, NULL, #call); \184}185186#define TC(call) \187void \188test_##call##_fd(void) \189{ \190runtest(call##_badfd, call##_cleanup, #call);\191}192193T(read);194T(write);195T(close);196T(ioctl);197T(lseek);198T(fsync);199T(ftruncate);200T(fstat);201T(getdirentry);202TC(dup2);203204205