Cvičenie 2 - Vytvorenie procesu

Pri riešení tohto cvičenia Vám, možno pomôžu:
Pripomenutie vytvorenia nového projektu v prostredí Microsoft Visual Studio: Ukážka 1 - vyvolanie Notepadu z programu v Pythone:

import subprocess

def edituj(text):
    with open('pom.txt',mode='w') as f:
        f.write(text)
    res=subprocess.run(['notepad','pom.txt'])
    if res.returncode == 0:
        for li in open('pom.txt'):
            print(li,end='')
    else:
        print('CHYBA',res)

Ukážka 2 - vyvolanie Notepadu z programu vo Windows v C:

#include <iostream>
#include "windows.h"

int main()
{
    STARTUPINFOA si;
    PROCESS_INFORMATION pi;
    HANDLE proc;
    DWORD exitCode;
    FILE* f;
    char buff[1025];

    // Zapisme nieco do suboru text.txt
    fopen_s(&f,"e:\\text.txt", "w");

    fprintf(f, "test");
    fclose(f);

    ZeroMemory(&pi, sizeof pi); // inicializacia premennej pi

    ZeroMemory(&si, sizeof si); // inicializacia premennej si
    si.cb = sizeof si;       
   
   
// vytvorime novy proces s beznymi nastaveniami
   
if (CreateProcessA(NULL, (char *) "notepad e:\\text.txt", NULL, NULL, false, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)) 
                

    {
        proc = pi.hProcess;                     // v pi.hProcess sme dostali identifikacne cislo (handle) noveho procesu
        if (WaitForSingleObject(proc, INFINITE) != WAIT_FAILED)    // cakame na skoncenie procesu
        {
            GetExitCodeProcess(proc, &exitCode);        // ak cakanie neskoncilo chybou, tak prevezmeme ukoncovaci kod
            printf("ExitCode = %d\n", exitCode);        // a vypiseme ho
        }
        CloseHandle(proc);                      // oznamime op. systemu, ze uz nepotrebujeme cislo procesu
        CloseHandle(pi.hThread);                // oznamime op. systemu, ze uz nepotrebujeme cislo jeho hlavneho threadu
    }

    // zobrazme zeditovany subor text.txt
    fopen_s(&f, "e:\\text.txt", "r");

    while (fgets(buff, sizeof buff, f) != NULL)
        printf(buff);
    fclose(f);

    return 0;
}

Vyskúšajte si spustiť túto ukážku.

Ukážka 3 - vytvorenie nového procesu v Linuxe v C:

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

int main( void ) {
    FILE *f;
    int stat;
    char buff[1025];

    f=fopen("text.txt", "w");
    fprintf(f, "test\n");
    fclose(f);

    int pid = fork();     // vytvorime synovsky proces s identickym programom

    if ( pid == 0 ) {
        // sme v synovskom procese: zmen program za iny
        execlp("gedit","gedit","text.txt", (char *) NULL); // prvy parameter je meno suboru,
                                                           //   ak nema uvedenu cestu, tak sa hlada v path,
                                                           // druhy parameter je rovnaky ako prvy (stane sa z neho argv[0])
                                                           // dalsie parametre su parametre prikazovaho riadku
                                                           // posledny musi byt NULL
        exit(127);        // skonci s kodom 127, sem prideme len ked sa execlp nepodari
    } else if (pid < 0)
        // nastala chyba: synovsky proces sa nepodarilo vytvorit, pid je cislo chyby
        printf("Chyba %d\n",pid);
    else {
        // sme v otcovskom procese: pid je identifikator synovskeho procesu
        waitpid(pid,&stat,0);
        printf("Exit status: %d\n\n",WEXITSTATUS(stat));

        f=fopen("text.txt", "r");
        while (fgets(buff, sizeof buff, f) != NULL)
            fputs(buff,stdout);
        fclose(f);
    }

    return 0;
}

Kompilovanie a spustenie v príkazovom riadku Linuxu (predpokladáme, že program ste uložili do súboru s názvom proc.c ak to tak nie je, tak prispôsobte príkazy vami zvolenému menu alebo súbor premenujte):

gcc proc.c -o proc
./proc

Odbočenie - práca s reťazcami v C (bude to treba pre úlohu 2 a 3)

Ukážka čítania reťazcov, prevodu reťazca na celé číslo a zreťazenia reťazcov.

Pre Visual studio:

#include <iostream>

int main()
{
    char x[11];
    scanf_s("%10s",x,11);  // cislo 10 v "%10s" hovori kolko znakov precitat,
                           // cislo 11 (treti parameter) hovori, ake velke je pole (musi mat miesto aj na koncovu nulu)
    printf("%s\n", x);
    printf("%d\n", atoi(x));

    char y[20];
    strcpy_s(y, "cislo je: ");
    strcat_s(y, x);
    printf("%s\n", y);
}

Pre gcc (teda standardne C napr. v Linuxe alebo CLione):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char x[11];
    scanf("%10s",x);  // scanf nepouziva treti parameter, ale je preto NEBEZPECNY lebo nepozna dlzku premennej x
    printf("%s\n", x);
    printf("%d\n", atoi(x));

    char y[20];
    strcpy(y, "cislo je: ");
    strcat(y, x);
    printf("%s\n", y);
}

Úloha 1:

Spustite si Linux (alebo MacOs, ak mate na cvičení svoj Mac),
Zoberte Ukážku 1 a skúste ju rozchodiť v Linuxe.
Budete musieť riešit, že v Linuxe nie je Notepad.
MacOS: V macOS je vyvolanie GUI programu z iného programu trocha zložitejšie, pozrite sem, aj to nerozbeháte tak sa spýtajte cvičiaceho.

Úloha 2:

(V Linuxe, macOS alebo vo Windows, podľa Vášho výberu)

Keď programujeme v C, tak exitcode procesu je výsledok funkcie main().

Pomocou tejto novej vedomosti naprogramujte dva programy:
Pomôcky a rady pre Visual Studio (a iné integrované prostredia) :
Úloha 3:

Keď zadefinujete funkciu main ako int main(int argc, char *argv[]) tak v argc dostanete počet parametrov príkazového riadku, ktorým bol program vyvolaný a v argv sú uložené parametre ako pole reťazcov (argv[0] je meno programu, až argv[1] je prvý parameter).

Pomocou tejto novej vedomosti naprogramujte programy: