Skip to content

Commit 4df9d00

Browse files
committed
Add kernel socket receive and scanf
1 parent 089e8c8 commit 4df9d00

File tree

2 files changed

+158
-0
lines changed

2 files changed

+158
-0
lines changed

common/kernel/source/kernel/socket.c

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <sys/protosw.h>
2525

2626
#include <ps4/kernel.h>
27+
#include <ps4/error.h>
2728

2829
int ps4KernelSocketCreate(struct thread *td, Ps4KernelSocket **sock, int domain, int type, int protocol)
2930
{
@@ -367,3 +368,152 @@ int ps4KernelSocketSend(struct thread *td, Ps4KernelSocket *sock, const void *da
367368

368369
return sosend(sock, NULL, &auio, 0, NULL, 0, td);
369370
}
371+
372+
int ps4StringEstimateFormatArguments(const char *format, size_t *count)
373+
{
374+
size_t c = 0;
375+
376+
if(format == NULL)
377+
return PS4_ERROR_ARGUMENT_PRIMARY_MISSING;
378+
379+
if(count == NULL)
380+
return PS4_ERROR_ARGUMENT_OUT_MISSING;
381+
382+
for(size_t i = 0; format[i] != '\0'; ++i)
383+
{
384+
if(format[i] == '%')
385+
{
386+
++c;
387+
388+
if(format[i + 1] == '\0')
389+
return PS4_ERROR_ARGUMENT_MALFORMED;
390+
391+
if(format[i + 1] == '%')
392+
i++;
393+
}
394+
}
395+
396+
*count = c;
397+
398+
return PS4_OK;
399+
}
400+
401+
// FIXME: Slow, improve me
402+
int ps4KernelSocketReceiveString(struct thread *td, Ps4KernelSocket *sock, void **data, size_t *size, size_t sizeMax)
403+
{
404+
uint8_t *_data;
405+
size_t _size;
406+
size_t offset;
407+
size_t outSize;
408+
int r;
409+
410+
if(sizeMax == 0)
411+
sizeMax = SIZE_MAX;
412+
413+
_size = 1024;
414+
if(_size > sizeMax - 1)
415+
_size = sizeMax - 1;
416+
417+
offset = 0;
418+
419+
ps4KernelMemoryAllocateData((void **)&_data, _size + 1);
420+
421+
while(1)
422+
{
423+
r = ps4KernelSocketReceive(td, sock, _data + offset, &outSize, 1, MSG_WAITALL);
424+
425+
if(r != PS4_OK)
426+
{
427+
ps4KernelMemoryFree(data);
428+
return PS4_ERROR_BAD_REQUEST;
429+
}
430+
431+
if(_data[offset] == '\n')
432+
break;
433+
434+
if(offset == _size)
435+
{
436+
_size *= 2;
437+
ps4KernelMemoryReallocateData((void **)&_data, _size + 1);
438+
}
439+
440+
++offset;
441+
}
442+
443+
_data[offset + 1] = '\0';
444+
*data = (void *)_data;
445+
*size = offset + 2;
446+
447+
return PS4_OK;
448+
}
449+
450+
int ps4KernelSocketScanSizedWithArgumentList(struct thread *td, Ps4KernelSocket *sock, size_t size, int *match, const char *format, va_list args)
451+
{
452+
void *data;
453+
int r;
454+
size_t outSize;
455+
456+
if(match == NULL || format == NULL)
457+
return PS4_ERROR_ARGUMENT_MISSING;
458+
459+
r = ps4KernelSocketReceiveString(td, sock, &data, &outSize, size);
460+
461+
if(r == PS4_OK)
462+
{
463+
*match = vsscanf(data, format, args);
464+
ps4KernelMemoryFree(data);
465+
}
466+
467+
return r;
468+
}
469+
470+
int ps4KernelSocketScanWithArgumentList(struct thread *td, Ps4KernelSocket *sock, int *match, const char *format, va_list args)
471+
{
472+
return ps4KernelSocketScanSizedWithArgumentList(td, sock, 0, match, format, args);
473+
}
474+
475+
int ps4KernelSocketScan(struct thread *td, Ps4KernelSocket *sock, int *match, const char *format, ...)
476+
{
477+
va_list args;
478+
int r;
479+
480+
va_start(args, format);
481+
r = ps4KernelSocketScanWithArgumentList(td, sock, match, format, args);
482+
va_end(args);
483+
484+
return r;
485+
}
486+
487+
int ps4KernelSocketReceive(Ps4KernelThread *td, Ps4KernelSocket *sock, const void *data, size_t *size, size_t sizeMax, int flags)
488+
{
489+
struct uio auio;
490+
struct iovec iov;
491+
492+
if(td == NULL)
493+
return PS4_ERROR_ARGUMENT_THREAD_MISSING;
494+
if(sock == NULL)
495+
return PS4_ERROR_ARGUMENT_PRIMARY_MISSING;
496+
if(data == NULL)
497+
return PS4_ERROR_ARGUMENT_OUT_MISSING;
498+
if(data == NULL)
499+
return PS4_ERROR_ARGUMENT_OUT_MISSING;
500+
if(sizeMax == 0)
501+
return PS4_ERROR_ARGUMENT_SIZE_NULL;
502+
503+
iov.iov_base = (void *)data;
504+
iov.iov_len = sizeMax;
505+
506+
auio.uio_iov = &iov;
507+
auio.uio_iovcnt = 1;
508+
auio.uio_segflg = UIO_SYSSPACE;
509+
auio.uio_rw = UIO_READ;
510+
auio.uio_td = td;
511+
auio.uio_offset = 0;
512+
auio.uio_resid = iov.iov_len;
513+
514+
int r = soreceive(sock, NULL, &auio, NULL, NULL, &flags);
515+
516+
*size = sizeMax - iov.iov_len;
517+
518+
return r;
519+
}

include/ps4/kernel/socket.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include <netinet/in.h>
4+
#include <sys/socket.h>
45
#include <sys/socketvar.h>
56

67
typedef struct socket Ps4KernelSocket;
@@ -23,3 +24,10 @@ int ps4KernelSocketPrintWithArgumentList(struct thread *td, Ps4KernelSocket *soc
2324
int ps4KernelSocketPrint(struct thread *td, Ps4KernelSocket *sock, const char *format, ...);
2425
int ps4KernelSocketPrintHexDump(struct thread *td, Ps4KernelSocket *sock, const void *data, size_t size);
2526
int ps4KernelSocketSend(struct thread *td, Ps4KernelSocket *sock, const void *data, size_t size);
27+
28+
int ps4KernelSocketReceiveString(struct thread *td, Ps4KernelSocket *sock, void **data, size_t *size, size_t sizeMax);
29+
30+
int ps4KernelSocketScanSizedWithArgumentList(struct thread *td, Ps4KernelSocket *sock, size_t size, int *match, const char *format, va_list args);
31+
int ps4KernelSocketScanWithArgumentList(struct thread *td, Ps4KernelSocket *sock, int *match, const char *format, va_list args);
32+
int ps4KernelSocketScan(struct thread *td, Ps4KernelSocket *sock, int *match, const char *format, ...);
33+
int ps4KernelSocketReceive(Ps4KernelThread *td, Ps4KernelSocket *sock, const void *data, size_t *size, size_t sizeMax, int flags);

0 commit comments

Comments
 (0)