GNU/Linux >> Znalost Linux >  >> Linux

13 Základní systémová volání Linuxu vysvětlena pomocí zábavného virového programu Linux

Pokud máte zájem psát programování systému Linux, měli byste se naučit všechna základní volání knihoven/systémů. Tento článek obsahuje ukázkový program C, který pokrývá sadu systémových volání, která vám pomohou porozumět použití těchto základních volání knihoven.

Ukázkový kód C uvedený níže dělá následující:

  • Automaticky otevře některé terminály
  • Zobrazí zprávu, že relace běží jako uživatel root nebo bez uživatele root
  • Zobrazte výše uvedenou zprávu na všech otevřených terminálech

Následuje 13 důležitých volání knihoven nebo systémových volání, která jsou zahrnuta v níže uvedeném příkladu kódu.

  1. memset() :Tato funkce vyplní prvních n bajtů oblasti paměti, na kterou ukazuje s, konstantním bajtem c.
  2. fopen() :Tato funkce otevře soubor, jehož název je řetězec, na který ukazuje jeho první argument, a přiřadí k němu proud.
  3. getcwd() :Tato funkce vrací řetězec zakončený nulou obsahující absolutní cestu, která je aktuálním pracovním adresářem volajícího procesu
  4. getuid() :Tato funkce vrací skutečné uživatelské ID volajícího procesu
  5. snprintf() :Tato funkce vytváří výstup podle formátu a zapisuje výstup do vyrovnávací paměti.
  6. fwrite() :Tato funkce se používá k zápisu dat do streamu
  7. fflush() :Tato funkce vynutí zápis všech dat uložených v uživatelském prostoru do konkrétního streamu
  8. fclose() :Tato funkce vyprázdní přidružený proud a zavře základní deskriptor souboru.
  9. system() :Tato funkce provede příkaz
  10. sleep() :Tato funkce uspí proces volání, dokud neuplynou zadané sekundy nebo dokud nepřijde signál, který není ignorován.
  11. opendir() :Tato funkce otevře adresářový proud
  12. readdir() :Tato funkce čte adresář, který je otevřen jako proud
  13. atoi() :Tato funkce převede argument ascii na celé číslo.

Následuje kód C, který ukazuje, jak používat všech výše uvedených 13 systémových volání.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<dirent.h>
#include<sys/types.h>
#include<pwd.h>

// A buffer to hold current working directory
char cwd[512];

