Witam,
Napisałem program który ma imitować wywołanie ls -l jednak rekurencyjnie przyjmując za parametry ścieżkę docelową oraz ilość zagłębień. Pobierając nazwę elementu z pierwszego listowania, sprawdza czy jest folderem i czy liczba zagłębień pozwala na wylistowanie. Jeżeli tak to tworzy nowy proces potomny, który listuje folder.
Dla wywołania:
program.o ./ 1
..
- (D) Test1
- (D) Test2
- (D) Test3
program powinien utworzyć trzy procesy i wykonać ls dla każdego podfolderu łącznie z folderem bazowym.
Problem w tym, że nie do końca funkcjonuje. Moje typy to złe parametry execl(), co próbowałem na różne sposoby (podając ścieżkę bezwzględną) lub zła sciezka do *DIR. Jednak gdy testuje wszystkie parametry wydają się poprawne.
Kod kompiluje sie poprawnie.
#include "stdio.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/wait.h"
#include "stdlib.h"
#include "dirent.h"
#include "sys/stat.h"
#include <pwd.h>
#include <time.h>
#include <grp.h>
// Struktury i zawartosc katalogow
char *nazwa;
struct dirent *dirent;
struct stat buf;
struct stat dane;
struct passwd *pw;
struct group *g;
// Listowanie katalogu o podanej w parametrze funkcji sciezce
void ls(char* sciezka, int v) {
printf("Sciezka (ls): %s\n",sciezka);
printf("V: %d\n",v);
DIR* drzewo = opendir(sciezka);
if (drzewo) {
while ((dirent = readdir(drzewo)) != NULL) {
int e;
e = stat(dirent->d_name, &buf);
printf("\nStat (%d): %s\n",e,dirent->d_name);
// Usuwanie ., ..
// if (strcmp(dirent->d_name, ".") == 0) { }
// if (strcmp(dirent->d_name, "..") == 0) { }
// Wyswietlanie charakterystyki pliku
pw = getpwuid(buf.st_uid);
g = getgrgid(buf.st_gid);
printf("%ldB ",buf.st_size);
printf("%s ",ctime(&buf.st_mtime));
printf("%s ",pw->pw_name);
// Prawa dostepu
// Uzytkownik
if (buf.st_mode & S_IRUSR) printf("r"); else printf("-");
if (buf.st_mode & S_IWUSR) printf("w"); else printf("-");
if (buf.st_mode & S_IXUSR) printf("x "); else printf("- ");
// Grupa
printf("%s ",g->gr_name);
if (buf.st_mode & S_IRGRP) printf("r"); else printf("-");
if (buf.st_mode & S_IWGRP) printf("w"); else printf("-");
if (buf.st_mode & S_IXGRP) printf("x "); else printf("- ");
// Pozostale
printf("* ");
if (buf.st_mode & S_IROTH) printf("r"); else printf("-");
if (buf.st_mode & S_IWOTH) printf("w"); else printf("-");
if (buf.st_mode & S_IXOTH) printf("x "); else printf("- ");
// Typ pliku
if (buf.st_mode & S_IFDIR) printf("KAT"); else printf("FIL");
if (buf.st_mode & S_IFCHR) printf("SPC");
printf(" %s",dirent->d_name);
// printf("<>:%d",buf.st_nlink);
}
}
closedir(drzewo);
printf("\n");
}
int main(int argc, char** argv) {
// Ilosc zaglebien
int zaglebienia = 0;
// Nazwa katalogu
char katalog[255];
// Badanie ilosci parametrow
if (argc > 1) {
// Badanie ilosci zaglebien.
// Jest zaglebienie = 0 to nigdy nie powstanie proces potomny
zaglebienia = atoi(argv[2]);
if (zaglebienia == 0) {
// Wylistuj katalog z parametru i zakoncz
printf("Wchodze, KAT:%s\n",argv[1]);
ls(argv[1],0);
}
else {
// Wylistuj katalog i uruchom n-procesow potomnych listujacych n-podkatalogow zmniejszajac zaglebienie o 1
// Sprawdz, czy uzytkownik nie podal wiecej zaglebien niz jest to mozliwe do wykonania
// Listowanie katalogu (synchronizacja)
int procesy = 0;
ls(argv[1],1);
// Pobieranie danych o podkatalogach do wylistowania
DIR* drzewo = opendir(argv[1]);
if (drzewo) {
while ((dirent = readdir(drzewo)) != NULL) {
stat(dirent->d_name, &buf);
if (buf.st_mode & S_IFDIR) {
if ( (strcmp(dirent->d_name, ".") != 0) && (strcmp(dirent->d_name, "..") != 0) )
{
procesy++;
// Istnieje podkatalog do wylistowania i nie jest to ani "." ani ".." ani ".nazwa"
if (fork() == 0) {
// Proces potomny listujacy TEN podkatalog
printf("%s:%d\n",dirent->d_name, zaglebienia-1);
char scie[255];
sprintf(scie,"%s%s",argv[1],dirent->d_name);
// printf("Sciezka: /users/gwozniak/so/%s\n",dirent->d_name);
printf("(PROC %d) sciezka: %s zagl_akt: %d zagl_nast: %d\n",procesy,scie,zaglebienia, zaglebienia-1);
execl("/users/gwozniak/so/prog8.o","prog8.o", scie, zaglebienia-1, (char *) 0);
//sleep(2); // Synchronizacja
} // if: fork
} // if: strcmp-2
} // if: strcmp-1
} // if: while
} // if: drzewo
closedir(drzewo);
} // if: zaglebienia
return 0;
}
else {
// Bledne wywolanie programu
printf("Bledne wywolanie programu.\n");
printf("Prawidlowe wywolanie: ./program <katalog> <zaglebienia>\n");
printf("Przyklad: ./program /usr 0\n");
return 1;
}
}