...
 
Commits (4)
  • Kevin Wolf's avatar
    libc: stdio_init(): fopen-Modus 's' gibt es nicht · ed0d89a5
    Kevin Wolf authored
    !  libc: Vor langer Zeit wurde einmal versehentlich in Commit f64c1b3c
       ein fopen-Modus 's' committet, der IO_OPEN_MODE_SYNC gesetzt hat (das
       aber wiederum ignoriert wird), am Tag danach aber in Commit 95134b9a
       wieder revertet. Davor und danach war es immer ein ungültiger Modus.
    
       Bevor fopen() jetzt anfangen kann, zu prüfen, ob es den übergebenen
       Modus überhaupt komplett versteht, muss zuerst das ungültige 's' in
       stdio_init() weg.
    Signed-off-by: Kevin Wolf's avatarKevin Wolf <kevin@tyndur.org>
    ed0d89a5
  • Kevin Wolf's avatar
    libc: fopen()-Modus korrekter parsen · 49d5afac
    Kevin Wolf authored
    ! libc: Bisher musste im fopen()-Modus das "+" direkt nach "r"/"w"/"a"
      kommen, damit es eine Wirkung hatte. Das ist falsch, denn dazwischen
      darf auch noch ein "b" kommen.
    
      Dieser Patch fixt den Parser, so dass er alle vorgesehenen Varianten
      akzeptiert, und die meisten nicht vorgesehenen mit EINVAL ablehnt.
      ("rb+b" usw. ist noch möglich, aber das sollte harmlos sein.)
    Signed-off-by: Kevin Wolf's avatarKevin Wolf <kevin@tyndur.org>
    49d5afac
  • Kevin Wolf's avatar
    libc: Nach fseek() io_res->os_eof zurücksetzen · a623f4f7
    Kevin Wolf authored
    ! libc: Wenn wir bis ans Ende der Datei gelesen haben und os_eof
      deswegen gesetzt wurde, muss das Flag nach einem fseek() wieder
      gelöscht werden, weil wir jetzt möglicherweise nicht mehr am Ende der
      Datei sind und feof() 0 zurückgeben soll. Wenn wir es doch sind, wird
      das nächste fread() das Flag wieder setzen.
    Signed-off-by: Kevin Wolf's avatarKevin Wolf <kevin@tyndur.org>
    a623f4f7
  • Max Reitz's avatar
    servmgr: Workaround für zyklische Abhängigkeiten · c8a7bd7e
    Max Reitz authored
    ! Es kann passieren, dass Service A auf B wartet, der auf C wartet. Dann
      melden sich diese beide beim servmgr, der dann für B darauf warten
      soll, dass B gestartet ist, und für A, dass B fertig ist. Da týndur
      leider keine Popupthreads für IPC benutzt, existiert aber nur ein
      wartender Thread. Wenn A später als B angefragt hat, wird also A ewig
      auf B warten, da B nie weiterlaufen kann, auch wenn C fertig ist.
      Ein einfacher Workaround ist es, zu einem Zeitpunkt immer nur einem
      anfragenden Service/Prozess das Privileg zu gestatten, den servmgr
      selbst zu benutzen, um zu warten. Alle anderen bekommen ein EAGAIN,
      wenn der Zielservice noch nicht angemeldet ist, und müssen das Warten
      selber übernehmen (hier als wiederholte Anfragen bei servmgr
      implementiert).
    Signed-off-by: Max Reitz's avatarMax Reitz <max@tyndur.org>
    c8a7bd7e
