Загрузка данных


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

int main() {
    int counter = 10;
    pid_t pid = fork();
    
    if (pid == 0) {
        counter = counter + 5;
        printf("Child: counter = %d, PID = %d, PPID = %d\n", 
               counter, getpid(), getppid());
        exit(0);
    } 
    else if (pid > 0) {
        counter = counter - 5;
        printf("Parent: counter = %d, PID = %d, Child PID = %d\n", 
               counter, getpid(), pid);
    } 
    else {
        perror("fork");
        exit(1);
    }
    
    return 0;
}

gcc fork_lab.c -o fork_lab
./fork_lab

дз2
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

int main() {
    int data = 42;
    pid_t pid = vfork();
    
    if (pid == 0) {
        // Дочерний процесс
        data = 99;
        printf("Child before exit: data = %d, PID = %d\n", data, getpid());
        _exit(0);   // Обратите внимание: _exit, а не exit
    } 
    else if (pid > 0) {
        // Родительский процесс
        printf("Parent after child finished: data = %d, PID = %d\n", data, getpid());
    } 
    else {
        perror("vfork");
        exit(1);
    }
    
    return 0;
}

gcc vfork_lab.c -o vfork_lab
./vfork_lab

if (pid == 0) {
    data = 99;
    printf("Child before exit: data = %d, PID = %d\n", data, getpid());
    return 0;   // ← ВМЕСТО _exit(0)
}

дз 3
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main() {
    printf("Loader PID: %d. Before exec...\n", getpid());
    
    execlp("/bin/ls", "ls", "-l", NULL);  // запускаем ls -l
    
    // Всё, что ниже, выполнится только при ошибке exec
    perror("execlp");
    printf("This line appears only on error.\n");
    
    return 1;
}

gcc exec_loader.c -o exec_loader
./exec_loader


#include <stdio.h>
#include <unistd.h>

int main() {
    printf("Target PID: %d. Hello from a separate program!\n", getpid());
    return 0;
}

gcc exec_target.c -o exec_target

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

int main() {
    printf("Loader PID: %d. Before exec...\n", getpid());
    
    // Запускаем нашу программу exec_target вместо ls
    execl("./exec_target", "exec_target", NULL);
    
    // Всё, что ниже, выполнится только при ошибке exec
    perror("execl");
    printf("This line appears only on error.\n");
    
    return 1;
}

gcc exec_loader.c -o exec_loader
./exec_loader

#define _GNU_SOURCE
#include <sched.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

static int child_func(void *arg) {
    char *buf = (char *)arg;
    
    printf("Child sees buf = \"%s\"\n", buf);
    strcpy(buf, "CHILD_DATA");
    
    return 0;
}

int main(int argc, char **argv) {
    const int STACK_SIZE = 65536;
    char *stack = malloc(STACK_SIZE);
    
    if (!stack) { 
        perror("malloc"); 
        exit(1); 
    }
    
    unsigned long flags = SIGCHLD;  // базовый флаг, чтобы родитель мог ждать
    
    // Если программа запущена с аргументом "vm", добавляем CLONE_VM
    if (argc > 1 && !strcmp(argv[1], "vm")) {
        flags |= CLONE_VM;
        printf("=== CLONE_VM flag is ENABLED ===\n");
    } else {
        printf("=== CLONE_VM flag is DISABLED ===\n");
    }
    
    char buffer[100];
    strcpy(buffer, "PARENT_DATA");
    
    printf("Parent before clone: buffer = \"%s\"\n", buffer);
    
    if (clone(child_func, stack + STACK_SIZE, flags, buffer) == -1) {
        perror("clone");
        exit(1);
    }
    
    int status;
    if (wait(&status) == -1) {
        perror("wait");
        exit(1);
    }
    
    printf("Parent after child exit: buffer = \"%s\"\n", buffer);
    
    free(stack);
    return 0;
}

gcc clone_lab.c -o clone_lab