feat(lab2): unix lab2 done
Lab 2 is in fact the first lab in the set of ones we actually do. It's not particularly hard, but consumed some time for me
This commit is contained in:
17
OSs/lab2/unix/part-A/Makefile
Normal file
17
OSs/lab2/unix/part-A/Makefile
Normal file
@ -0,0 +1,17 @@
|
||||
targets = father son
|
||||
all: $(targets)
|
||||
|
||||
father: father.o
|
||||
$(CC) -o $@ $^ $(CFLAGS)
|
||||
|
||||
son: son.o
|
||||
$(CC) -o $@ $^ $(CFLAGS)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c $^ -o $@ $(CFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f $(targets)
|
||||
rm -f *.o
|
||||
rm -f task_dump*
|
||||
rm -f task*
|
||||
4
OSs/lab2/unix/part-A/README.txt
Normal file
4
OSs/lab2/unix/part-A/README.txt
Normal file
@ -0,0 +1,4 @@
|
||||
Чтобы продемонстрировать работу лабораторки достаточно запустить lab.sh как
|
||||
скрипт. Он соберет проект и запустит его для трех пунктов задания. При этом он
|
||||
сложит вывод программы в файлы task0, task1 и task2, а вывод `ps xf` в
|
||||
task_dump-0, task_dump-1 и task_dump-2 соотвественно
|
||||
16
OSs/lab2/unix/part-A/common.h
Normal file
16
OSs/lab2/unix/part-A/common.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* "THE CHEESE-WARE LICENSE" (Revision 1):
|
||||
* <ElectronixTM> wrote this file. As long as you retain this notice
|
||||
* you can do whatever you want with this stuff. If we meet some day,
|
||||
* and you think this stuff is worth it, you can buy me some cheese
|
||||
* in return
|
||||
*/
|
||||
|
||||
#ifndef COMMON_H_
|
||||
#define COMMON_H_
|
||||
|
||||
#define WAIT_FOR_CHILD 0
|
||||
#define DONT_WAIT_FOR_CHILD 1
|
||||
#define ZOMBIE_PROCESS 2
|
||||
|
||||
#endif
|
||||
56
OSs/lab2/unix/part-A/father.c
Normal file
56
OSs/lab2/unix/part-A/father.c
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* "THE CHEESE-WARE LICENSE" (Revision 1):
|
||||
* <ElectronixTM> wrote this file. As long as you retain this notice
|
||||
* you can do whatever you want with this stuff. If we meet some day,
|
||||
* and you think this stuff is worth it, you can buy me some cheese
|
||||
* in return
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define PROG_PREFIX "father: "
|
||||
#define log(fmt, args...) printf(PROG_PREFIX fmt "\n", ##args)
|
||||
|
||||
#define CMD_SIZE 256
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
if (argc != 2) {
|
||||
log("Wrong program usage. 1 argument shuld be passed - program mode");
|
||||
log("%d - wait for child", WAIT_FOR_CHILD);
|
||||
log("%d - father doesn't wait for child", DONT_WAIT_FOR_CHILD);
|
||||
log("%d - father doesn't wait for child, but child finishes",
|
||||
ZOMBIE_PROCESS);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
long mode = strtol(argv[1], NULL, 10);
|
||||
if (fork() == 0) {
|
||||
execl("son", "son", argv[1], NULL);
|
||||
}
|
||||
char cmd[CMD_SIZE] = {0};
|
||||
snprintf(cmd, CMD_SIZE, "ps fx > task_dump-%ld", mode);
|
||||
if (mode == WAIT_FOR_CHILD) {
|
||||
system(cmd);
|
||||
int status = 0;
|
||||
int ret = wait(&status);
|
||||
if (ret < 0) {
|
||||
log("waiting for son ended with error code %d", ret);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
} else if (mode == DONT_WAIT_FOR_CHILD) {
|
||||
system(cmd);
|
||||
} else if (mode == ZOMBIE_PROCESS) {
|
||||
sleep(2);
|
||||
system(cmd);
|
||||
} else {
|
||||
log("Invalid argument. No mode correspoiding to %ld", mode);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
7
OSs/lab2/unix/part-A/lab.sh
Executable file
7
OSs/lab2/unix/part-A/lab.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
make -j$(nproc)
|
||||
|
||||
./father 0 > task0
|
||||
./father 1 > task1
|
||||
./father 2 > task2
|
||||
47
OSs/lab2/unix/part-A/son.c
Normal file
47
OSs/lab2/unix/part-A/son.c
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* "THE CHEESE-WARE LICENSE" (Revision 1):
|
||||
* <ElectronixTM> wrote this file. As long as you retain this notice
|
||||
* you can do whatever you want with this stuff. If we meet some day,
|
||||
* and you think this stuff is worth it, you can buy me some cheese
|
||||
* in return
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define PROG_PREFIX "son: "
|
||||
#define log(fmt, args...) printf(PROG_PREFIX fmt "\n", ##args)
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
log("\n"
|
||||
"HEEEEEY, father\n"
|
||||
"There's an endless road to rediscover\n"
|
||||
"HEEEEEY, sister\n"
|
||||
"Do you still belive in love I wonder");
|
||||
if (argc != 2) {
|
||||
log("Ooops, wrong amount of args, %d", argc);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
long mode = strtol(argv[1], NULL, 10);
|
||||
log("mode: %ld", mode);
|
||||
switch(mode) {
|
||||
case WAIT_FOR_CHILD:
|
||||
log("pid %d ppid %d", getpid(), getppid());
|
||||
sleep(5);
|
||||
break;
|
||||
case DONT_WAIT_FOR_CHILD:
|
||||
log("before parent die: pid %d ppid %d", getpid(), getppid());
|
||||
sleep(5);
|
||||
log("after parent die: pid %d ppid %d", getpid(), getppid());
|
||||
break;
|
||||
case ZOMBIE_PROCESS:
|
||||
break;
|
||||
default:
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user