Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Tarot
gnulib
Commits
b6dfa79f
Commit
b6dfa79f
authored
Aug 24, 2009
by
Bruno Haible
Browse files
Tests for module 'dup3'.
parent
c2462636
Changes
3
Hide whitespace changes
Inline
Side-by-side
ChangeLog
View file @
b6dfa79f
2009-08-23 Bruno Haible <bruno@clisp.org>
Tests for module 'dup3'.
* modules/dup3-tests: New file.
* tests/test-dup3.c: New file.
New module 'dup3'.
* lib/unistd.in.h (dup3): New declaration.
* lib/dup3.c: New file.
modules/dup3-tests
0 → 100644
View file @
b6dfa79f
Files:
tests/test-dup3.c
Depends-on:
open
configure.ac:
Makefile.am:
TESTS += test-dup3
check_PROGRAMS += test-dup3
tests/test-dup3.c
0 → 100644
View file @
b6dfa79f
/* Test duplicating file descriptors.
Copyright (C) 2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Written by Eric Blake <ebb9@byu.net>, 2009,
and Bruno Haible <bruno@clisp.org>, 2009. */
#include <config.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
/* Get declarations of the Win32 API functions. */
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif
#include "binary-io.h"
#define ASSERT(expr) \
do \
{ \
if (!(expr)) \
{ \
fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
fflush (stderr); \
abort (); \
} \
} \
while (0)
/* Return true if FD is open. */
static
bool
is_open
(
int
fd
)
{
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
/* On Win32, the initial state of unassigned standard file
descriptors is that they are open but point to an
INVALID_HANDLE_VALUE, and there is no fcntl. */
return
(
HANDLE
)
_get_osfhandle
(
fd
)
!=
INVALID_HANDLE_VALUE
;
#else
# ifndef F_GETFL
# error Please port fcntl to your platform
# endif
return
0
<=
fcntl
(
fd
,
F_GETFL
);
#endif
}
/* Return true if FD is not inherited to child processes. */
static
bool
is_cloexec
(
int
fd
)
{
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
HANDLE
h
=
(
HANDLE
)
_get_osfhandle
(
fd
);
DWORD
flags
;
ASSERT
(
GetHandleInformation
(
h
,
&
flags
));
return
(
flags
&
HANDLE_FLAG_INHERIT
)
==
0
;
#else
int
flags
;
ASSERT
((
flags
=
fcntl
(
fd
,
F_GETFD
))
>=
0
);
return
(
flags
&
FD_CLOEXEC
)
!=
0
;
#endif
}
int
main
()
{
int
use_cloexec
;
#if defined O_CLOEXEC
for
(
use_cloexec
=
0
;
use_cloexec
<=
1
;
use_cloexec
++
)
#else
use_cloexec
=
0
;
#endif
{
const
char
*
file
=
"test-dup3.tmp"
;
int
fd
=
open
(
file
,
O_CREAT
|
O_TRUNC
|
O_RDWR
,
0600
);
int
o_flags
;
char
buffer
[
1
];
o_flags
=
0
;
#if defined O_CLOEXEC
if
(
use_cloexec
)
o_flags
|=
O_CLOEXEC
;
#endif
/* Assume std descriptors were provided by invoker. */
ASSERT
(
STDERR_FILENO
<
fd
);
ASSERT
(
is_open
(
fd
));
/* Ignore any other fd's leaked into this process. */
close
(
fd
+
1
);
close
(
fd
+
2
);
ASSERT
(
!
is_open
(
fd
+
1
));
ASSERT
(
!
is_open
(
fd
+
2
));
/* Assigning to self is invalid. */
errno
=
0
;
ASSERT
(
dup3
(
fd
,
fd
,
o_flags
)
==
-
1
);
ASSERT
(
errno
==
EINVAL
);
ASSERT
(
is_open
(
fd
));
/* If the source is not open, then the destination is unaffected. */
errno
=
0
;
ASSERT
(
dup3
(
fd
+
1
,
fd
+
2
,
o_flags
)
==
-
1
);
ASSERT
(
errno
==
EBADF
);
ASSERT
(
!
is_open
(
fd
+
2
));
errno
=
0
;
ASSERT
(
dup3
(
fd
+
1
,
fd
,
o_flags
)
==
-
1
);
ASSERT
(
errno
==
EBADF
);
ASSERT
(
is_open
(
fd
));
/* The destination must be valid. */
errno
=
0
;
ASSERT
(
dup3
(
fd
,
-
2
,
o_flags
)
==
-
1
);
ASSERT
(
errno
==
EBADF
);
errno
=
0
;
ASSERT
(
dup3
(
fd
,
10000000
,
o_flags
)
==
-
1
);
ASSERT
(
errno
==
EBADF
);
/* Using dup3 can skip fds. */
ASSERT
(
dup3
(
fd
,
fd
+
2
,
o_flags
)
==
fd
+
2
);
ASSERT
(
is_open
(
fd
));
ASSERT
(
!
is_open
(
fd
+
1
));
ASSERT
(
is_open
(
fd
+
2
));
if
(
use_cloexec
)
ASSERT
(
is_cloexec
(
fd
+
2
));
else
ASSERT
(
!
is_cloexec
(
fd
+
2
));
/* Verify that dup3 closes the previous occupant of a fd. */
ASSERT
(
open
(
"/dev/null"
,
O_WRONLY
,
0600
)
==
fd
+
1
);
ASSERT
(
dup3
(
fd
+
1
,
fd
,
o_flags
)
==
fd
);
ASSERT
(
close
(
fd
+
1
)
==
0
);
ASSERT
(
write
(
fd
,
"1"
,
1
)
==
1
);
ASSERT
(
dup3
(
fd
+
2
,
fd
,
o_flags
)
==
fd
);
ASSERT
(
lseek
(
fd
,
0
,
SEEK_END
)
==
0
);
ASSERT
(
write
(
fd
+
2
,
"2"
,
1
)
==
1
);
ASSERT
(
lseek
(
fd
,
0
,
SEEK_SET
)
==
0
);
ASSERT
(
read
(
fd
,
buffer
,
1
)
==
1
);
ASSERT
(
*
buffer
==
'2'
);
/* Clean up. */
ASSERT
(
close
(
fd
+
2
)
==
0
);
ASSERT
(
close
(
fd
)
==
0
);
ASSERT
(
unlink
(
file
)
==
0
);
}
return
0
;
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment