2017-09-18 2 views
1

J'ai vu des messages comme this sur StackOverflow qui parle de l'utilisation de uname() pour obtenir le numéro de version actuel du noyau (stocké dans utsname.release). Cependant, cela renvoie une chaîne.Vérifier la version du noyau à l'exécution en C

Y at-il un moyen de retourner le ou vérifier la version du noyau comme une valeur numérique de sorte que l'on peut simplement utiliser if (version >= min_req_ver) { ... }?

La seule méthode que j'ai vu est d'inclure linux/version.h et de vérifier LINUX_VERSION_CODE cependant dans CentOS par exemple, ce numéro de version n'est pas mis à jour quand on exécute un noyau plus récent que le noyau par défaut. La fonction uname() signale cependant la version actuelle correcte du noyau à travers les distributions Linux (sur celles que j'ai testées), y compris dans un scénario tel que l'utilisation de CentOS avec un noyau plus récent.

+1

vous pouvez essayer de l'analyser avec sscanf, mais il faut savoir, qu'il peut y avoir des extensions non numériques à la sortie (à savoir « 3.16.0-4-amd64 », etc.). Plus précis est probablement utsname.version, mais il y a encore plus de foo dedans rendant l'analyse difficile (c'est-à-dire "# 1 SMP Debian 3.16.7-ckt11-1 + deb8u3 (2015-08-04)"). Malheureusement, le schéma rigide "major.minor.patchlevel" ne tient pas en pratique – Ctx

+1

vous ne pouvez pas simplement comparer la version comme vous l'avez mentionné (version> = min_req), car elle incluait la version du noyau, Major, Minor et le numéro de patch. Utilisez la fonction 'uname', obtenez chaque version en utilisant sscanf et comparez. – Rajeshkumar

Répondre

2

Utilisez la fonction ci-dessous pour obtenir la version Kernel, Major, Minor et Patch et comparez la version individuelle.

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <ctype.h> 
#include <sys/utsname.h> 

int main(void) { 

    struct utsname buffer; 
    char *p; 
    long ver[16]; 
    int i=0; 

    errno = 0; 
    if (uname(&buffer) != 0) { 
     perror("uname"); 
     exit(EXIT_FAILURE); 
    } 

    printf("system name = %s\n", buffer.sysname); 
    printf("node name = %s\n", buffer.nodename); 
    printf("release  = %s\n", buffer.release); 
    printf("version  = %s\n", buffer.version); 
    printf("machine  = %s\n", buffer.machine); 

#ifdef _GNU_SOURCE 
    printf("domain name = %s\n", buffer.domainname); 
#endif 

    p = buffer.release; 

    while (*p) { 
     if (isdigit(*p)) { 
      ver[i] = strtol(p, &p, 10); 
      i++; 
     } else { 
      p++; 
     } 
    } 

    printf("Kernel %d Major %d Minor %d Patch %d\n", ver[0], ver[1], ver[2], ver[3]); 

    return EXIT_SUCCESS; 
} 
+0

J'ai utilisé 'sscanf' à la fin. – jwbensley