vfs: _user_ioctl: any buffer value is allowed for some ops.

some ops want an integer value instead of a pointer as arg parameter ( #15058 ).

http://pubs.opengroup.org/onlinepubs/9699919799/functions/ioctl.html clearly specifies that:
"The type of arg depends upon the particular control request, but it shall be either an
integer or a pointer to a device-specific data structure."

add a test for functions which should return ENOTTY as errno.

Change-Id: I4a98af73b17c79c3460123d3794ee866f8719898
Reviewed-on: https://review.haiku-os.org/c/1447
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
Jérôme Duval 2019-05-12 10:11:21 +02:00 committed by waddlesplash
parent 32cbf55317
commit df0ba1eca1
2 changed files with 64 additions and 3 deletions

View File

@ -919,11 +919,12 @@ _user_seek(int fd, off_t pos, int seekType)
status_t
_user_ioctl(int fd, uint32 op, void* buffer, size_t length)
{
if (buffer != NULL && !IS_USER_ADDRESS(buffer))
return B_BAD_ADDRESS;
TRACE(("user_ioctl: fd %d\n", fd));
// "buffer" is not always a pointer depending on "op", so we cannot
// check that it is a userland buffer here; the underlying implementation
// must do that.
SyscallRestartWrapper<status_t> status;
return status = fd_ioctl(false, fd, op, buffer, length);

View File

@ -0,0 +1,60 @@
/*
* Copyright 2019, Jérôme Duval, jerome.duval@gmail.com.
* Distributed under the terms of the MIT License.
*/
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
extern const char *__progname;
int
main(int argc, char **argv)
{
if (argc < 2) {
fprintf(stderr, "usage: %s <file>\n", __progname);
return 1;
}
int fd = open(argv[1], O_RDONLY);
if (fd < 0) {
fprintf(stderr, "%s: could open the file read-only \"%s\": %s\n",
__progname, argv[1], strerror(errno));
return 1;
}
int err = tcdrain(fd);
if (err != -1 || errno != ENOTTY) {
fprintf(stderr, "%s: tcdrain didn't fail with ENOTTY \"%s\": %s\n",
__progname, argv[1], strerror(errno));
close(fd);
return 1;
}
err = tcflow(fd, TCION);
if (err != -1 || errno != ENOTTY) {
fprintf(stderr, "%s: tcflow didn't fail with ENOTTY \"%s\": %s\n",
__progname, argv[1], strerror(errno));
close(fd);
return 1;
}
err = tcflush(fd, TCIOFLUSH);
if (err != -1 || errno != ENOTTY) {
fprintf(stderr, "%s: tcflush didn't fail with ENOTTY \"%s\": %s\n",
__progname, argv[1], strerror(errno));
close(fd);
return 1;
}
close(fd);
return 0;
}