IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Refaire la commande cp avec des appels système


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 27
    Par défaut Refaire la commande cp avec des appels système
    Bonsoir,

    Je dois réaliser un programme en C qui reprend dans les grandes lignes la commande cp du terminal (sans ses options, juste la commande de base) en utilisant les appels système. Donc les fonction telles que open, write, read, fstat...

    Dans les faits, lire un fichier avec read et écrire dans un autre avec write en y allant caractère par caractère pour effectuer le copier-coller, je sais le faire. Mon problème se pose sur la création du nouveau fichier. L'exécution doit avoir "la même forme" que cp donc comme suit:

    ./cp  /.../fichierSource  /.../repertoireDest/ 
    Sauf que voilà, je n'arrive pas à créer mon fichier dans le répertoire de destination. Si il n'y avait pas de répertoire spécifique pour la destination ça aurait été simple, je serais passé par open avec les modes correspondants (O_CREAT et O_WRONLY) ou par creat. Comment je dois m'y prendre pour faire ceci sachant que la concaténation de mon argv[2] et argv[1] n'est pas possible car argv[1] peut ne pas avoir seulement le nom du fichier à copier mais également son chemin d'accès (absolu ou relatif) ? Et d'ailleurs, je ne suis pas sûr que j'ai le droit d'utiliser la bibliothèque string.h dans mon programme pour faire une concaténation.

    Auriez-vous une solution à cela ? Comment créer le fichier dont le nom sera identique au fichier source (selon la condition que l'on se trouve dans un répertoire autre) mais à un emplacement bien spécifique ?

    Merci de votre aide.

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Tu lis le chemin du fichier source pour extraire le nom du fichier (équivalent de la commande basename): le fichier commence après le dernier séparateur de chemin ('/' ou un des champs de locale?).

    Il te faudra aussi détecter si le chemin cible désigne un dossier existant ou un futur fichier.

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 27
    Par défaut
    Merci pour la réponse. J'ai vu qu'il y avait la fonction basename dans libgen.h mais aussi dirname pour isoler le chemin d'accès. Je vais reprendre l'élaboration du code et je reviendrais vers vous en cas de besoins.

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 27
    Par défaut
    C'est bon j'ai pu réaliser ma fonction cp basique, basename et dirname m'ont aidé a écrire le le chemin associer au nom du fichier en fonction de condition comme la copie dans le même dossier.

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par TuxThePenguin Voir le message
    Auriez-vous une solution à cela ? Comment créer le fichier dont le nom sera identique au fichier source (selon la condition que l'on se trouve dans un répertoire autre) mais à un emplacement bien spécifique ?
    Bonjour

    En fait, la règle de gestion de la commande cp ne se base pas sur notre position (répertoire autre) mais sur la façon dont on l'invoque
    • soit il y a toute une liste de noms (exemple cp xxx yyy zzz aaa bbb ccc) et dans ce cas, le dernier nom de la liste doit impérativement être un nom de dossier et ainsi tous les autres fichiers qui précèdent y sont copiés en gardant leur nom d'origine (donc ici ce sera ccc/xxx, ccc/yyy, ccc/zzz, ccc/aaa, ccc/bbb).
    • soit il n'y a que deux noms (exemple cp xxx yyy) et dans ce cas, soit le second nom est juste un nom de fichier et la commande recopie le premier dans le second, soit c'est un nom de dossier et dans ce cas elle se comporte comme dans le premier cas


    Bien entendu, cela n'empêche pas les problèmes. Notemment si plusieurs fichiers ont le même "nom de base" car seul ce dernier est pris en compte quand elle copie dans un dossier (exemple cp d1/xxx d2/xxx d3/xxx dossier_dest) => le permier "d1/xxx" sera copié et chacun des autres "xxx" fera l'objet d'une question pour savoir s'il doit l'écraser (sauf si on a rajouté l'option "-f" (force) à la commande).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Merci de cliquer sur le bouton en bas de page si le problème est effectivement résolu

  7. #7
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 27
    Par défaut
    Merci de ta réponse Sve@r.

    Je n'avais pas pensé à ces conditions-là. J'ai donc réadapté mon code pour faire de la copie de multiple fichier dans un même répertoire.

    Par contre, je me pose une question, afin de savoir si le dernier argument entré est un répertoire, j'utilise l'appel système stat et regarde ensuite ce qu'il résulte de la fonction IS_DIR sur argv[argc-1]. Cependant en reprenant ton second exemple d'exécution de cp (la copie d'un fichier sous un nouveau nom), le second argument sera un fichier inexistant jusqu'alors. Si je souhaite intégrer ceci dans mon code, je ne peut utiliser stat et ensuite IS_REG sur argv[2] afin de savoir si c'est un fichier car ce dernier n'existe pas encore.
    Je cherche surement le compliqué là où il n'est pas, car si argv[2] n'est pas un répertoire, on peut se dire qu'il est forcément un fichier et faire dans e cas la copie sous un nouveau nom, mais ne pourrait-il pas être autre chose qu’un fichier nous empêchant donc cette copie sous nouveau nom?

    Je voudrais également savoir, pour toutes ces commandes intégrées au système comme cp, ls, cat, mv.... Dans un langage comme le c (ou autre) puis compilé ou elles ont été réalisé autrement ? Comment ont elles été codé? Dans un langage comme le c (ou autre) puis compilé ou elles ont été réalisé autrement ?

    Merci

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par TuxThePenguin Voir le message
    Cependant en reprenant ton second exemple d'exécution de cp (la copie d'un fichier sous un nouveau nom), le second argument sera un fichier inexistant jusqu'alors. Si je souhaite intégrer ceci dans mon code, je ne peut utiliser stat et ensuite IS_REG sur argv[2] afin de savoir si c'est un fichier car ce dernier n'existe pas encore.
    Je cherche surement le compliqué là où il n'est pas, car si argv[2] n'est pas un répertoire, on peut se dire qu'il est forcément un fichier et faire dans e cas la copie sous un nouveau nom, mais ne pourrait-il pas être autre chose qu’un fichier nous empêchant donc cette copie sous nouveau nom?
    Dans Unix/Linux tout est fichier. Mais tout fichier n'est pas forcément équivalent l'un par rapport à l'autre.
    Tu as
    • le fichier classique ou ordinaire (fichier texte, document tableur, film, musique, image). C'est le fichier de base. Sa caractéristique est qu'il n'a aucune caractéristique ou structure spécifique reconnaissable par Unix ; même si sa structure est reconnaissable par un logiciel particulier (vlc, gimp, libreoffice, etc)
    • le dossier (ou répertoire). C'est une entrée à 2 colonnes contenant 1) un nom de fichier et 2) un n° d'inode. Grace à ce mécanisme, le système peut retrouver quel dossier contient quel fichier et comment y accéder quand on demande à l'ouvrir
    • le pipe (outil de communication bloquant entre 2 processus)
    • le socket (outil de communication non bloquant entre 2 processus)
    • le device (fichier dédié aux périphériques IO). Ils sont de 2 type: "b" (IO mode "block" comme le disque), et "c" (IO mode "caractère, comme l'écran). Ce ne sont pas vraiment des fichiers dans le sens conventionnel mais plutôt des points d'entrée vers l'endroit où le noyau gère ses périphériques
    • le lien symbolique (les raccourcis zindow en sont une pâle copie). Il s'agit d'un fichier contenant le nom d'un autre fichier. Mais pour que le système sache que ce nom est un nom de fichier (et non un simple contenu texte), il faut que ce fichier soit typé différemment

    Il existe aussi le type "lien réel" mais comme il ne s'agit que d'un autre nom relié à un même n° d'inode, et que le type d'un fichier se situe dans son inode, on peut alors l'assimiler au fichier auquel il est lié

    La copie ne peut pas s'appliquer aux devices, ni aux sockets ou aux pipes. Elle pourrait s'adresser au lien symbolique mais les primitives système, quand on accède au lien symbolique, vont automatiquement s'adresser au fichier qui y est référencé donc ce type là est squeezé y compris par stat() qui ne sait pas voir les liens symboliques. Seule lstat() sait les distinguer. La copie d'un répertoire pourrait revenir à recréer un second répertoire contenant les mêmes noms de fichier que le premier ce qui serait peu utile donc dans ce cas précis, et avec une option appropriée, la commande crée un second répertoire et y copie tous les fichiers qui s'y trouvent y compris en récursif si le repertoire en contient d'autres (ceci dit, je n'ai jamais testé la copie d'un répertoire qui contiendrait des fichiers exotiques comme devices ou sockets). Mais je ne pense pas que ton prof te demande d'aller si loin.
    Donc finalement avec un peu de réflexion (et d'intuition) on se rend compte que le cp ne s'appliquera qu'aux fichiers dits "classiques". Si tu veux le reproduire, il te faut donc juste tester S_ISREG et éventuellement S_ISDIR. Ou plutôt S_ISDIR sur le dernier nom et si ce n'est pas bon, alors tu dois avoir impérativement avoir 2 et seulement 2 noms et le dernier répondant au S_ISREG.
    Puis chacun des autres fichiers précédents ce dernier doivent, eux, juste répondre au S_ISREG et sinon pour chaque fichier n'y répondant pas, tu le squeeze.

    Citation Envoyé par TuxThePenguin Voir le message
    Je voudrais également savoir, pour toutes ces commandes intégrées au système comme cp, ls, cat, mv.... Dans un langage comme le c (ou autre) puis compilé ou elles ont été réalisé autrement ? Comment ont elles été codé? Dans un langage comme le c (ou autre) puis compilé ou elles ont été réalisé autrement ?
    Unix/Linux ont été écrits en C. C'est pour ça que le C est si plébiscité dans le monde Unix/Linux => tu peux à loisir taper dans le système avec ton propre code en utilisant les primitives système (primitives utilisées aussi par les commandes classiques).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 27
    Par défaut
    Merci pour tous ces renseignements qui m'auront été bien utiles. Je viens de commencer mes cours de système d'exploitation et ceci a pu éclaircir certains points.

    J'avais déjà vu la partie sur les liens symbolique et les liens physique. Saurais-tu pourquoi cette notion de lien physique n'a pas été implémenter sous les systèmes Windows contrairement au liens symboliques faisant référence aux raccourcis sous Windows ?

    Et par curiosité si ce n'est pas indiscret, depuis quand t'intéresses-tu à l'univers unix/linux et parcours donc ce système d'exploitation ? Car tu as l'air d'avoir pas mal de connaissance sur ce domaine au niveau du fonctionnement du système d'exploitation et e sont architecture.

    Je passe le sujet en résolu

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [CGI-BIN] Problèmes avec les appels systèmes
    Par ozyamdias dans le forum Apache
    Réponses: 1
    Dernier message: 27/08/2007, 17h17
  2. besoin d'aide avec les session
    Par alain57 dans le forum Langage
    Réponses: 4
    Dernier message: 29/06/2006, 20h25
  3. Besoin d'aide avec les regxp
    Par vodevil dans le forum Langage
    Réponses: 1
    Dernier message: 04/04/2006, 12h28
  4. Besoin d'aide avec les fichier htaccess et htpasswd
    Par Polux000 dans le forum Apache
    Réponses: 2
    Dernier message: 26/01/2006, 00h05
  5. Réponses: 2
    Dernier message: 29/08/2003, 17h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo