1162852Sdes/*
2162852Sdes * Copyright (c) 2006 Darren Tucker
3162852Sdes *
4162852Sdes * Permission to use, copy, modify, and distribute this software for any
5162852Sdes * purpose with or without fee is hereby granted, provided that the above
6162852Sdes * copyright notice and this permission notice appear in all copies.
7162852Sdes *
8162852Sdes * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9162852Sdes * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10162852Sdes * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11162852Sdes * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12162852Sdes * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13162852Sdes * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14162852Sdes * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15162852Sdes */
16162852Sdes
17162852Sdes#include <sys/types.h>
18162852Sdes#include <sys/stat.h>
19162852Sdes
20162852Sdes#include <fcntl.h>
21162852Sdes#include <stdio.h>
22162852Sdes#include <stdlib.h>
23162852Sdes#include <unistd.h>
24162852Sdes
25162852Sdes#define NUM_OPENS 10
26162852Sdes
27225825Sdesint closefrom(int);
28225825Sdes
29162852Sdesvoid
30162852Sdesfail(char *msg)
31162852Sdes{
32162852Sdes	fprintf(stderr, "closefrom: %s\n", msg);
33162852Sdes	exit(1);
34162852Sdes}
35162852Sdes
36162852Sdesint
37162852Sdesmain(void)
38162852Sdes{
39162852Sdes	int i, max, fds[NUM_OPENS];
40162852Sdes	char buf[512];
41162852Sdes
42162852Sdes	for (i = 0; i < NUM_OPENS; i++)
43180744Sdes		if ((fds[i] = open("/dev/null", O_RDONLY)) == -1)
44162852Sdes			exit(0);	/* can't test */
45162852Sdes	max = i - 1;
46162852Sdes
47162852Sdes	/* should close last fd only */
48162852Sdes	closefrom(fds[max]);
49162852Sdes	if (close(fds[max]) != -1)
50162852Sdes		fail("failed to close highest fd");
51162852Sdes
52162852Sdes	/* make sure we can still use remaining descriptors */
53162852Sdes	for (i = 0; i < max; i++)
54162852Sdes		if (read(fds[i], buf, sizeof(buf)) == -1)
55162852Sdes			fail("closed descriptors it should not have");
56162852Sdes
57162852Sdes	/* should close all fds */
58162852Sdes	closefrom(fds[0]);
59162852Sdes	for (i = 0; i < NUM_OPENS; i++)
60162852Sdes		if (close(fds[i]) != -1)
61162852Sdes			fail("failed to close from lowest fd");
62180746Sdes	return 0;
63162852Sdes}
64