8
votes

Déterminez le système d'exploitation pendant l'exécution

Ni ISO C NOR POSIX n'offre une fonctionnalité pour déterminer le système d'exploitation sous-jacent pendant l'exécution. D'un point de vue théorique, cela n'a pas d'importance car c offre des emballages pour les appels système les plus courants et à partir d'un point de vue de cueillette NIT, il n'est même pas obligé de être un sous-jacent OS.

Cependant, dans de nombreux scénarios mondiaux réels, il s'est avéré utile d'en savoir plus sur l'environnement hôte que c est disposé à partager, par exemple. Afin de savoir où stocker les fichiers de configuration ou comment appeler SELECT () , donc:

Y a-t-il une manière idiomatique pour une application écrite dans C pour déterminer le système d'exploitation sous-jacent pendant l'exécution?

au moins, puis-je décider facilement entre Linux, Windows, BSD et MacOS?

Ma devin actuelle est de vérifier l'existence de certains fichiers / répertoires, tels que C: \ ou / , mais cette approche semble peu fiable. Peut-être interroger une série de telles sources peut aider à établir la notion d'empreintes digitales du système d'exploitation, augmentant ainsi la fiabilité. Quoi qu'il en soit, je suis impatient de vos suggestions.


19 commentaires

Euh, vous connaissez ces informations à la compilation


Comment déterminer le système d'exploitation à Runtime vous aider à écrire un SELECT () appel correctement?


+1, @david. Au moins pour les différences telles que Linux vs. Windows vs. Mac OS X, etc. Je suppose qu'un moyen d'exécution de différencier entre différentes versions de chacun de ceux-ci pourrait être ce que l'OP recherche, mais la réponse à celle-ci serait spécifique à chaque système d'exploitation, probablement.


@David: Je n'aime pas #Ifdef .


Tenter d'exécuter le programme pendant un certain temps. Si cela est tué dans un crash, vous êtes sous Windows. Si le système d'exploitation est mis à jour sur 5G ou un chat, vous êtes sur un Mac. Si vous êtes piraté après 180 jours, c'est Linux. Sinon c'est BSD.


Vous ne connaissez pas vraiment ces informations au moment de la compilation. Vous pouvez exécuter des fichiers binaires Windows sur Wine + Linux, vous pouvez exécuter des binaires Linux sur Solaris, vous pouvez exécuter des binaires Linux sur certains BSDS.


@Philip Eh bien, #Ifdef est essentiel ici, vous devez apprendre à s'entendre avec elle même si vous ne pouvez pas vous amener à l'aimer


@rsaxvc, mais pour autant que votre application concerne, vin + linux windows, en cours d'exécution binaires linux sur solaris linux, et de les exécuter sur BSD est encore linux.


@rsaxvc Puis il appartient à l'émulateur de faire du bon travail d'être le système émulé. Lorsque vous courez sur le vin, le système d'exploitation est Windows du point de vue du programme.


@ David Heffernan: Que voulez-vous dire? Aucun de ceux-ci sont des émulateurs.


@Carl - Mais vous devrez peut-être modifier le comportement d'exécution des spécificités du système d'exploitation pour y faire face. Regardez le système de fichiers Proc - différent de nombreux non-unes, vous devez donc le faire face au moment de l'exécution si vous faites une compatibilité binaire.


vin vous dit même par son nom: le vin n'est pas un émulateur


@rsaxvc - Bien sûr, mais si vous écrivez une application que vous avez l'intention d'exécuter dans ces environnements émulés, vous devez en tenir compte. Si vous écrivez une application Windows qui ne fonctionne pas dans le vin, cela signifie simplement que le vin ne fait pas assez de travail.


