Skip to content

Commit

Permalink
implement support for ioctl
Browse files Browse the repository at this point in the history
  • Loading branch information
Meulengracht committed May 25, 2020
1 parent 36abfb3 commit c5cf97a
Show file tree
Hide file tree
Showing 13 changed files with 201 additions and 11 deletions.
2 changes: 2 additions & 0 deletions librt/libc/include/internal/_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ typedef OsStatus_t(*stdio_read)(stdio_handle_t*, void*, size_t, size_t*);
typedef OsStatus_t(*stdio_write)(stdio_handle_t*, const void*, size_t, size_t*);
typedef OsStatus_t(*stdio_resize)(stdio_handle_t*, long long);
typedef OsStatus_t(*stdio_seek)(stdio_handle_t*, int, off64_t, long long*);
typedef OsStatus_t(*stdio_ioctl)(stdio_handle_t*, int, va_list);
typedef OsStatus_t(*stdio_close)(stdio_handle_t*, int);

typedef struct stdio_ops {
Expand All @@ -70,6 +71,7 @@ typedef struct stdio_ops {
stdio_write write;
stdio_resize resize;
stdio_seek seek;
stdio_ioctl ioctl;
stdio_close close;
} stdio_ops_t;

Expand Down
1 change: 1 addition & 0 deletions librt/libc/include/internal/_pipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

struct pipe {
struct dma_attachment attachment;
unsigned int options;
};

#endif //!__INTERNAL_PIPE_H__
56 changes: 56 additions & 0 deletions librt/libc/include/ioctl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* MollenOS
*
* Copyright 2020, Philip Meulengracht
*
* 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/>.
*
*
* Generic IO Cotntol. These are functions that may be supported by all
* io descriptors. If they are not supported errno is set to EBADF
*/

#ifndef __C_IOCTL_H__
#define __C_IOCTL_H__

#include <crtdefs.h>

// groups
#define _IOCTL_SHARED 'x'

// options
#define _IOCTL_VOID 0x20000000
#define _IOCTL_READ 0x40000000
#define _IOCTL_WRITE 0x80000000
#define _IOCTL_READWRITE (_IOCTL_READ | _IOCTL_WRITE)

// decoding macros
#define _IOCTL_TYPE(x) ((x >> 16) & 0xFF)
#define _IOCTL_CMD(x) ((x >> 8) & 0xFF)

// encoding macros
#define _IOC(dir, type, cmd, len) (dir | (type << 16) || (cmd << 8) || len)
#define _IOC_V(type, cmd) _IOC(_IOCTL_VOID, type, cmd, 0)
#define _IOC_R(type, cmd, arg_type) _IOC(_IOCTL_READ, type, cmd, sizeof(arg_type))
#define _IOC_W(type, cmd, arg_type) _IOC(_IOCTL_WRITE, type, cmd, sizeof(arg_type))
#define _IOC_RW(type, cmd, arg_type) _IOC(_IOCTL_READWRITE, type, cmd, sizeof(arg_type))

// shared commands that ctl standard iod functions
#define FIONBIO _IOC_W(_IOCTL_SHARED, 0, int) // set blocking io
#define FIOASYNC _IOC_W(_IOCTL_SHARED, 1, int) // set async io
#define FIONREAD _IOC_R(_IOCTL_SHARED, 2, int) // number of bytes available

CRTDECL(int, ioctl(int iod, unsigned long request, ...));

#endif //!__C_IOCTL_H__
48 changes: 48 additions & 0 deletions librt/libc/stdio/io/ioctl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* MollenOS
*
* Copyright 2020, Philip Meulengracht
*
* 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/>.
*
*
* Generic IO Cotntol. These are functions that may be supported by all
* io descriptors. If they are not supported errno is set to EBADF
*/

#include <internal/_io.h>
#include <ioctl.h>
#include <os/mollenos.h>

int ioctl(int iod, unsigned long request, ...)
{
stdio_handle_t* handle = stdio_handle_get(iod);
OsStatus_t status;
va_list args;

if (!handle) {
_set_errno(EBADF);
return -1;
}

va_start(args, request);
status = handle->ops.ioctl(handle, request, args);
va_end(args);

if (status == OsNotSupported) {
_set_errno(EBADF);
return -1;
}
return OsStatusToErrno(status);
}
6 changes: 6 additions & 0 deletions librt/libc/stdio/libc_io_file_operations.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,18 @@ OsStatus_t stdio_file_op_inherit(stdio_handle_t* handle)
return OsSuccess;
}

