Je dois créer un nouveau dossier doté des mêmes permissions qu’un autre dossier. Mon but ultime pour cette tâche est de copier un répertoire et son contenu entièrement. C’est l’un de mes premiers pas et je n’arrive pas à le faire fonctionner.
Ce que j’ai est ci-dessous:
struct stat srcstat; int srcstatus = stat(source, &srcstat); if (chdir(dest)) if (mkdir(dest, srcstat.st_mode)){ printf("error: could not create \n"); exit(1); }
source est une chaîne contenant le chemin d’access au dossier dont je souhaite utiliser les permissions. dest est une chaîne avec le chemin d’access au nouveau dossier.
le ls avec les anciennes et nouvelles permissions de dossiers est ci-dessous
drwxrwxrwx 2 kingacev CS-Majors 4096 Apr 18 17:03 test drwxr-xr-x 2 kingacev CS-Majors 4096 Apr 18 18:12 test3
Ma première pensée est que je ne peux pas utiliser srcstat.st_mode de la manière que je tente. Si tel est le cas, existe-t-il un moyen tout aussi simple de faire ce que j’essaie de faire? Si non, à quelle distance de la marque suis-je?
Vous ne respectez pas le ” umask “, un paramètre par processus qui masque les bits d’autorisation dans les opérations de création de fichiers et de répertoires.
Il n’y a pas de moyen sûr de désactiver le umask. Ce que vous devriez faire à la place, c’est créer le répertoire avec le mode zéro (c.-à-d. Tout access refusé) et ensuite utiliser chmod
(l’appel système, pas la commande shell du même nom) pour ajuster les permissions à ce que vous voulez.
Votre fragment de programme contient de nombreux autres bogues. C’est difficile à faire, et peut-être que si vous vous trompez , ce sera une faille de sécurité, alors je vais écrire le code correct en détail:
int make_directory_like(const char *to_create, const char *prototype) { struct stat st; if (lstat(prototype, &st)) { fprintf(stderr, "lstat: %s: %s\n", prototype, strerror(errno)); return -1; } if (!S_ISDIR(st.st_mode)) { fprintf(stderr, "lstat: %s: %s\n", prototype, strerror(ENOTDIR)); return -1; } /* create directory initially with no perms at all - this is the only safe way to suppress the effects of the umask. */ if (mkdir(to_create, 0000)) { if (errno != EEXIST) { fprintf(stderr, "mkdir: %s: %s\n", to_create, strerror(errno)); return -1; } else { /* check whether the thing that exists is a directory */ struct stat st2; if (lstat(to_create, &st2)) { fprintf(stderr, "lstat: %s: %s\n", to_create, strerror(errno)); return -1; } if (!S_ISDIR(st2.st_mode)) { fprintf(stderr, "mkdir: %s: %s\n", to_create, strerror(EEXIST)); return -1; } } } if (chmod(to_create, st.st_mode & ~S_IFMT)) { fprintf(stderr, "chmod: %s: %s\n", to_create, strerror(errno)); return -1; } return 0; }
Exercices pour vous:
lstat
plutôt que stat
? mkdir
échoue avec errno == EEXIST
? chdir
comme vous le faisiez? (Il y a deux raisons.) mkdir
sur le chemin de création, alors que nous ne soaps pas si quelque chose existe déjà? Vous voulez définir le umask
à zéro. Voir http://man7.org/linux/man-pages/man2/umask.2.html
Sinon, certains bits (souvent 022, comme vous le voyez) seront toujours effacés.
umask(0);