summaryrefslogtreecommitdiffstats
path: root/src/VBox/GuestHost/OpenGL/util/filenet.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 03:01:46 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 03:01:46 +0000
commitf8fe689a81f906d1b91bb3220acde2a4ecb14c5b (patch)
tree26484e9d7e2c67806c2d1760196ff01aaa858e8c /src/VBox/GuestHost/OpenGL/util/filenet.c
parentInitial commit. (diff)
downloadvirtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.tar.xz
virtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.zip
Adding upstream version 6.0.4-dfsg.upstream/6.0.4-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/GuestHost/OpenGL/util/filenet.c')
-rw-r--r--src/VBox/GuestHost/OpenGL/util/filenet.c385
1 files changed, 385 insertions, 0 deletions
diff --git a/src/VBox/GuestHost/OpenGL/util/filenet.c b/src/VBox/GuestHost/OpenGL/util/filenet.c
new file mode 100644
index 00000000..178c015e
--- /dev/null
+++ b/src/VBox/GuestHost/OpenGL/util/filenet.c
@@ -0,0 +1,385 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#ifdef WINDOWS
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+
+#include "cr_error.h"
+#include "cr_mem.h"
+#include "cr_string.h"
+#include "cr_bufpool.h"
+#include "cr_net.h"
+#include "cr_endian.h"
+#include "cr_threads.h"
+#include "net_internals.h"
+
+typedef enum {
+ CRFileMemory,
+ CRFileMemoryBig
+} CRFileBufferKind;
+
+#define CR_FILE_BUFFER_MAGIC 0x89134539
+
+#ifndef WINDOWS
+#define O_BINARY 0
+#endif
+
+typedef struct CRFileBuffer {
+ unsigned int magic;
+ CRFileBufferKind kind;
+ unsigned int len;
+ unsigned int allocated;
+ unsigned int pad;
+} CRFileBuffer;
+
+static struct {
+ int initialized;
+ int num_conns;
+ CRConnection **conns;
+ CRBufferPool *bufpool;
+#ifdef CHROMIUM_THREADSAFE
+ CRmutex mutex;
+#endif
+ CRNetReceiveFuncList *recv_list;
+ CRNetCloseFuncList *close_list;
+} cr_file;
+
+static void
+crFileReadExact( CRConnection *conn, void *buf, unsigned int len )
+{
+ char *dst = (char *) buf;
+
+ while ( len > 0 )
+ {
+ int num_read = read( conn->fd, buf, len );
+
+ if ( num_read < 0 )
+ {
+ crError( "Bad bad bad file error!" );
+ }
+ if (num_read == 0)
+ {
+ crError( "END OF FILE!" );
+ }
+
+ dst += num_read;
+ len -= num_read;
+ }
+}
+
+static void
+crFileWriteExact( CRConnection *conn, const void *buf, unsigned int len )
+{
+ int retval = write( conn->fd, buf, len );
+ if ( retval < (int) len )
+ {
+ crError( "crFileWriteExact: %s (tried to write %d bytes, actually wrote %d)", conn->filename, len, retval );
+ }
+}
+
+static void
+crFileAccept( CRConnection *conn, const char *hostname, unsigned short port )
+{
+ (void)hostname;
+ conn->file_direction = CR_FILE_READ;
+ conn->fd = open( conn->filename, O_RDONLY | O_BINARY );
+ if (conn->fd < 0)
+ {
+ crError( "Couldn't open %s for reading!", conn->filename );
+ }
+ (void) port;
+}
+
+static void
+*crFileAlloc( CRConnection *conn )
+{
+ CRFileBuffer *buf;
+
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&cr_file.mutex);
+#endif
+
+ buf = (CRFileBuffer *) crBufferPoolPop( cr_file.bufpool, conn->buffer_size );
+
+ if ( buf == NULL )
+ {
+ crDebug( "Buffer pool was empty, so I allocated %d bytes",
+ (int)(sizeof(CRFileBuffer) + conn->buffer_size) );
+ buf = (CRFileBuffer *)
+ crAlloc( sizeof(CRFileBuffer) + conn->buffer_size );
+ buf->magic = CR_FILE_BUFFER_MAGIC;
+ buf->kind = CRFileMemory;
+ buf->pad = 0;
+ buf->allocated = conn->buffer_size;
+ }
+
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&cr_file.mutex);
+#endif
+
+ return (void *)( buf + 1 );
+}
+
+static void
+crFileSingleRecv( CRConnection *conn, void *buf, unsigned int len )
+{
+ crFileReadExact( conn, buf, len );
+}
+
+static void
+crFileSend( CRConnection *conn, void **bufp, const void *start, unsigned int len )
+{
+ CRFileBuffer *file_buffer;
+ unsigned int *lenp;
+
+ if ( bufp == NULL )
+ {
+ /* we are doing synchronous sends from user memory, so no need
+ * to get fancy. Simply write the length & the payload and
+ * return. */
+ if (conn->swap)
+ {
+ len = SWAP32(len);
+ }
+ crFileWriteExact( conn, &len, sizeof(len) );
+ crFileWriteExact( conn, start, len );
+ return;
+ }
+
+ file_buffer = (CRFileBuffer *)(*bufp) - 1;
+
+ CRASSERT( file_buffer->magic == CR_FILE_BUFFER_MAGIC );
+
+ /* All of the buffers passed to the send function were allocated
+ * with crFileAlloc(), which includes a header with a 4 byte
+ * length field, to insure that we always have a place to write
+ * the length field, even when start == *bufp. */
+ lenp = (unsigned int *) start - 1;
+ *lenp = len;
+
+ crFileWriteExact(conn, lenp, len + sizeof(int) );
+
+ /* reclaim this pointer for reuse and try to keep the client from
+ accidentally reusing it directly */
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&cr_file.mutex);
+#endif
+ crBufferPoolPush( cr_file.bufpool, file_buffer, conn->buffer_size );
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&cr_file.mutex);
+#endif
+ *bufp = NULL;
+}
+
+static void
+crFileFree( CRConnection *conn, void *buf )
+{
+ CRFileBuffer *file_buffer = (CRFileBuffer *) buf - 1;
+
+ CRASSERT( file_buffer->magic == CR_FILE_BUFFER_MAGIC );
+ conn->recv_credits += file_buffer->len;
+
+ switch ( file_buffer->kind )
+ {
+ case CRFileMemory:
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&cr_file.mutex);
+#endif
+ crBufferPoolPush( cr_file.bufpool, file_buffer, conn->buffer_size );
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&cr_file.mutex);
+#endif
+ break;
+
+ case CRFileMemoryBig:
+ crFree( file_buffer );
+ break;
+
+ default:
+ crError( "Weird buffer kind trying to free in crFileFree: %d", file_buffer->kind );
+ }
+}
+
+int
+crFileRecv( void )
+{
+ CRMessage *msg;
+ int i;
+
+ if (!cr_file.num_conns)
+ {
+ return 0;
+ }
+ for ( i = 0; i < cr_file.num_conns; i++ )
+ {
+ CRFileBuffer *file_buffer;
+ unsigned int len;
+ CRConnection *conn = cr_file.conns[i];
+
+ crFileReadExact( conn, &len, sizeof( len ) );
+
+ CRASSERT( len > 0 );
+
+ if ( len <= conn->buffer_size )
+ {
+ file_buffer = (CRFileBuffer *) crFileAlloc( conn ) - 1;
+ }
+ else
+ {
+ file_buffer = (CRFileBuffer *)
+ crAlloc( sizeof(*file_buffer) + len );
+ file_buffer->magic = CR_FILE_BUFFER_MAGIC;
+ file_buffer->kind = CRFileMemoryBig;
+ file_buffer->pad = 0;
+ }
+
+ file_buffer->len = len;
+
+ crFileReadExact( conn, file_buffer + 1, len );
+
+ conn->recv_credits -= len;
+
+ msg = (CRMessage *) (file_buffer + 1);
+ crNetDispatchMessage( cr_file.recv_list, conn, msg, len );
+
+ /* CR_MESSAGE_OPCODES is freed in
+ * crserverlib/server_stream.c
+ *
+ * OOB messages are the programmer's problem. -- Humper 12/17/01 */
+ if (msg->header.type != CR_MESSAGE_OPCODES && msg->header.type != CR_MESSAGE_OOB)
+ {
+ crFileFree( conn, file_buffer + 1 );
+ }
+ }
+
+ return 1;
+}
+
+static void
+crFileHandleNewMessage( CRConnection *conn, CRMessage *msg,
+ unsigned int len )
+{
+ CRFileBuffer *buf = ((CRFileBuffer *) msg) - 1;
+
+ /* build a header so we can delete the message later */
+ buf->magic = CR_FILE_BUFFER_MAGIC;
+ buf->kind = CRFileMemory;
+ buf->len = len;
+ buf->pad = 0;
+
+ crNetDispatchMessage( cr_file.recv_list, conn, msg, len );
+}
+
+static void
+crFileInstantReclaim( CRConnection *conn, CRMessage *mess )
+{
+ crFileFree( conn, mess );
+}
+
+void
+crFileInit( CRNetReceiveFuncList *rfl, CRNetCloseFuncList *cfl, unsigned int mtu )
+{
+ (void) mtu;
+
+ cr_file.recv_list = rfl;
+ cr_file.close_list = cfl;
+
+ if (cr_file.initialized)
+ {
+ return;
+ }
+
+ cr_file.num_conns = 0;
+ cr_file.conns = NULL;
+
+#ifdef CHROMIUM_THREADSAFE
+ crInitMutex(&cr_file.mutex);
+#endif
+ cr_file.bufpool = crBufferPoolInit(16);
+
+
+ cr_file.initialized = 1;
+}
+
+static int
+crFileDoConnect( CRConnection *conn )
+{
+ conn->file_direction = CR_FILE_WRITE;
+ /* NOTE: the third parameter (file permissions) is only used/required when
+ * we specify O_CREAT as part of the flags. The permissions will be
+ * masked according to the effective user's umask setting.
+ */
+#ifdef WINDOWS
+ conn->fd = open( conn->filename, O_CREAT | O_WRONLY | O_BINARY |
+ S_IREAD | S_IWRITE);
+#else
+ conn->fd = open( conn->filename, O_CREAT | O_WRONLY | O_BINARY,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+#endif
+ if (conn->fd < 0)
+ {
+ crWarning( "Couldn't open %s for writing!", conn->filename );
+ return 0;
+ }
+ return 1;
+}
+
+static void
+crFileDoDisconnect( CRConnection *conn )
+{
+ close( conn->fd );
+ conn->type = CR_NO_CONNECTION;
+ crMemcpy( cr_file.conns + conn->index, cr_file.conns + conn->index+1,
+ (cr_file.num_conns - conn->index - 1)*sizeof(*(cr_file.conns)) );
+ cr_file.num_conns--;
+}
+
+void
+crFileConnection( CRConnection *conn )
+{
+ int n_bytes;
+
+ CRASSERT( cr_file.initialized );
+
+ conn->type = CR_FILE;
+ conn->Alloc = crFileAlloc;
+ conn->Send = crFileSend;
+ conn->SendExact = crFileWriteExact;
+ conn->Recv = crFileSingleRecv;
+ conn->Free = crFileFree;
+ conn->Accept = crFileAccept;
+ conn->Connect = crFileDoConnect;
+ conn->Disconnect = crFileDoDisconnect;
+ conn->InstantReclaim = crFileInstantReclaim;
+ conn->HandleNewMessage = crFileHandleNewMessage;
+ conn->index = cr_file.num_conns;
+ conn->sizeof_buffer_header = sizeof( CRFileBuffer );
+ conn->actual_network = 0;
+
+ conn->filename = crStrdup( conn->hostname );
+
+ n_bytes = ( cr_file.num_conns + 1 ) * sizeof(*cr_file.conns);
+ crRealloc( (void **) &cr_file.conns, n_bytes );
+
+ cr_file.conns[cr_file.num_conns++] = conn;
+}
+
+CRConnection**
+crFileDump( int* num )
+{
+ *num = cr_file.num_conns;
+
+ return cr_file.conns;
+}
+