OsStatus_t stdio_file_op_ioctl(stdio_handle_t* handle, int request, va_list vlist)
{
return OsNotSupported;
}

void stdio_get_file_operations(stdio_ops_t* ops)
{
ops->inherit = stdio_file_op_inherit;
ops->read = stdio_file_op_read;
ops->write = stdio_file_op_write;
ops->seek = stdio_file_op_seek;
ops->resize = stdio_file_op_resize;
ops->ioctl = stdio_file_op_ioctl;
ops->close = stdio_file_op_close;
}
6 changes: 6 additions & 0 deletions librt/libc/stdio/libc_io_ipc_operations.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,18 @@ OsStatus_t stdio_ipc_op_inherit(stdio_handle_t* handle)
return OsSuccess;
}

OsStatus_t stdio_ipc_op_ioctl(stdio_handle_t* handle, int request, va_list vlist)
{
return OsNotSupported;
}

void stdio_get_ipc_operations(stdio_ops_t* ops)
{
ops->inherit = stdio_ipc_op_inherit;
ops->read = stdio_ipc_op_read;
ops->write = stdio_ipc_op_write;
ops->seek = stdio_ipc_op_seek;
ops->resize = stdio_ipc_op_resize;
ops->ioctl = stdio_ipc_op_ioctl;
ops->close = stdio_ipc_op_close;
}
6 changes: 6 additions & 0 deletions librt/libc/stdio/libc_io_net_operations.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,18 @@ OsStatus_t stdio_net_op_inherit(stdio_handle_t* handle)
return status1;
}

OsStatus_t stdio_net_op_ioctl(stdio_handle_t* handle, int request, va_list vlist)
{
return OsNotSupported;
}

void stdio_get_net_operations(stdio_ops_t* ops)
{
ops->inherit = stdio_net_op_inherit;
ops->read = stdio_net_op_read;
ops->write = stdio_net_op_write;
ops->seek = stdio_net_op_seek;
ops->resize = stdio_net_op_resize;
ops->ioctl = stdio_net_op_ioctl;
ops->close = stdio_net_op_close;
}
6 changes: 6 additions & 0 deletions librt/libc/stdio/libc_io_null_operations.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,18 @@ OsStatus_t stdio_null_op_inherit(stdio_handle_t* handle)
return OsSuccess;
}

OsStatus_t stdio_null_op_ioctl(stdio_handle_t* handle, int request, va_list vlist)
{
return OsNotSupported;
}

void stdio_get_null_operations(stdio_ops_t* ops)
{
ops->inherit = stdio_null_op_inherit;
ops->read = stdio_null_op_read;
ops->write = stdio_null_op_write;
ops->seek = stdio_null_op_seek;
ops->resize = stdio_null_op_resize;
ops->ioctl = stdio_null_op_ioctl;
ops->close = stdio_null_op_close;
}
42 changes: 34 additions & 8 deletions librt/libc/stdio/libc_io_pipe_operations.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,28 @@

#include <ds/streambuffer.h>
#include <errno.h>
#include <ioctl.h>
#include <internal/_io.h>

OsStatus_t stdio_pipe_op_read(stdio_handle_t* handle, void* buffer, size_t length, size_t* bytes_read)
{
streambuffer_t* stream = handle->object.data.pipe.attachment.buffer;
streambuffer_t* stream = handle->object.data.pipe.attachment.buffer;
unsigned int options = handle->object.data.pipe.options;
size_t bytesRead;

bytesRead = streambuffer_stream_in(stream, buffer, length, 0);


bytesRead = streambuffer_stream_in(stream, buffer, length, options);
*bytes_read = bytesRead;
return OsSuccess;
}

OsStatus_t stdio_pipe_op_write(stdio_handle_t* handle, const void* buffer, size_t length, size_t* bytes_written)
{
streambuffer_t* stream = handle->object.data.pipe.attachment.buffer;
unsigned int options = handle->object.data.pipe.options;
size_t bytesWritten;

bytesWritten = streambuffer_stream_out(stream, buffer, length, 0);


*bytes_written = bytesWritten
bytesWritten = streambuffer_stream_out(stream, (void*)buffer, length, options);
*bytes_written = bytesWritten;
return OsSuccess;
}

