X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f X-Recipient: djgpp AT delorie DOT com Message-ID: <57169220.7070408@gmx.de> Date: Tue, 19 Apr 2016 22:16:32 +0200 From: "Juan Manuel Guerrero (juan DOT guerrero AT gmx DOT de) [via djgpp AT delorie DOT com]" User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.9.2.13) Gecko/20101206 SUSE/3.1.7 Thunderbird/3.1.7 MIME-Version: 1.0 To: djgpp AT delorie DOT com Subject: Small adjustments of fcntl to increase posix compliance. Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit X-Provags-ID: V03:K0:W/cwAzibrlXZ1N0G8p0vt79K2HZa/FVEy84KiJeFfYw+kLv7bq4 eoilQnalsQhp4G2ZJAIWzdiRQzOJ1Hbr3Sl9OKRvL+WcDY960cmdHNks5n/GFsQpq0NVvd5 Gx4s43hm3LSBd0HyfAcQVFDNfqBTh+uLeofsOkY4kBpIpgHltjK9W5FsuE53SAwrXaMYS/U N/HUa0camRjzOrmFyr3WA== X-UI-Out-Filterresults: notjunk:1;V01:K0:UZKgoDnP7CY=:MkLbe+vRN0qtN49zVoFTQU 0wW1UoRaxYLD6YKJ4ANVWf6UqcNzAmhTGg7wdYU/RjO9wAsF1q9JOTuzyneDlJvSWKl8Fq8Q8 O4cqNLdmbq7L7EOep4fm/4zUehLMyqAhr+jSyRnR98wAIh6J1GC6gntW8DIJ0U9mRm16EIMbq /sv1xOuUIFfk+zjq1Er1CC9kFpiDhNtHtffbTLEK5L9zlATacEhSjIfsjlP0Xks0NxC4D8OLK Am6YGIgmt9z4Hu3iDXrGEd36U/7w+34YPGhe/KIQXVEN5MGW5Zs9Lm7j8CthB8AfvK5qNj6Y1 1C8rTI7+H9hQupmPUV9agN+/z+8Vp/AI3jUQs9i6/ZV1lTRbyN+cE1roTeNwbLDHl2yjwhto/ rTSq6a3aYiWj7evxvbIPT50+In1wFOGp6saWj68C3wUBbmKUucEfWe3OnJj96V8SlpeY1e2+a /Yc0qb2kK85jTQtf/Dv/3+EGkQUSSnrIYjhRmFASA3LYLx42Qov3v2Y5oLlGNR298fFDJat2X 9LdCbH9eYmkfvysG72ZwUy5iOGqHMWJyHpSEVqJzQO3J2nvXXcCwzU1dDqNcatFSM38mSysRg hUk5zlnQ0JCu6+TzJLYIX+YC+Pm33dGpvjjScVcT/VuadtQv7QkDeZ0c/BdHcebyX0zNa3WfE dEDM+vBUjnh46cj5WL7/0Y1yJFcExhqw5oOy31YtrqG4Te/ho1kmWDx+HCcHcqUHAdmVDKWcv dVrFF7+Mqm3QccYFNBl3E74QI5Jpc/Ja1nLgMLWwNvxp9uH6Dzev3gdgX/zZaVJBgRJxbLjlt gzGHJ6U Reply-To: djgpp AT delorie DOT com While I was porting some GNU programs lately I have observed that certain checks for fcntl() fail. According to http://pubs.opengroup.org/onlinepubs/009695399/functions/fcntl.html and to the check, fcntl shall return -1 and set errno to EBADF if the file descriptor is invalid, this means closed or negative file descriptor. Invalid descriptor produced by F_DUPFD shall set errno to EINVAL and not to EBADF as it uses to be. Invalid commands shall set errno to EINVAL and not to ENOSYS as it uses to be. For the case of unsupported commands by DJGPP like socket specific commands F_GETOWN and F_SETOWN I still set errno to ENOSYS. I have also added a small test program that shall verify the new behaviour. As usual suggestions, objections and comments are welcome. If I do not get a response in a reasonable periode of time I will commit the change below. Regards, Juan M. Guerrero 2016-04-16 Juan Manuel Guerrero * djgpp/src/docs/kb/wc206.txi: Info about fcntl change added. * djgpp/src/libc/posix/fcntl/fcntl.c: For invalid input file descriptor set errno to EBADF, for invalid output file descriptor set errno to EINVAL. * djgpp/src/libc/posix/fcntl/fcntl.txh: For invalid input file descriptor set errno to EBADF, for invalid output file descriptor set errno to EINVAL. * djgpp/tests/libc/posix/fcntl/fcntl.c: Check for EINVAL in case of invalid output file descriptor, and for EBADF in case of invalid input file descriptor. * djgpp/tests/libc/posix/fcntl/makefile: Entry for fcntl added. diff -aprNU7 djgpp.orig/include/fcntl.h djgpp/include/fcntl.h --- djgpp.orig/include/fcntl.h 2015-05-01 00:21:46 -0509 +++ djgpp/include/fcntl.h 2016-04-19 20:48:42 -0509 @@ -1,7 +1,8 @@ +/* Copyright (C) 2016 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2012 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #ifndef __dj_include_fcntl_h_ @@ -29,14 +30,16 @@ extern "C" { #define F_SETFD 5 #define F_SETFL 6 #define F_SETLK 7 #define F_SETLKW 8 #define F_GETLK64 9 #define F_SETLK64 10 #define F_SETLKW64 11 +#define F_GETOWN 12 +#define F_SETOWN 13 #define F_UNLCK 0 #define F_RDLCK 1 #define F_WRLCK 2 #define O_RDONLY 0x0000 #define O_WRONLY 0x0001 diff -aprNU7 djgpp.orig/src/docs/kb/wc206.txi djgpp/src/docs/kb/wc206.txi --- djgpp.orig/src/docs/kb/wc206.txi 2016-04-18 19:13:42 -0509 +++ djgpp/src/docs/kb/wc206.txi 2016-04-18 19:13:20 -0509 @@ -6,7 +6,13 @@ Here is a list of changes from DJGPP V2. @findex dup2 AT r{, and POSIX.1-2001 compliance} The validity of the file descriptors passed to @code{dup2} is now checked. If @var{existing_handle} is not a valid open file descriptor or if @var{new_handle} is out of the allowed range for file descriptors the call of @code{dup2} will fail and @code{errno} will be set to @code{EBADF}. With this adjustment, the @acronym{Posix} compliance of the @code{dup2} implementation is increased. + +@findex fcntl AT r{, and POSIX.1-2001 compliance} +If the passed file descriptors are not valid for the @code{F_DUPFD} command then +the call of @code{fcntl} will fail and @code{errno} will be set to @code{EINVAL}. +With this adjustment, the @acronym{Posix} compliance of the @code{fcntl} implementation +is increased. diff -aprNU7 djgpp.orig/src/libc/posix/fcntl/fcntl.c djgpp/src/libc/posix/fcntl/fcntl.c --- djgpp.orig/src/libc/posix/fcntl/fcntl.c 2016-04-16 15:47:28 -0509 +++ djgpp/src/libc/posix/fcntl/fcntl.c 2016-04-19 19:59:30 -0509 @@ -266,15 +266,18 @@ fcntl(int fd, int cmd, ...) short dev_info = _get_dev_info(fd); static int inherit_bit_visible = -1; int errno_save; /* Verify the descriptor is valid by retrieving the handle's device info word. */ if (dev_info == -1) + { + errno = EBADF; return dev_info; + } /* Allow a fd to override with a FSEXT. */ func = __FSEXT_get_function(fd); if (func) { int rv; @@ -303,21 +306,21 @@ fcntl(int fd, int cmd, ...) break; tofd++; } if (tofd >= open_max) { - errno = EMFILE; + errno = EINVAL; return -1; } - errno = errno_save; - return dup2(fd, tofd); + errno = (tofd = dup2(fd, tofd)) == -1 ? EINVAL : errno_save; + return tofd; } case F_GETFD: { unsigned long entry_ptr; @@ -534,14 +537,22 @@ fcntl(int fd, int cmd, ...) lock_r64 = va_arg(ap, struct flock64 *); va_end (ap); ret = _fcntl_lk64(fd, cmd, lock_r64); return ret; } - } + + + case F_GETOWN: + case F_SETOWN: + { + errno = ENOSYS; + return -1; + } + } /* In case fcntl is called with an unrecognized command. */ - errno = ENOSYS; + errno = EINVAL; return -1; } diff -aprNU7 djgpp.orig/src/libc/posix/fcntl/fcntl.txh djgpp/src/libc/posix/fcntl/fcntl.txh --- djgpp.orig/src/libc/posix/fcntl/fcntl.txh 2003-03-25 12:32:28 -0509 +++ djgpp/src/libc/posix/fcntl/fcntl.txh 2016-04-19 19:56:10 -0509 @@ -150,27 +150,29 @@ calling @code{fcntl} with the @code{F_DU @code{dup2} instead, see @ref{dup2}. @subheading Return Value If an invalid or unsupported value is passed in @var{cmd}, or @var{fd} is an invalid file handle, the function returns -1 and sets @code{errno} to the appropriate value. Unsupported values of @var{cmd} cause -@code{ENOSYS} to be stored in @code{errno}. If @var{cmd} is -@code{F_DUPFD}, the function returns the new descriptor or -1 in case of -a failure. +@code{ENOSYS} to be stored in @code{errno}. Invalid values of @var{cmd} +cause @code{EINVAL} to be stored in @code{errno}. If @var{cmd} is @code{F_DUPFD}, +the function returns the new descriptor or -1 in case of a failure and sets +@code{errno} to @code{EINVAL}. If @var{fd} is an invalid file handle, +the function sets @code{errno} to @code{EBADF}. Lock requests which specify the open file's current @code{EOF} position as the value of @var{l_start} and zero as the @var{l_len} value will fail, returning -1 with @code{errno} set to @code{EACCES}. @subheading Portability @port-note posix Contrary to Posix requirement, the handle returned by @code{F_DUPFD} shares the @code{FD_CLOEXEC} flag with @var{fd} (unless they are on different sides of the 20-handle mark), since DOS/Windows only maintain a single set of bits for all the handles associated with the same call to @code{open}. -@portability !ansi, posix +@portability !ansi, posix-1003.1-2001 @subheading Example @example /* Save the handle in a way that it won't be passed to child processes. */ diff -aprNU7 djgpp.orig/tests/libc/posix/fcntl/fcntl.c djgpp/tests/libc/posix/fcntl/fcntl.c --- djgpp.orig/tests/libc/posix/fcntl/fcntl.c 1969-12-31 18:50:24 -0509 +++ djgpp/tests/libc/posix/fcntl/fcntl.c 2016-04-18 19:18:36 -0509 @@ -0,0 +1,48 @@ +#include +#include +#include +#include +#include +#include + + +int +main (void) +{ + int result = 0; + int bad_fd = INT_MAX; + struct rlimit rlim; + + + if (getrlimit(RLIMIT_NOFILE, &rlim) == 0 + && 0 <= rlim.rlim_cur && rlim.rlim_cur <= INT_MAX) + bad_fd = rlim.rlim_cur; + + if (fcntl(0, F_DUPFD, -1) != -1) result |= 1; + if (errno != EINVAL) result |= 2; + + if (fcntl(0, F_DUPFD, bad_fd) != -1) result |= 4; + if (errno != EINVAL) result |= 8; + + close (0); + if (fcntl(0, F_DUPFD, STDERR_FILENO + 1) != -1) result |= 16; + if (errno != EBADF) result |= 32; + + { + int fd; + fd = open(".", O_RDONLY); + if (fd == -1) + result |= 64; + else if (fcntl(fd, F_DUPFD, STDERR_FILENO + 1) == -1) + result |= 128; + + close (fd); + } + + if (result) + printf("fcntl check failed with result = %d\n", result); + else + printf("fcntl check passed.\n"); + + return result; +} diff -aprNU7 djgpp.orig/tests/libc/posix/fcntl/makefile djgpp/tests/libc/posix/fcntl/makefile --- djgpp.orig/tests/libc/posix/fcntl/makefile 2001-01-31 12:14:46 -0509 +++ djgpp/tests/libc/posix/fcntl/makefile 2016-04-16 17:11:16 -0509 @@ -1,11 +1,12 @@ TOP=../.. SRC += binpr.c SRC += bt.c +SRC += fcntl.c SRC += fcntl3gb.c SRC += inherit.c SRC += makef3gb.c SRC += open.c SRC += tfcntl.c SRC += tfcntl2.c SRC += trunc.c