Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/vtsh.yml → .github/workflows/vt25hell.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
name: Test VT Shell
name: Test VT25hell

on:
push:
branches:
- main
pull_request:
paths:
- 'lab/vtsh/**'
- 'lab/vt25hell/**'

jobs:
build:
Expand All @@ -20,7 +20,7 @@ jobs:
image: silkeh/clang:latest
defaults:
run:
working-directory: ./lab/vtsh
working-directory: ./lab/vt25hell
steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -45,5 +45,5 @@ jobs:
clang-tidy -p ./build {} \;

- name: Test
working-directory: ./lab/vtsh/test
working-directory: ./lab/vt25hell/test
run: python3 -m unittest discover
16 changes: 16 additions & 0 deletions lab/vt25hell/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
BasedOnStyle: Google

AccessModifierOffset: -2

AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false

DerivePointerAlignment: false
BreakConstructorInitializers: BeforeComma
AlignAfterOpenBracket: BlockIndent

BinPackArguments: false
BinPackParameters: false

AlignArrayOfStructures: Right
17 changes: 17 additions & 0 deletions lab/vt25hell/.clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Checks: |
-*,
bugprone-*,
cert-*,
clang-analyzer-*,
concurrency-*,
cppcoreguidelines-*,
google-*,
hicpp-*,
misc-*,
modernize-*,
performance-*,
portability-*,
-portability-avoid-pragma-once,
readability-*
WarningsAsErrors: '*'
FormatStyle: file
8 changes: 8 additions & 0 deletions lab/vt25hell/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# CMake
build/

# Clangd
.cache/

# Python
__pycache__/
25 changes: 25 additions & 0 deletions lab/vt25hell/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"recommendations": [
"ms-vscode.cmake-tools", // CMake support (docs, runners)

/**
* C/C++ extensions group alternative 1:
*/
"llvm-vs-code-extensions.vscode-clangd", // LSP
"vadimcn.vscode-lldb", // debugger extension for clang
/* or official lldb extension */
// "llvm-vs-code-extensions.lldb-dap",

/**
* C/C++ extensions group alternative 2:
*/
// "ms-vscode.cpptools", // C/C++ extension pack with debugger & LSP

/**
* Optional extensions:
*/
// "usernamehw.errorlens", // For inlineerror displaying
// "ms-vscode-remote.remote-wsl", // For WSL support
// "ms-vscode-remote.remote-containers", // For devcontainer support
]
}
7 changes: 7 additions & 0 deletions lab/vt25hell/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"clangd.arguments": [
"-compile-commands-dir=./build",
"-header-insertion=never",
],
"files.eol": "\n",
}
13 changes: 13 additions & 0 deletions lab/vt25hell/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.12)

project(
vtsh
VERSION 0.1
DESCRIPTION "Good Old VT Shell"
LANGUAGES C
)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

add_subdirectory(bin)
add_subdirectory(lib)
82 changes: 82 additions & 0 deletions lab/vt25hell/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Shell

## Введение

Базовый пользовательский интерфейс операционной системы - это терминал, с его
помощью можно взаимодействовать с ОС, давать ей команды и запускать программы и
наблюдать результат их выполнения. А имея возможность запускать программы можно
расширить возможности данной ОС. В данной лабораторной работе вам предлагается
реализовать простую командную оболочку наподобие Bash.

## Часть 1. Запуск программ

Необходимо реализовать собственную оболочку командной строки - shell. Shell
должен предоставлять пользователю возможность запускать программы на компьютере
с переданными аргументами командной строки и отображать время их выполнения
(расчитать как разность времени завершения и времени запуска).

## Часть 2. Логические операторы

В разработанное приложение командной оболочки необходимо добавить поддержку
логических операторов (аналогичных операторам из Bash) согласно выданному варианту:

1. `&&` - логическое И (AND),
2. `||` - логическое ИЛИ (OR),
3. `;` - последовательное выполнение,
4. `&` - выполнение в фоне.

## Требования к реализации

1. Программа (комплекс программ) должна быть реализован на языке C.

2. Дочерние процессы должны быть созданы через указанные в варианте системные
вызовы операционной системы, с обеспечением корректного запуска и завершения
процессов. Запрещено использовать высокоуровневые абстракции над системными
вызовами. Необходимо использовать, процедуры libc.

## Требования к отчету и защите

Отчет должен содержать:

1. Титульный лист с указанием номера и названия ЛР, вашего ФИО, ФИО
преподавателя практики, номера вашей группы, варианта ЛР.

2. Текст задания в соответствии с вариантом.

3. Листинг исходного кода всех программ, написанных в рамках данной ЛР.

7. Заключение.

Студент должен быть готов:

1. Продемонстрировать работоспособность Shell и предоставить исходный код.

2. Ответить на вопросы по реализации программ и контрольные вопросы.

## Описание вариантов

Запуск подпрограмм (группа **proc**):

- `proc-fork`: Запуск подпроцесса с помощью системного вызова fork

- `proc-vfork`: Запуск подпроцесса с помощью системного вызова vfork

- `proc-clone`: Запуск подпроцесса с помощью системного вызова clone

- `proc-clone3`: Запуск подпроцесса с помощью системного вызова clone3

Дополнительный оператор потока управления Shell (группа **shell**):

- `shell-and`: Выполнение команд с логическим оператором AND (`&&` в bash).

