C言語システムコール-rmdir

rmdirシステムコール

概要

rmdirは指定ディレクトリを削除します。

ただし、削除するディレクトリの中は空である必要があります。


サンプルプログラム

指定ディレクトリ内部のファイルを全て削除して、ディレクトリを削除します。

ディレクトリ内部を再帰してのディレクトリ削除処理となります。


#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>

/* prototypes */
static int dir_clear(char *filepath);

/*!
 * @brief     ディレクトリでなければ削除する。
 * @param[in] filepath  ファイル名
 * @return    -1        error
 * @return     0        ディレクトリなので削除していない
 * @return     1        削除成功
 */
static int
is_file_delete(char *filepath)
{
    int rc = 0;
    struct stat sb = {0};
 
    rc = stat(filepath, &sb);
    if(rc < 0){
        printf("Error: stat() %s: %s\n", strerror(errno), filepath);
        return(-1);
    }
    if(S_ISDIR(sb.st_mode)) return(0);

    rc = unlink(filepath);
    if(rc < 0){
        printf("Error: unlink() %s: %s\n", strerror(errno), filepath);
        return(-1);
    }
    return(1);
}

/*!
 * @brief     ディレクトリ内部を再帰して削除する。
 * @param[in] filepath  ファイル名
 * @return    0:success/-1:failure
 * @sa        dir_clear()
 */
static int
recursive_dir_clear(char *filepath)
{
    int rc = 0;

    rc = is_file_delete(filepath);
    if(rc == 1) return(0);
    if(rc != 0) return(-1);

    /* ディレクトリ内部を再帰 */
    rc = dir_clear(filepath);
    if(rc != 0) return(-1);

    rc = rmdir(filepath);
    if(rc < 0){
        printf("Error: rmdir() %s: %s\n", strerror(errno), filepath);
        return(-1);
    }

    return(0);
}

/*!
 * @brief     ディレクトリ内部を削除する。
 * @param[in] filepath  ファイル名
 * @return    0:success/-1:failure
 */
static int
dir_clear(char *filepath)
{
    int rc = 0;
    DIR *dp = NULL;
    struct dirent *ent = NULL;
    char buf[BUFSIZ];

    dp = opendir(filepath);
    if(dp == NULL){
        printf("Error: opendir() %s %s\n", strerror(errno), filepath);
        return(-1);
    } 

    while((ent = readdir(dp)) != NULL){
        if((strcmp(".", ent->d_name) == 0) ||
           (strcmp("..", ent->d_name) == 0)) continue;

        snprintf(buf, sizeof(buf), "%s/%s", filepath, ent->d_name);
        rc = recursive_dir_clear(buf);
        if(rc != 0) break;
    }

    closedir(dp);
    return(rc);
}

/*!
 * @brief     ディレクトリパスを削除する。
 * @param[in] filepath  ディレクトリ名
 * @return    0:success/-1:failure
 */
static int
rmdir_path(char *filepath)
{
    int rc = 0;

    /* 内部ファイルを削除する */
    rc = dir_clear(filepath);
    if(rc != 0) return(-1);

    /* 指定ディレクトリを削除する */
    rc = rmdir(filepath);
    if(rc < 0){
        printf("Error: rmdir() %s: %s\n", strerror(errno), filepath);
        return(-1);
    }

    return(0);
}

int
main(int argc, char *argv[])
{
    if(argc != 2){
        fprintf(stderr, "Usage: %s path\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    if(rmdir_path(argv[1]) < 0) exit(EXIT_FAILURE);
    exit(EXIT_SUCCESS);
}


関連ページ