@Carlnorum - Je sais, c'est ce que j'ai dit, c'est pourquoi vous pourriez avoir besoin de connaître le système d'exploitation au moment de la compilation au lieu de la compilation. (Personnellement, je préférerais simplement la compiler deux fois et conclure les spécificités du système d'exploitation)


@rsaxvc Bien sûr, il est un émulateur. Il émule Windows sur les systèmes qui ne sont pas sous Windows. Les Gens du vin ne aiment pas les connotations négatives du mot et en particulier l'attente d'un émulateur fonctionne mal. Mais il est un émulateur exactement de la même manière que WOW64 est un émulateur.


@DavidHeffernan - Mauvais exemple - Dans WOW64, la CPU exécute directement les instructions X86-32, tout comme celle-ci. Ce que le vin est, est un ensemble de bibliothèques qui implémentent le Winapi sur un backend différent. Aucune émulation à (sauf si vous voulez dire WOW64 sur itanium ...)


@DavidHeffernan - Je suppose que cela est vraiment juste sémantique et pas très liée à la question à portée de main.


@rsaxvc Ah, vous définissez l'émulation pour signifier l'émulation du matériel. Une définition plus générale, celle que j'utilise, comprend l'émulation du logiciel. Description de Microsoft de WOW64 commence comme ceci : WOW64 est l'émulateur X86 qui permet aux applications Windows 32 bits de fonctionner de manière transparente sur des fenêtres de 64 bits. Oui, cela n'est pas lié à Q. N'hésitez pas à ranger.


J'essaie toujours de comprendre pourquoi vous n'aimeriez pas #Ifdef , mais soyez parfaitement content d'utiliser si . Avez-vous un aperçu de cela?


5 Réponses :


7
votes

En fait, la plupart des systèmes ont un uname commande qui montre le noyau en cours d'utilisation. Sous Mac OS, ce qui est généralement « Darwin », sur Linux, il est tout simplement « Linux », sous Windows, il est « erreur » et FreeBSD retournera « FreeBSD ».

liste complète de uname sorties

Je suis sûr qu'il ya un C équivalent uname , de sorte que vous ne aurez pas besoin system ()


4 commentaires

On dirait que je vous ai battu tous :-)


@TOM Êtes-vous sûr de ce qui se passe sur Windows? Pour tous les compilateurs C?


@DavidHeffernan haha, je suis sûr que ne sera pas renvoyer l'erreur "Erreur". Cependant, les résultats sur Windows varient beaucoup. Pour autant que je sache, seuls Cygwin renvoie un bref uname, mais certains compilateurs peuvent en réalité le compiler. A cause de cela, uname n'est pas fiable lorsqu'il est dirigé sous le vin ou le croisement.


@Tomvanderwoerdt - J'ai posté un dicton "Tu as raison, on ne peut pas être fait pour tous les OSS", mais ensuite réalisé que l'OP ne posait que BSD / OSX / Windows / Linux.



4
votes

IF vous êtes sur un système POSIX, vous pouvez appeler uname () à partir de .

Ceci est évidemment pas 100% portable, mais je ne pense pas qu'il y aura une méthode qui peut accorder que lors de l'exécution.

voir la page man pour plus de détails


0 commentaires

1
votes

Le temps d'exécution n'est pas le moment de le déterminer, étant donné que, sans binaires épopées KORDES pour une plate-forme ne fonctionnera pas sur une autre, vous devez simplement utiliser #Ifdef S autour du code sensible à la plate-forme. < / p>


2 commentaires

-1 parce que la question portait sur la façon de déterminer le système d'exploitation lors de l'exécution, pas si oui ou non vous devriez le faire.


Ouais, mais ça n'aide pas l'OP. Pour la vaste la majorité des cas, un objet émis pour FreeBSD ne fonctionnera de toute façon pas sur Linux (qui détient la majeure partie de ses cas) le faire au moment de l'exécution est le moindre de ses problèmes.



-2
votes
if (strchr(getenv("PATH"),'\\'))
    puts("You may be on windows...");
Even do I agree that "Runtime isn't the time to determine this..."

0 commentaires

1
votes

La réponse acceptée Etats Uname Code>, mais ne fournit pas d'exemple de travail minimal, c'est donc pour quiconque intéressé - espère que cela vous fera économiser le temps qu'il a pris pour moi:

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

int main(void) {
   struct utsname buffer;
   if (uname(&buffer) != 0) {
      perror("uname");
      exit(0);
   }
   printf("OS: %s\n", buffer.sysname);

   return 0;
}


1 commentaires

Erreur C1083: impossible d'ouvrir Inclure le fichier: 'SYS / UTSNAME.H': Aucun fichier ou répertoire de ce type. Sur Linux, cela fonctionne, mais pas sous Windows.