Expand Down Expand Up @@ -84,12 +83,39 @@ OsStatus_t stdio_pipe_op_inherit(stdio_handle_t* handle)
return status;
}

OsStatus_t stdio_pipe_op_ioctl(stdio_handle_t* handle, int request, va_list args)
{
streambuffer_t* stream = handle->object.data.pipe.attachment.buffer;

if (request == FIONBIO) {
int blocking = va_arg(args, int);
if (blocking) {
handle->object.data.pipe.options |= STREAMBUFFER_NO_BLOCK;
}
else {
handle->object.data.pipe.options &= ~(STREAMBUFFER_NO_BLOCK);
}
return OsSuccess;
}
else if (request == FIONREAD) {
int* bytesAvailableOut = va_arg(args, int*);
if (bytesAvailableOut) {
size_t bytesAvailable;
streambuffer_get_bytes_available_in(stream, &bytesAvailable);
*bytesAvailableOut = (int)bytesAvailable;
}
return OsSuccess;
}
return OsNotSupported;
}

void stdio_get_pipe_operations(stdio_ops_t* ops)
{
ops->inherit = stdio_pipe_op_inherit;
ops->read = stdio_pipe_op_read;
ops->write = stdio_pipe_op_write;
ops->seek = stdio_pipe_op_seek;
ops->resize = stdio_pipe_op_resize;
ops->ioctl = stdio_pipe_op_ioctl;
ops->close = stdio_pipe_op_close;
}
1 change: 1 addition & 0 deletions librt/libc/stdio/pipe/pipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,6 @@ int pipe(long size, int flags)

memcpy(&ioObject->object.data.pipe.attachment, &attachment,
sizeof(struct dma_attachment));
ioObject->object.data.pipe.options = 0;
return ioObject->fd;
}
10 changes: 10 additions & 0 deletions librt/libds/include/ds/streambuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ streambuffer_clear_option(
_In_ streambuffer_t* stream,
_In_ unsigned int option));

DSDECL(void,
streambuffer_get_bytes_available_in(
_In_ streambuffer_t* stream,
_Out_ size_t* bytesAvailableOut));

DSDECL(void,
streambuffer_get_bytes_available_out(
_In_ streambuffer_t* stream,
_Out_ size_t* bytesAvailableOut));

DSDECL(size_t,
streambuffer_stream_out(
_In_ streambuffer_t* stream,
Expand Down
22 changes: 22 additions & 0 deletions librt/libds/streambuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,28 @@ streambuffer_try_truncate(
atomic_fetch_add(&stream->consumer_comitted_index, bytes_comitted);
}

void
streambuffer_get_bytes_available_in(
_In_ streambuffer_t* stream,
_Out_ size_t* bytesAvailableOut)
{
unsigned int write_index = atomic_load(&stream->producer_comitted_index);
unsigned int read_index = atomic_load(&stream->consumer_index);
size_t bytes_available = bytes_readable(stream->capacity, read_index, write_index);
*bytesAvailableOut = bytes_available;
}

void
streambuffer_get_bytes_available_out(
_In_ streambuffer_t* stream,
_Out_ size_t* bytesAvailableOut)
{
unsigned int write_index = atomic_load(&stream->producer_index);
unsigned int read_index = atomic_load(&stream->consumer_comitted_index);
size_t bytes_available = bytes_writable(stream->capacity, read_index, write_index);
*bytesAvailableOut = bytes_available;
}

size_t
streambuffer_stream_out(
_In_ streambuffer_t* stream,
Expand Down
6 changes: 3 additions & 3 deletions revision.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
#ifndef _REVISION_H_
#define _REVISION_H_

#define BUILD_DATE "22 May 2020"
#define BUILD_TIME "14:03:48"
#define BUILD_DATE "25 May 2020"
#define BUILD_TIME "06:24:21"
#define BUILD_SYSTEM "clang"

#define REVISION_MAJOR 0
#define REVISION_MINOR 6
#define REVISION_BUILD 14774
#define REVISION_BUILD 14778

#endif //!_REVISION_H_

2 comments on commit c5cf97a

@Meulengracht
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TeamCity ValiOS / i386 / Build Build 355 is now running

@Meulengracht
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TeamCity ValiOS / i386 / Build Build 355 outcome was SUCCESS
Summary: Running Build time: 00:02:50

Please sign in to comment.