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;
    }            
}