Linux & Systèmes PDF Gratuit

Cours Programmation Système en C sous Linux (Avancé)

Téléchargez ce manuel technique au format PDF pour maîtriser les appels système POSIX et l'API Linux en langage C. Ce poly de cours sert de tutoriel pratique et de référence : ce document constitue un polycopié de référence pour l'apprentissage de la programmation système. Le manuel couvre les primitives POSIX (fork, exec, signaux, IPC) et les interfaces Linux pour la gestion des processus, de l'IPC, des fichiers et de la programmation réseau. Extraits de code et exercices permettent une utilisation en travaux pratiques et une révision ciblée des concepts.

🎯 Ce que vous allez apprendre

  • Arguments et variables d'environnement — récupération et formatage des paramètres via argc/argv, conversion de chaînes en nombres avec atoi ou sscanf, formatage avec sprintf, lecture de la table environ, accès via getenv et modification locale avec putenv.
  • Processus, fork et gestion des PID/UID — comportement de fork(), distinctions père/fils, usages de getpid()/getppid(), et enjeux liés aux UID et Set-UID.
  • Lancement de programmes et sécurité (exec & system) — différence entre remplacement d'image avec exec* et invocation d'un shell via system(), risques d'injection et recommandations pour utiliser fork() + exec() dans les contextes sensibles.
  • Communication inter‑processus (tubes et FIFO) — création de pipes anonymes et nommés, redirection des flux, transmission de données binaires et protocoles simples père‑fils.
  • Threads POSIX et synchronisation — création/gestion de threads POSIX, passage de fonctions/pointeurs, prévention des conditions de course avec mutex et sémaphores POSIX.
  • Programmation réseau avec sockets TCP — notions d'adresses, services et ports, création de sockets TCP, connexion client/serveur et gestion robuste des E/S et des erreurs.
  • Signaux Unix — gestion des signaux courants (SIGINT, SIGTERM, SIGCHLD), installation de handlers avec sigaction et masquage via sigprocmask.
  • Réentrance des fonctions système — principes de réentrance, fonctions sûres dans les handlers, interaction entre signaux et E/S, et stratégies pour écrire des handlers réentrants évitant les races.

Concepts clés de la programmation système

La programmation système s'appuie sur des concepts fondamentaux : appels système, descripteurs de fichiers, modèles de processus et de threads, primitives de synchronisation et mécanismes d'IPC. Le contenu met l'accent sur la gestion des ressources (descripteurs, mémoires partagées), le traitement systématique des erreurs et la sécurité (permissions, Set-UID). Les exemples ciblent des pratiques reproductibles et mesurables, adaptées à la conception de services résilients et performants sur Debian/Ubuntu.

📑 Sommaire du document

  • Arguments d’un programme et variables d’environnement
  • Processus
  • Lancement d’un programme : exec
  • Communication entre processus
  • Threads Posix
  • Gestion du disque dur et des fichiers
  • Signaux
  • Programmation réseaux

Prérequis techniques détaillés

  • Système : Debian/Ubuntu (testé principalement sur les versions LTS récentes).
  • Compilateur : GCC 9 ou supérieur recommandé ; compatibilité avec GCC 8 généralement assurée.
  • Outils de construction : make, gcc, possibilité d'utiliser cmake pour certains exemples.
  • Bibliothèques et en-têtes : glibc compatible POSIX, <unistd.h>, <signal.h>, <pthread.h>, <sys/socket.h>, <sys/types.h> et <netinet/in.h>.
  • Accès : droits utilisateur standard suffisants pour la plupart des TP ; droits élevés requis uniquement pour expérimenter Set-UID ou ports privilégiés.

Exercices et Travaux Pratiques de programmation système

Le PDF inclut exemples de code compilables, énoncés d'exercices progressifs et indications d'auto‑évaluation. Les scénarios portent sur compilation et exécution sous Debian/Ubuntu, utilisation de gcc et make, ainsi que cas réseau et IPC réutilisables en laboratoire. Des pistes de correction et des commentaires méthodologiques sont proposés lorsque disponibles.

Objectifs des travaux pratiques

  • Implémentation d'un mini-shell avec gestion de redirections et de background.
  • Gestionnaire de processus simple (esquisse d'un ps-like) utilisant /proc et appels système.
  • Serveur TCP multi-threadé avec gestion robuste des E/S et synchronisation.
  • Échanges IPC via pipes, FIFO et mémoire partagée ; protocoles simples père‑fils.
  • TP sécurité : analyse des risques liés à system() et réécriture sécurisée avec fork() + exec().

💡 Pourquoi choisir ce cours ?

Rédigé par Rémy Malgouyres (LIMOS, Université Clermont 1), le document combine exposés concis et nombreux extraits de code C adaptés à Debian/Ubuntu. L'approche privilégie la pratique reproductible : chaque notion POSIX est illustrée par un exemple et un exercice, avec un accent marqué sur la sécurité et la conformité aux spécifications POSIX.

Pourquoi ce polycopié est une référence

Ce polycopié se distingue par son ancrage académique et sa méthodologie : cours et exercices conçus pour être exécutés dans des environnements Debian/Ubuntu standard, corrections commentées et cas pratiques mesurables. Les choix pédagogiques reflètent l'expérience de l'auteur au sein du laboratoire LIMOS, garantissant des exemples pertinents pour la conception de daemons, utilitaires système et composants réseau. La documentation indique clairement les limites d'usage et les configurations testées, facilitant la réutilisation en laboratoire et en milieu professionnel.

👤 À qui s'adresse ce cours ?

  • Public cible : étudiants en informatique et développeurs systèmes travaillant sur la programmation bas niveau sous Linux (daemons, utilitaires système, composants réseau).
  • Prérequis : maîtrise solide du langage C (pointeurs, gestion mémoire), familiarité avec le shell Unix et la compilation (gcc/make), et notions de base en réseaux (TCP/IP) pour suivre la partie sockets.

❓ Foire Aux Questions (FAQ)

Comment accéder et modifier une variable d'environnement depuis un programme C ?

Utilisez getenv("NOM") pour lire la valeur et putenv pour assigner une nouvelle chaîne sous la forme "NOM=VALEUR". La modification n'affecte que le processus courant et ses descendants ; la table complète est accessible via la variable externe environ.

Quand utiliser fork() versus exec(), et quels sont les risques liés à system() ?

fork() duplique le processus courant (utile pour préparer redirections ou créer un processus enfant), tandis que exec* remplace l'image du processus par un nouveau programme. system() invoque un shell et expose aux injections si des données non validées sont transmises ; privilégiez fork() + exec() pour réduire les vecteurs d'injection, en particulier avec des binaires Set‑UID.