diff --git a/src/include/syscallno.h b/src/include/syscallno.h index e191bdd01720f2dbbc73f11b356d4bc619e4f076..eeed27f2e9f7696a6491bb79fef26e44c374c56b 100644 --- a/src/include/syscallno.h +++ b/src/include/syscallno.h @@ -113,6 +113,7 @@ #define SYSCALL_LIO_DUP 102 #define SYSCALL_LIO_STREAM_ORIGIN 103 #define SYSCALL_LIO_PIPE 104 +#define SYSCALL_LIO_IOCTL 105 #define SYSCALL_LIO_SRV_SERVICE_REGISTER 110 #define SYSCALL_LIO_SRV_TREE_SET_RING 111 diff --git a/src/kernel2/include/lostio/client.h b/src/kernel2/include/lostio/client.h index c8862bece1a821247ffe04c5e53fef4c58d69fcc..df1cfc7d8fb35d6bc6bf126b2a4ac1a5d5c6fbc4 100644 --- a/src/kernel2/include/lostio/client.h +++ b/src/kernel2/include/lostio/client.h @@ -177,6 +177,16 @@ int lio_truncate(struct lio_stream* s, uint64_t size); */ int lio_close(struct lio_stream* s); +/** + * Führt einen ressourcenspezifischen Befehl auf einem Stream aus. + * + * @param s Stream, auf den sich der Befehl bezieht + * @param cmd Auszuführender Befehl (LIO_IOCTL_*-Konstanten) + * + * @return 0 bei Erfolg, negativ im Fehlerfall. + */ +int lio_ioctl(struct lio_stream* s, int cmd); + /** * Inhalt eines Verzeichnisses auslesen */ diff --git a/src/kernel2/include/syscall.h b/src/kernel2/include/syscall.h index a60f42c4db412eaf2f76e9809048c492b8820ea7..a713a73267aa6c170cf1a5c2c6f15c58732365fe 100644 --- a/src/kernel2/include/syscall.h +++ b/src/kernel2/include/syscall.h @@ -250,6 +250,9 @@ int syscall_lio_sync(lio_usp_stream_t* stream_id); void syscall_lio_read_dir(lio_usp_resource_t* res, size_t start, size_t num, struct lio_usp_dir_entry* dent, ssize_t* result); +/// Ressourcenspezifischen Befehl ausführen +int syscall_lio_ioctl(lio_usp_stream_t* stream_id, int cmd); + /// Neue Datei anlegen void syscall_lio_mkfile(lio_usp_resource_t* parent, const char* name, size_t name_len, lio_usp_resource_t* result); diff --git a/src/kernel2/src/lostio/client.c b/src/kernel2/src/lostio/client.c index 551218733e1abbea608404e87d0cf04f9e027857..07ad62aa3e8fb15161e4bd1e476db20e9e267f1b 100644 --- a/src/kernel2/src/lostio/client.c +++ b/src/kernel2/src/lostio/client.c @@ -742,6 +742,19 @@ int lio_close(struct lio_stream* s) return 0; } +/** + * Führt einen ressourcenspezifischen Befehl auf einem Stream aus. + * + * @param s Stream, auf den sich der Befehl bezieht + * @param cmd Auszuführender Befehl (LIO_IOCTL_*-Konstanten) + * + * @return 0 bei Erfolg, negativ im Fehlerfall. + */ +int lio_ioctl(struct lio_stream* s, int cmd) +{ + return -ENOTTY; +} + /** * Inhalt eines Verzeichnisses auslesen */ diff --git a/src/kernel2/src/syscall.c b/src/kernel2/src/syscall.c index ace33ca7d7f1f56f03419be15602aa44777f0b5c..c7a4432a88a557ba5ebff81bdc325a94ade15423 100644 --- a/src/kernel2/src/syscall.c +++ b/src/kernel2/src/syscall.c @@ -135,6 +135,7 @@ void syscall_init() syscall_register(SYSCALL_LIO_PROBE_SERVICE, &syscall_lio_probe_service, 2); syscall_register(SYSCALL_LIO_DUP, &syscall_lio_dup, 2); syscall_register(SYSCALL_LIO_STREAM_ORIGIN, &syscall_lio_stream_origin, 1); + syscall_register(SYSCALL_LIO_IOCTL, &syscall_lio_ioctl, 2); syscall_register(SYSCALL_LIO_SRV_SERVICE_REGISTER, &syscall_lio_srv_service_register, 4); diff --git a/src/kernel2/src/syscalls/lostio.c b/src/kernel2/src/syscalls/lostio.c index a2369c858ea361b322d20b7aa6db8ba01355fe4f..1c7fd3f3ca63d7ca964d1e63d81ac51e788a9a5b 100644 --- a/src/kernel2/src/syscalls/lostio.c +++ b/src/kernel2/src/syscalls/lostio.c @@ -312,6 +312,20 @@ void syscall_lio_read_dir(lio_usp_resource_t* resid, size_t start, size_t num, free(int_buf); } +/// Ressourcenspezifischen Befehl ausführen +int syscall_lio_ioctl(lio_usp_stream_t* stream_id, int cmd) +{ + struct lio_usp_stream* fd; + + // TODO: Ein paar is_userspace + fd = lio_usp_get_stream(current_process, *stream_id); + if (fd == NULL) { + return -EBADF; + } + + return lio_ioctl(fd->stream, cmd); +} + /// Neue Datei anlegen void syscall_lio_mkfile(lio_usp_resource_t* parent, const char* name, size_t name_len, lio_usp_resource_t* result) diff --git a/src/modules/include/syscall.h b/src/modules/include/syscall.h index d5a283b9a060b4a43ccfd3a3313f8f8926be28a8..ee4cad3222f5d16ee8ca51014cde8ea0c209d2fc 100644 --- a/src/modules/include/syscall.h +++ b/src/modules/include/syscall.h @@ -319,6 +319,16 @@ int64_t lio_seek(lio_stream_t s, uint64_t offset, int whence); */ int lio_truncate(lio_stream_t s, uint64_t size); +/** + * Führt einen ressourcenspezifischen Befehl auf einem Stream aus. + * + * @param s Stream, auf den sich der Befehl bezieht + * @param cmd Auszuführender Befehl (LIO_IOCTL_*-Konstanten) + * + * @return 0 bei Erfolg, negativ im Fehlerfall. + */ +int lio_ioctl(lio_stream_t s, int cmd); + /** * Liest Einträge einer Verzeichnisressource aus. * diff --git a/src/modules/lib/syscalls/lostio.c b/src/modules/lib/syscalls/lostio.c index 4a9212f2526ea34058c36f4a4d981c92c2ce0f59..888b76da657859c8e8f77ed16f81fa0a15500e8f 100644 --- a/src/modules/lib/syscalls/lostio.c +++ b/src/modules/lib/syscalls/lostio.c @@ -426,6 +426,31 @@ int lio_truncate(lio_stream_t s, uint64_t size) return result; } +/** + * Führt einen ressourcenspezifischen Befehl auf einem Stream aus. + * + * @param s Stream, auf den sich der Befehl bezieht + * @param cmd Auszuführender Befehl (LIO_IOCTL_*-Konstanten) + * + * @return 0 bei Erfolg, negativ im Fehlerfall. + */ +int lio_ioctl(lio_stream_t s, int cmd) +{ + int result; + + asm( + "pushl %3;" + "pushl %2;" + "mov %1, %%eax;" + "int $0x30;" + "add $0x10, %%esp;" + : "=a" (result) + : "i" (SYSCALL_LIO_IOCTL), "r" (&s), "r" (cmd) + : "memory"); + + return result; +} + /** * Liest Einträge einer Verzeichnisressource aus. *