......@@ -26,6 +26,7 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <errno.h>
#include <string.h>
#include <init.h>
#include <rpc.h>
......@@ -36,8 +37,14 @@ static pid_t servmgr_pid(void);
bool servmgr_need(const char* service_name)
{
return rpc_get_dword(servmgr_pid(), "NEEDSERV", strlen(service_name) + 1,
(char*) service_name);
int result;
do {
result = rpc_get_int(servmgr_pid(), "NEEDSERV",
strlen(service_name) + 1, (char*) service_name);
} while (result == -EAGAIN);
return result == 1;
}
/**
......
......@@ -95,41 +95,47 @@ FILE* __create_file_from_lio_stream(lio_stream_t s)
FILE* fopen (const char* filename, const char* mode)
{
uint8_t attr;
int i;
//Attribute aus dem mode-String parsen
attr = 0;
int i;
for (i = 0; i < strlen(mode); i++) {
switch (mode[i]) {
case 'r':
attr |= IO_OPEN_MODE_READ;
if (mode[i + 1] == '+') {
attr |= IO_OPEN_MODE_WRITE;
}
break;
i = 0;
case 'w':
attr |= IO_OPEN_MODE_WRITE | IO_OPEN_MODE_CREATE |
IO_OPEN_MODE_TRUNC;
switch (mode[i++]) {
case 'r':
attr |= IO_OPEN_MODE_READ;
goto parse_plus;
// Bei w+ muss Lesen auch aktiviert werden.
if (mode[i + 1] == '+') {
attr |= IO_OPEN_MODE_READ;
}
break;
case 'w':
attr |= IO_OPEN_MODE_WRITE | IO_OPEN_MODE_CREATE |
IO_OPEN_MODE_TRUNC;
goto parse_plus;
case 'a':
attr |= IO_OPEN_MODE_WRITE | IO_OPEN_MODE_CREATE
| IO_OPEN_MODE_APPEND;
if (mode[i + 1] == '+') {
attr |= IO_OPEN_MODE_READ;
}
break;
case 'a':
attr |= IO_OPEN_MODE_WRITE | IO_OPEN_MODE_CREATE
| IO_OPEN_MODE_APPEND;
goto parse_plus;
case 'd':
attr |= IO_OPEN_MODE_DIRECTORY;
break;
}
case 'd':
attr |= IO_OPEN_MODE_DIRECTORY;
break;
parse_plus:
if (mode[i] == 'b') {
i++;
}
if (mode[i] == '+') {
attr |= IO_OPEN_MODE_READ | IO_OPEN_MODE_WRITE;
i++;
}
if (mode[i] == 'b') {
i++;
}
break;
}
if (mode[i] != '\0') {
errno = EINVAL;
return NULL;
}
// Datei oeffnen
......@@ -682,13 +688,14 @@ int fseek (FILE* io_res, long int offset, int origin)
}
out:
// ungetc-Buffer leeren
// ungetc-Buffer leeren. EOF ist auch nicht mehr gültig.
if (ret == 0) {
if (io_res->ungetc_count != 0) {
free(io_res->ungetc_buffer);
io_res->ungetc_buffer = NULL;
io_res->ungetc_count = 0;
}
io_res->os_eof = false;
}
return ret;
}
......
......@@ -61,12 +61,12 @@ void stdio_init(void)
size = fread(path, 1, 128, path_file);
path[size] = 0;
// Falls stdin schon geoeffnet wurde, wird freopen benutzt, damit siche
// nichts durcheinander kommt
// Falls stdin schon geoeffnet wurde, wird freopen benutzt, damit
// sicher nichts durcheinander kommt
if (stdin) {
freopen(path, "rs", stdin);
freopen(path, "r", stdin);
} else {
stdin = fopen(path, "rs");
stdin = fopen(path, "r");
}
fclose(path_file);
}
......
......@@ -40,6 +40,8 @@
#include <string.h>
#include <stdio.h>
#include <init.h>
#include <errno.h>
#include <lock.h>
#include "servmgr.h"
static void rpc_needserv(pid_t pid, uint32_t cid, size_t data_size, void* data);
......@@ -64,7 +66,7 @@ static void rpc_needserv(pid_t pid, uint32_t cid, size_t data_size, void* data)
// Pruefen ob der Name nullterminiert ist
if (!data_size || (name[data_size - 1] != 0)) {
rpc_send_dword_response(pid, cid, 0);
rpc_send_int_response(pid, cid, 0);
return;
}
......@@ -73,10 +75,26 @@ static void rpc_needserv(pid_t pid, uint32_t cid, size_t data_size, void* data)
} else {
// Noch nicht konfiguriert. Jetzt bleibt nur hoffen, dass der Dienst
// schon geladen wurde, sich aber noch nicht registriert hat.
static volatile uint32_t semaphore;
if (locked_increment(&semaphore) > 0) {
locked_decrement(&semaphore);
// Wir können nicht mehrere gleichzeitig warten lassen, weil das sonst
// zyklische Abhängigkeiten geben könnte
if (service_running(name)) {
rpc_send_int_response(pid, cid, true);
} else {
rpc_send_int_response(pid, cid, -EAGAIN);
}
return;
}
result = service_wait(name, 10000);
locked_decrement(&semaphore);
}
rpc_send_dword_response(pid, cid, result);
rpc_send_int_response(pid, cid, result);
}
/**
......