1

のように、ディレクトリとディレクトリ内のファイルを削除する関数を何度か作成しようとしましたが、rm -rうまくいきませんでした。私が試したテクニックは次のとおりです。

/* rm command */
#include <fts.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

#define DEBUG

int rm_file(const char **argv);
int rm_tree(const char **argv);
void usage(void);

int rflag = 0;

int main(int argc, char *argv[])
{
    int ch;

    while((ch = getopt(argc, argv, "Rr")) != -1) {
        switch(ch) {
            case 'R':
            case 'r':
                rflag = 1;
                break;
            default:
                usage();
        }
    }
    argc -= optind;
    argv += optind;

    while(*argv) {
        if(rflag)
            rm_tree(argv);
        else
            rm_file(argv);
        argv++;
    }

    return 0;
}

int rm_tree(const char **argv)
{
    FTS *ftsp;
    FTSENT *ftsent;

    if((ftsp = fts_open(argv, 0, NULL)) == NULL) {
        fprintf(stderr, "error: rm: can't stat directory\n");
        return 1;
    }

    while((ftsent = fts_read(ftsp)) != NULL) {
        switch(ftsent->fts_info) {
            case FTS_DNR:
                fprintf(stderr, "error: rm: can't stat directory\n");
                break;
#ifndef DEBUG
            case FTS_D:
                rm_tree(&ftsent->fts_accpath);
                break;
#endif
            case FTS_F:
                if(unlink(ftsent->fts_accpath) == -1) {
                    fprintf(stderr, "error: rm: can't remove file\n");
                }
                break;
            case FTS_SL:
                if(unlink(ftsent->fts_accpath) == -1) {
                    fprintf(stderr, "error: rm: can't remove file\n");
                }
                break;
            default:
                if(unlink(ftsent->fts_accpath) == -1) {
                    fprintf(stderr, "error: rm: can't remove file\n");
                }
                break;
        }
    }

    if(rmdir(*argv) == -1) {
        fprintf(stderr, "error: rm: can't remove directory\n");
        return 1;
    }

    return 0;
}

int rm_file(const char **argv)
{
    struct stat st;

    if(lstat(*argv, &st) == -1) {
        fprintf(stderr, "error: rm: can't stat file\n");
        return 1;
    }

    if(S_ISDIR(st.st_mode)) {
        fprintf(stderr, "error: rm: can't remove directory\n");
        return 1;
    }

    if(unlink(*argv) == -1) {
        fprintf(stderr, "error: rm: can't remove file\n");
        return 1;
    }

    return 0;
}

void usage(void) 
{
    fprintf(stderr, "usage: rm file1 file2\n");
    exit(1);
}

しかし、常に、セグメンテーション違反が発生するか、機能しません。私は正しい方向を見ていますか?ftw()関数と関数を使ってみましたがopendir()、これを機能させる方法がわかりませんでした。誰か助けていただければ幸いです。

デバッグタグに含まれるコードは、失敗する傾向がある場所です。

4

1 に答える 1

4

OpenBSDrmなどのオープンソースオペレーティングシステムのソースコードを分析して、実際にどのように行われるかを見てみましょう(を探してください)。rm_tree

于 2012-12-09T21:40:13.360 に答える