void inform(char *path, char *binary_name)
{
    // Declare variables for file operations
    FILE *fp = NULL;

    // A counter to be used in loop
    unsigned int counter = 0;

    // A buffer to hold the information message
    char msg[1024];
    // memset function initializes the bytes
    // in the buffer 'msg' with NULL characters
    memset(msg, '\0', sizeof(msg));

    memset(cwd, '\0', sizeof(cwd));

    // Check for the path to be non NULL
    if(NULL== path)
    {
         printf("\n NULL path detected\n");
         return;
    }

    // fopen will open the file represented
    // by 'path' in read write mode.
    fp = fopen(path,"r+");

    if(!fp)
    {
        printf("\n Failed to open %s\n",path);
        return;
    }
    else
    {
        printf("\n Successfully opened %s\n",path);
    }

    // getcwd() gives us the current working directory
    // of the environemt from which this binary was
    // executed
    if(NULL == getcwd(cwd,sizeof(cwd)))
    {
        printf("\n Failed to get current directory\n");
        return;
    }

    // getuid() returns the real user ID of the calling
    // process.
    // getuid() returns 0 for root and non zero for
    // any other user.
    if( 0 != getuid())
    {
        // This functions fills the buffer 'msg' with the formatted string by replacing %s in the harcoded string with the appropriate values
        snprintf(msg,sizeof(msg),"\n\n\nYOU ARE NOT ROOT!!!!!");
    }
    else
    {
       snprintf(msg, sizeof(msg),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nYOU ARE ROOT!!!!!!!!!!!!!!");
    }

   // Make sure the information8 is printed 25 times on each
   // open terminal
   for(counter=0;counter<25;counter++)
   {
       printf("\n fwrite()\n");
       // Write the information message on to the terminal
       fwrite(msg, strlen(msg), 1, fp);
       // Flush the message to the stdout of the terminal
       fflush(fp);
       // Wait for one second.
       sleep(1);
   }
   // close the file representing the terminal
   fclose(fp);

}

int main(int argc, char *argv[])
{
    // Since we will do some directory operations
    // So declare some variables for it.
    DIR *dp = NULL;
    struct dirent *ptr = NULL;

    // This variable will contain the path to
    // terminal
    char *path = NULL;

    // Used as a counter in loops
    int i =0;

    // Step1 :
    // Open 5 terminals each after 2 seconds
    // of delay.
    for(;i<5;i++)
    {
        // The system API executes a shell command
        // We try to execute two commands here
        // Both of these commands will open up
        // a terminal. We have used two commands
        // just in case one of them fails.
        system("gnome-terminal");
        system("/usr/bin/xterm");

        // This call is used to cause a delay in
        // program execution. The argument to this
        // function is the number of seconds for
        // which the delay is required
        sleep(2);
    }

    // Give user some 60 seconds before issuing
    // a information message.
    sleep(60);

    // Now, open the directory /dev/pts which
    // corresponds to the open command terminals.
    dp = opendir("/dev/pts");
    if(NULL == dp)
    {
        printf("\n Failed to open /dev/pts\n");
        return 0;
    }

    // Now iterate over each element in the
    // directory untill all the elements are
    // iterated upon.
    while ( NULL != (ptr = readdir(dp)) )
    {
        // ptr->d_name gives the current device
        // name or the terminal name as a device.
        // All the numeric names correspond to
        // open terminals.

        // To check the numeric values we use
        // atoi().
        // Function atoi() converts the ascii
        // value into integer

        switch(atoi(ptr->d_name))
        {
            // Initialize 'path' accordingly

            case 0:path = "/dev/pts/0";
                   break;
            case 1:
                   path = "/dev/pts/1";
                   break;
            case 2:
                   path = "/dev/pts/2";
                   break;
            case 3:
                   path = "/dev/pts/3";
                   break;
            case 4:
                   path = "/dev/pts/4";
                   break;
            case 5:
                   path = "/dev/pts/5";
                   break;
            case 6:
                   path = "/dev/pts/6";
                   break;
            case 7:
                   path = "/dev/pts/8";
                   break;
            case 9:
                   path = "/dev/pts/9";
                   break;
            default:
                   break;
         }
         if(path)
         {
             // Call this function to throw some information.
             // Pass the path to terminal where the information
             // is to be sent and the binary name of this
             // program
             inform(path, argv[0]);
             // Before next iteration, make path point to
             // NULL
             path = NULL;
         }

    }

    sleep(60);

    return 0;
}

Samotný výše uvedený kód je samovysvětlující, protože obsahuje adekvátní komentáře, které vysvětlují, co tato systémová volání dělají. Pokud jste nováčkem v programování systému Linux, tento kód dostatečně vysvětlí použití všech těchto důležitých funkcí. Pro více podrobností a pokročilé použití si prosím pozorně přečtěte jejich manuálové stránky.

Tento kód je simulací zábavného základního virového programu. Jakmile zkompilujete a spustíte výše uvedený program c, provede následující. Tento kód byl testován na Linux mint. Ale mělo by to fungovat na všech derivátech ubuntu.

  • Uživatel uvidí 5 terminálů, které se otevírají jeden po druhém po 1 sekundě.
  • Zatímco se uživatel bude divit, co se právě stalo, všechny jeho otevřené terminály začnou pomalu dostávat opakované informace o přihlášení, zda je přihlášení root nebo non-root.
  • Upozorňujeme, že pro účely učení je v kódu povoleno protokolování ladění. Pokud se chcete pobavit, zakomentujte ladicí printf a poté jej spusťte.

Linux
  1. Pochopení systémových volání na Linuxu pomocí strace

  2. Definování systémových úloh pomocí Cron pod Linuxem

  3. Proč je moje funkce cat se systémovými voláními pomalejší ve srovnání s kočkou v Linuxu?

  1. Jak zálohovat celý systém Linux pomocí Rsync

  2. Základní příkazy pro řešení problémů s výkonem v Linuxu

  3. Linuxový systém řazení front

  1. Linux – celosystémové monitorování volání do funkce knihovny?

  2. Nastavte systémové datum a čas pomocí C++ v Linuxu

  3. Velmi základní Linux pro vzdělávací účely