mkdir() не работает

Привет, я пытаюсь создать функцию рекурсивного копирования, которая эмулирует программу CP в Unix. Таким образом, если я запущу программу с параметром -r, она скопирует папку со всеми ее подкаталогами. Я использую следующую функцию.

void copyDirectory(char *destDir, char *dirName)
{
    printf("copyDirectory run \n");

    int charCnt;
    int srcFd;
    int dstFd;
    char* sourcePath;
    char* destPath;

    DIR *dir = opendir(dirName);
    if(dir == NULL){
        return;
    }

    char Path[256], *EndPtr = Path;

    struct dirent *e;
    strcpy(Path, dirName);

    EndPtr += (strlen(dirName)+1);
    while((e = readdir(dir)) != NULL){
        sourcePath = malloc(strlen(Path)+1+strlen(e->d_name));
        destPath = malloc(strlen(destDir)+1+strlen(Path));
        strcpy(destPath, destDir);
        strcat(destPath, slash);
        strcat(destPath, Path);

        if (0 != access(destPath, F_OK)) {
            mkdir(destPath,0777);
            printf("mkdir %s \n", destPath);
        }

        strcpy(sourcePath, Path);
        strcat(sourcePath, slash);
        strcat(sourcePath, e->d_name);

        printf("copyDirectory destPath = %s \n", destPath);
        printf("copyDirectory sourcePath = %s \n", sourcePath);

        if(strcmp(e->d_name, dott) == 0){
            continue;
        }
        if(strcmp(e->d_name, dot) == 0){
            continue;
        }


        if(whatType(sourcePath) == 1){
            copyDirectory(destDir, sourcePath);   
        }
        else{
            /* copyFile(destPath, sourcePath);*/
        } 

        free(sourcePath);
        free(destPath);
    }
}

Кажется, это работает нормально, если я запускаю программу, используя следующую командную строку.

Mycopy Sourcefolder/ DestinationFoler/

но когда я запускаю его с помощью этой командной строки, функция mkdir внутри моей программы перестает работать.

Mycopy Sourcefolder/Subfolder/ DestinationFoler/

Странно то, что я поместил маркер printf внутри вызова mkdir, чтобы увидеть, что такое destPath, и форматирование не отличается от того, когда я вызываю программу, не используя подкаталог. Что здесь происходит?


person user2661167    schedule 15.09.2013    source источник
comment
Если бы только был способ проверить возвращаемый результат mkdir, который дал бы вам подсказку, почему он терпит неудачу....   -  person Duck    schedule 15.09.2013
comment
@Duck означает проверить код возврата, проверить errno, чтобы понять, почему он не работает. +1 за сарказм. Но никогда не знаешь, когда постер здесь не получит такого юмора из-за разного фона....   -  person jim mcnamara    schedule 15.09.2013
comment
@jim mcnamara - вы правы насчет разного происхождения, который я иногда упускаю из виду, но я не стремился к сарказму, а какой следующий вопрос я должен задать себе вместо того, чтобы бежать в Stackoverflow? Может быть, я становлюсь раздражительным в старости, но в последнее время проблема с кодом возврата стала любимой мозолью. Почему этому не уделяется больше внимания в школах и других источниках программирования?   -  person Duck    schedule 15.09.2013
comment
На самом деле я получил sarcarsm и с тех пор проверил с возвратом ошибки и обнаружил, что мой destPath неверен. Мне нужно, чтобы mkdir DestinationFolder/SubFolder, а не DestinationFolder/SourceFolder/SubFoloder. Как я могу это сделать? Я попытался поставить strcat(destPath, basename(Path)); но это заставит его работать, если у меня будет только один подкаталог, но испортит каталоги, если у меня будут более глубокие деревья каталогов.   -  person user2661167    schedule 15.09.2013


Ответы (1)


Всегда рекомендуется проверять возвращаемое значение функций и системных вызовов, таких как mkdir. Это нашло бы вас (возможную) ошибку в вашем коде, которую я объясню ниже.

if (0 != mkdir(destPath,0777)) {
  printf("When executing: mkdir(\"%s\")\n", destPath);
  perror("mkdir");
  exit(1);
}

При этом вы увидите:

When executing: mkdir("trg/src")
mkdir: No such file or directory

Ваш код, кажется, работает нормально. Чтобы проверить это, мне пришлось добавить несколько #include и #define и реализовать функцию whatType, поэтому все, что я пишу, предполагает, что у нас есть аналогичные определения для них.

Существует большая разница между вашим кодом и cp -r в Linux, что может объяснить проблему, свидетелем которой вы являетесь. Предположим, у вас есть существующая структура каталогов под src/ и что нет каталога с именем trg/. если вы выполните:

cp -r src trg

это приведет к тому, что вся структура каталогов src/ будет скопирована в trg/, то есть, если у вас есть файл src/f, он будет скопирован в trg/f.

С другой стороны, если изначально существовал каталог с именем trg, то вся структура каталогов src/ будет скопирована в trg/src/, то есть файл src/f будет скопирован в trg/src/f.

С вашим кодом поведение всегда второе. Ваш код предполагает, что целевой корневой каталог существует: первый каталог, который он пытается создать, всегда trg/src. Это не удается, если trg/ еще не существует.

person nickie    schedule 15.09.2013
comment
на самом деле это моя цель. если каталог существует, он должен создать trg/src/file, но проблема, с которой я столкнулся, заключается в том, что когда я пытался скопировать src/subfolder/ в trg, он должен попытаться сделать mkdir trg/subfolder, а не trg/src/subfolder - person user2661167; 15.09.2013
comment
Есть ли простой способ просто удалить первое слово из строки, используя / в качестве символа разграничения? - person user2661167; 15.09.2013
comment
Функция strchr(s, c) найдет первое вхождение символа c в строку s и вернет указатель на него или NULL, если он не существует. Этот указатель плюс один удаляет первое слово. - person nickie; 15.09.2013