[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Lost] [Patch] init_execute relative Pfade und $PATH
Am Sonntag, 23. März 2008 01.47:19 schrieb Kevin Wolf:
> Antoine Kaufmann schrieb:
> > + strncpy(program, cmd, program_len);
> > + program[program_len] = 0;
> > + printf("program: '%s' ", program);
>
> Debugausgabe, und dazu noch eine englische. Schande! ;-)
Die ist schon deutsch. Ich habe nur den Namen der Variablen übernommen. *g*
> > + // Pruefen ob es sich um einen Pfad handelt
> > + abs_path = io_get_absolute_path(program);
> > + f = fopen(abs_path, "r");
> > + if (f == NULL) {
>
> Zum einen fände ich es grundsätzlich schöner, wenn die kurze Bedingung
> der then-Pfad ist, ansonsten habe ich bis zum else schon wieder
> vergessen, worum es geht.
Die fällt jetzt eh weg.
> In diesem speziellen Fall (und unten nochmal) öffnest du f ja nur zum
> prüfen, ob es das gibt. Hatten wir nicht neulich ein access() aufgenommen?
Hm stimmt...
> > + printf("dir: '%s' pp: '%s'\n", dir, program_path);
>
> Debugausgabe
>
> > + // Pruefen ob die Datei existiert
> > + f = fopen(program_path, "r");
> > + if (f != NULL) {
> > + // Wenn ja, wird ein Puffer alloziert und abs_path
> > gesetzt + abs_path = malloc(strlen(program_path) + 1);
>
> Memleak. abs_path muß erst freigegeben werden.
Hat was.
> > + // Wenn kein Programm gefunden wurde, wird abgebrochen
> > + if (abs_path == NULL) {
> > + return 0;
> > + }
>
> Kann abs_path jemals NULL sein? Wenn ja, ist es so geschickt, oben fopen
> mit NULL als Dateinamen aufzurufen?
Jetzt schon.
> > === commmands.c
> > ==================================================================
> > + if (wait == TRUE) {
> > + while (waitpid(pid, &status, 0) != pid);
> > + }
> > + return status;
>
> Wenn wait == FALSE, ist status undefiniert.
Das ist so eh Bockmist. Denn damit kriegt man von shell ständig Befehl nicht
gefunden, wenn ein Programm nicht sauber terminiert.
Hier der 2. Anlauf.
=== init.c
==================================================================
--- init.c (/lost/trunk/src/modules/lib/init.c) (revision 1451)
+++ init.c (/lost/local/src/modules/lib/init.c) (revision 1451)
@@ -38,6 +38,8 @@
#include "string.h"
#include "init.h"
#include "stdlib.h"
+#include <io.h>
+#include <unistd.h>
// Kindprozess eintragen
extern void wait_child_add(pid_t pid);
@@ -88,17 +90,78 @@
}
-
/**
*
*/
-
pid_t init_execute(const char* cmd)
{
pid_t pid;
+ // Vollstaendigen Pfad des Programmes finden
+ size_t program_len = strcspn(cmd, " ");
+ char program[program_len + 1];
+ char* abs_path;
+
+ strncpy(program, cmd, program_len);
+ program[program_len] = 0;
+
+ // Pruefen ob es sich um einen Pfad handelt
+ abs_path = io_get_absolute_path(program);
+ if (access(abs_path, R_OK) != 0) {
+ // Den absoluten Pfad freigeben
+ free(abs_path);
+ abs_path = NULL;
+
+ // Es handelt sich nicht um eine Pfadangabe, dann wird jetzt PATH
+ // durchsucht.
+ const char* path = getenv("PATH");
+ if (path == NULL) {
+ return 0;
+ }
+
+ // Sonst wird jetzt eine Kopie davon angefertigt um sie auseinander zu
+ // nehmen.
+ char path_backup[strlen(path) + 1];
+ char* dir;
+ strcpy(path_backup, path);
+
+ dir = strtok(path_backup, ";");
+ while (dir != NULL) {
+ // Verzeichnis + / + Programm + \0
+ size_t dir_len = strlen(dir);
+ char program_path[dir_len + 1 + program_len + 1];
+ strcpy(program_path, dir);
+ program_path[dir_len] = '/';
+ strcpy(program_path + dir_len + 1, program);
+
+ // Pruefen ob die Datei existiert
+ if (access(program_path, R_OK) == 0) {
+ // Wenn ja, wird ein Puffer alloziert und abs_path gesetzt
+ abs_path = malloc(strlen(program_path) + 1);
+ strcpy(abs_path, program_path);
+ break;
+ }
+
+ dir = strtok(NULL, ";");
+ }
+ }
+
+ // Wenn kein Programm gefunden wurde, wird abgebrochen
+ if (abs_path == NULL) {
+ return 0;
+ }
+
+ // Ansonsten wird jetzt der ganze Befehl in einen Puffer kopiert
+ size_t abs_path_len = strlen(abs_path);
+ size_t args_len = strlen(cmd + program_len);
+ size_t rpc_size = abs_path_len + args_len + 1;
+ char rpc_data[rpc_size];
+ strcpy(rpc_data, abs_path);
+ strcpy(rpc_data + abs_path_len, cmd + program_len);
+ free(abs_path);
+
// TODO: Relative Pfade
- pid = rpc_get_dword(1, "LOADELF ", strlen(cmd) + 1, (char*)cmd);
+ pid = rpc_get_dword(1, "LOADELF ", rpc_size, rpc_data);
// Kindprozess eintragen, falls er erfolgreich gestartet wurde
if (pid != 0) {
=== commmands.c
==================================================================
--- commmands.c (/lost/trunk/src/modules/c/shell/commmands.c) (revision 1451)
+++ commmands.c (/lost/local/src/modules/c/shell/commmands.c) (revision 1451)
@@ -67,122 +67,27 @@
#endif
-int shell_start_path_app(const char* cmd, const char* path, bool wait)
+int shell_start_path_app(const char* cmd, bool wait)
{
- const char* bindir_path = path;
- DIR* bindir = opendir(bindir_path);
- if(bindir == NULL)
- {
- DEBUG_MSG1("Konnte das Applikationsverzeichnis '%s' nicht finden",
- bindir_path);
+ DEBUG_MSG("Starte das Programm");
+ pid_t pid = init_execute(cmd);
+
+ // Fehler ist aufgetreten
+ if (pid == 0) {
return -1;
}
- struct dirent* dir_entry;
-
- do {
- dir_entry = readdir(bindir);
- if (dir_entry == NULL) {
- break;
- }
- if (shell_match_command(dir_entry->d_name, cmd) == TRUE) {
- // Hier wird nach Leerschlaegen gesucht, um festzustellen, ob dem
- // Befehl Argumente uebegeben werden sollen.
- char* start_opts = strchr(cmd, ' ');
- if (start_opts != NULL) {
- // Falls Argumente uebergeben werden sollen, wird der
- // Leerschlag, der die Argumente vom Programmnamen trennt durch
- // ein Nullbyte ersetzt, da das die Verarbeitung des
- // Programmnamens erleichtert.
- *start_opts = '\0';
-
- // Jetzt werden noch weitere Leerschlaege uebersprungen, da die
- // nicht erwuenscht sind.
- while (*(++start_opts) == ' ');
- start_opts--;
- }
-
- // Speicher fuer den neuen Pfad. Besteht aus: Dem Verzeichnis mit
- // den Anwendungen, einem Slash, dem Anwendungsnamen und einem
- // abschliessenden Nullbyte. Die seltsame Darstellung dient nur der
- // besseren Lesbarkeit, und wird hoffentlich vom Compiler
- // wegoptimiert ;-).
- char start_path[strlen(bindir_path) + 1 + strlen(cmd) + 1];
- bool insert_slash = (bindir_path[strlen(bindir_path)-1] != '/');
- memcpy(start_path, bindir_path, strlen(bindir_path));
- if (insert_slash) {
- start_path[strlen(bindir_path)] = '/';
- memcpy(start_path + strlen(bindir_path) + 1,
- cmd, strlen(cmd) + 1);
- } else {
- memcpy(start_path + strlen(bindir_path), cmd, strlen(cmd) + 1);
- }
-
-
- char* message;
-
- // FIXME: Hier sollten eigentlich keine mallocs() noetig sein...
- if (start_opts == NULL) {
- // Wenn keine Kommandozeilenargumente an das Programm
- // uebergeben werden sollen, muss nur der Pfad des Programms an
- // init geschickt werden.
- message = malloc(strlen(start_path) + 1);
- //memcpy(message, "LOADELF ", 8);
- memcpy((void*) ((dword)message/* + 8*/), start_path,
- strlen(start_path) + 1);
- } else {
- // Da vorher der Leerschlag durch ein Nullbyte ersetzt wurde,
- // wird das hier wieder korrigiert, damit die Argumente einfach
- // kopiert werden koennen.
- *start_opts = ' ';
-
- message = malloc(strlen(start_path) + 1 +
- strlen(start_opts));
-
- memcpy((void*) ((dword)message /*+ 8*/), start_path,
- strlen(start_path));
- memcpy((void*) ((dword)message /*+ 8 */+
- strlen(start_path)), start_opts,
- strlen(start_opts) + 1);
- }
-
- // Jetzt wird der RPC an Init geschickt. Hier sollte noch irgend
- // was hin, um zu warten bis der Prozess beendet wurde.
- //send_message(1, 512, 0, strlen(message) + 1, message);
- DEBUG_MSG("Starte das Programm");
- pid_t pid = init_execute(message);
-
- // Fehler ist aufgetreten
- if (pid == 0) {
- free(message);
- closedir(bindir);
- return -1;
- }
-
- // Wenn es gewuenscht wurde, wird jetzt gewartet, bis der Prozess
- // beendet wird.
- if (wait == TRUE) {
- int status;
- while (waitpid(pid, &status, 0) != pid);
- }
-
- // FIXME: s.o.
- free(message);
- closedir(bindir);
- return 0;
- }
-
- free(dir_entry);
-
- } while(dir_entry != NULL);
-
- closedir(bindir);
- return -1;
+ // Wenn es gewuenscht wurde, wird jetzt gewartet, bis der Prozess beendet
+ // wird.
+ if (wait == TRUE) {
+ int status;
+ while (waitpid(pid, &status, 0) != pid);
+ }
+ return 0;
}
/**
- * Wird aufgerufen, wenn keiner der internen Befehle passt. Dabei wird das
- * apps-Verzeichnis durchsucht.
+ * Wird aufgerufen, wenn keiner der internen Befehle passt.
*/
int shell_command_default(int argc, char* argv[], const char* cmd)
{
@@ -191,26 +96,12 @@
return 0;
}
- int result;
- const char* path = getenv("PATH");
-
- const char* cwd = getcwd(NULL, 0);
- result = shell_start_path_app(cmd, cwd, TRUE);
- free((char*) cwd);
-
- // FIXME: Das ist so eigentlich nicht richtig...
- if (result == 0) {
- return result;
- } else {
- result = shell_start_path_app(cmd, path, TRUE);
- if (result == 0) {
- return 0;
- }
+ if (shell_start_path_app(cmd, TRUE) == 0) {
+ return 0;
}
- puts("Befehl wurde nicht gefunden!");
-
- return 1;
+ puts("Befehl wurde nicht gefunden!");
+ return -1;
}
/**
@@ -219,38 +110,13 @@
int shell_command_start(int argc, char* argv[], const char* cmd)
{
DEBUG_MSG("start");
-
- char* space = strchr((char*) cmd, ' ');
- if (space == NULL) {
- DEBUG_MSG("space == NULL");
+
+ if (shell_start_path_app(cmd, TRUE) == 0) {
return 0;
- }
-
- cmd = space + 1;
-
- int result;
- const char* path = getenv("PATH");
- char* cwd = getcwd(NULL, 0);
+ }
- DEBUG_MSG("Starte aus dem aktuellen Verzeichnis");
- result = shell_start_path_app(cmd, cwd, FALSE);
- free(cwd);
-
- // FIXME: Das ist so eigentlich nicht richtig...
- if (result == 0) {
- DEBUG_MSG("result == 0");
- return result;
- } else {
- DEBUG_MSG("Starte aus dem Pfad");
- result = shell_start_path_app(cmd, path, FALSE);
- if (result == 0) {
- DEBUG_MSG("result == 0");
- return result;
- }
- }
puts("Befehl wurde nicht gefunden!");
-
- return 1;
+ return -1;
}