- `shell-or`: Выполнение команд с логическим оператором OR (`||` в bash).

- `shell-seq`: Выполнение команд последовательно (`;` в bash).

- `shell-bg`: Выполнение команды в фоновом процессе (`&` в bash).

## Источники

- Тесты взяты из репозитория [sergey-v-galtsev/shad-os][shad-os-tests]

[shad-os-tests]: https://gitlab.com/sergey-v-galtsev/shad-os/-/blob/master/bsh/test.py
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
26 changes: 26 additions & 0 deletions lab/vt25hell/test/base_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import os
from typing import Optional
from unittest import TestCase

from shell import Shell


class BaseShellTest(TestCase):
def setUp(self):
self.shell = Shell("../build/bin/vtsh")
self.test_files = set()

def tearDown(self):
for file in self.test_files:
if os.path.exists(file):
os.remove(file)

def add_test_file(self, filename: str):
self.test_files.add(filename)

def execute(self, cmd: str, expected: Optional[str] = None):
status, stdout = self.shell.execute(cmd)

self.assertEqual(status, 0)
if expected is not None:
self.assertEqual(stdout, expected)
18 changes: 18 additions & 0 deletions lab/vt25hell/test/shell.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import subprocess


class Shell:
def __init__(self, path: str):
self._path = path

def execute(self, cmd: str):
shell = subprocess.Popen(
self._path,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
encoding="utf8",
)

stdout, _ = shell.communicate(cmd + "\n", timeout=2)
return shell.returncode, stdout.replace("vtsh> ", "").strip()
40 changes: 40 additions & 0 deletions lab/vt25hell/test/test_basics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import os

from base_test import BaseShellTest


class TestShellBasics(BaseShellTest):
def test_empty_command(self):
self.execute("", "")

def test_simple_echo(self):
self.execute("echo hello", "hello")
self.execute(" echo hello world", "hello world")

def test_multiple_commands(self):
self.execute("echo hello\necho world", "hello\nworld")

def test_file_operations(self):
self.add_test_file("./foo")

self.execute("touch ./foo", "")
self.assertTrue(os.path.exists("./foo"))
self.execute("rm ./foo", "")
self.assertFalse(os.path.exists("./foo"))

def test_multiple_file_operations(self):
self.add_test_file("./bar")

self.execute("touch ./bar\ncat ./bar\nwc -c bar\nrm ./bar", "0 bar")
self.assertFalse(os.path.exists("./bar"))

def test_stdin_interaction(self):
self.execute("cat\nhello\nworld", "hello\nworld")

def test_nested_shells(self):
self.execute("./shell\necho hi\n./shell\necho hello", "hi\nhello")

def test_invalid_paths(self):
self.execute("cat /sys/proc/foo/bar", "")
self.execute("foobar", "Command not found")

65 changes: 65 additions & 0 deletions lab/vt25hell/test/test_redirection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import unittest

from base_test import BaseShellTest

REQUIRED_REDIRECTION_FUNCTIONALITY = False

@unittest.skipIf(not REQUIRED_REDIRECTION_FUNCTIONALITY,
("Redirection functionality is not required in the task. "
"This functionality is for an additional task."))
class TestShellRedirection(BaseShellTest):
def test_simple_redirection(self):
self.add_test_file("aaa")

self.execute("echo vt flood > aaa", "")
self.execute("cat <aaa", "vt flood")
self.execute("cat >/dev/null < aaa", "")

def test_redirection_overwrite(self):
self.add_test_file("aaa")

self.execute("echo c forever >aaa", "")
self.execute("cat < aaa", "c forever")

def test_redirection_with_spaces(self):
self.add_test_file("aaa")

self.execute("echo >aaa andrew tanenbaum", "")
self.execute("<aaa cat", "andrew tanenbaum")

def test_multiline_redirection(self):
self.add_test_file("aaa")

self.execute("> aaa cat\nhello\nworld", "")
self.execute("< aaa cat", "hello\nworld")

def test_complex_redirection(self):
self.add_test_file("aaa")
self.add_test_file("bbb")

self.execute(">aaa head -c 250 < /dev/zero", "")
self.execute("wc > bbb -c aaa", "")
self.execute("< bbb cat", "250 aaa")

def test_invalid_redirection_syntax(self):
self.execute("echo test foo bar>bbb", "test foo bar>bbb")
self.execute("echo test<aaa>bbb", "test<aaa>bbb")

def test_combined_redirection(self):
self.add_test_file("lol")
self.add_test_file("wut")

self.execute("echo >lol<wut alpha", "")
self.execute("cat lol<wut", "alpha")

def test_syntax_errors(self):
self.execute("echo >foo > bar", "Syntax error")
self.execute("cat <one > two <bar", "Syntax error")
self.execute("wc -l <", "Syntax error")
self.execute("cat < >hello", "Syntax error")
self.execute("cat >>hello", "Syntax error")

def test_io_errors(self):
self.execute("</dev/zero cat > /sys/proc/foo/bar", "I/O error")
self.execute("cat < /foo/bar/baz", "I/O error")
self.execute("cat < baz > foo", "I/O error")
3 changes: 1 addition & 2 deletions lab/vtsh/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@ project(

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

add_subdirectory(bin)
add_subdirectory(lib)
add_subdirectory(src)
Loading
Loading