Квазиполезное
git-репозиторий, в котором будет вестись работа над домашними заданиями. Зарегистрировать репозиторий можно по ссылке http://goo.gl/forms/RZl2klLfAp.make clean && make. Если на этом этапе происходит ошибка, тесты не запускаются.Обзавестись какой-нибудь Unix-like системой.
Написать на языке C программу, печатающую "Hello, world!" (с переводом строки в конце).
/hello_world/hello_world.c/hello_world/Makefile/hello_world/hello_worldman 3 printfmake ничего не делаетmake clean удаляет всё, что создал makeНеобходимо реализовать примитивный вариант утилиты cat, копирующий символы из stdin на stdout. Для реализации ввода-вывода нужно пользоваться системными вызовами read и write. Функциями из stdio.h (printf, getchar, putchar, ...) можно пользоваться только для вывода отладочной информации и/или сообщений об ошибках.
/cat/cat.c/cat/Makefile/cat/catman 2 readman 2 write./cat < cat.c > cat2.c && diff cat.c cat2.c && echo OKcurl neerc.ifmo.ru/~os/blob.bin | ./cat > blob.bin && curl neerc.ifmo.ru/~os/blob.bin > blob2.bin && diff blob.bin blob2.bin && echo OK (осторожно, 2×5Mb)Необходимо реализовать скрипт для командной оболочки bash, обходящий указанную директорию и выводящий список файлов, изменённых более недели назад и являющихся символьными ссылками, которые ссылаются на несуществующий файл. Директория, которую нужно обойти, указана первым аргументом командной строки.
Найденные файлы можно выводить в любом порядке. Пути до файлов можно выводить в любом корректном формате. Например, все следующие варианты допустимы и являются путями до одного и того же файла: a/b/c/d, ./a//b/c/d, a/../a/b/c/d.
/badlinks/badlinks.shman 1 testman 1 bashСкрипт создаст директорию hw2-example. Запуск ./badlinks.sh hw2-example должен вывести:
$ ./badlinks.sh hw2-example
hw2-example/bad-old-link
hw2-example/nested/bad-old-link2
hw2-example/link-to-nested/bad-old-link2
Реализовать программу, в течение 10 секунд ожидающую SIGUSR1 или SIGUSR2 и печатающую информацию о полученном сигнале в формате "<имя сигнала> from <pid>". Здесь <имя сигнала> — SIGUSR1 или SIGUSR2, а <pid> — номер процесса, от которого пришёл сигнал. Если никакой сигнал не пришёл, вывести No signals were caught. Если пришло несколько сигналов, вывести информацию только про какой-либо один из них.
/sigusr/sigusr.c/sigusr/Makefile/sigusr/sigusrman 7 signalman 2 sigactionman 1 killman 2 killman 3 sleep или man 2 alarmsignal(2) — не тот системный вызов, который вы ищетеprintf-а?$ ./sigusr > tmp & sleep 2; kill -SIGUSR1 $!; wait; cat tmp
SIGUSR1 from <pid>
$ ./sigusr
No signals were caught
Вам требуется написать упрощённую версию командного интерпретатора. Он будет считывать со стандартного ввода команду, выполнять её, дожидаться её завершения, и повторять сначала.
Команда --- это строка, заканчивающаяся символом перевода строки. Эту строку нужно разбить по символу "|" на подкоманды. Каждую подкоманду нужно разбить по пробелу на имя и аргументы, и запустить. Стандартный вывод первой подкоманды нужно перенаправить на стандартный ввод второй, стандартный вывод второй --- на стандартный ввод третьей, ... Стандартный ввод для первой подкоманды совпадает со стандартным вводом командного интерпретатора, стандартный вывод последней --- со стандартным выводом интерпретатора.
Если ввод кончился, интерпретатор должен завершиться. Если интерпретатору прилетел SIGINT (ctrl+C), то он должен быть перепослан запущенной команде.
Для наглядности, печатайте приглашение $ тогда, когда можно вводить команду.
/simplesh/simplesh.c/simplesh/Makefile/simplesh/simpleshhost$ ./simplesh
> $
< ls
> <содержимое директории>
> $
< cat /proc/cpuinfo | grep model | grep name | sed -re s/.*:\s(.*)/\1/ | uniq
> <модель процессора>
> $
< ^D
< и > символизируют ввод и вывод и показаны исключительно для наглядности.
host$ ./simplesh
> $
< cat | wc -l
< first line
< second line
< third line
< ^D
> 3
> $
< cat|wc -l
< first
< second
< third
< ^D
> 3
> $
< ^D
Запуск cat | sleep 1 | cat должен вести себя так же, как при запуске в обычном шелле: точно так же реагировать на ввод, столько же работать и не плодить зомби-процессы. То же относится к sleep 15 | sleep 1 | sleep 15.
Проверка того, что команда считывается правильно: (echo -ne l; sleep 1; echo s) | ./simplesh (запускать в настоящем шелле, а не в реализуемом) должно показывать содержимое текущей директории.
Уметь объяснять, что происходит при запуске echo -ne "cat\nhello" | ./simplesh и мотивировать, почему именно это - правильное поведение.
yes date | ./simplesh должно выводить бесконечно много раз текущее время.
(echo md5sum; sleep 1; dd if=/dev/zero bs=1024 count=100000) | ./simplesh должно печатать, среди прочего, 75a1e608e6f1c50758f4fee5a7d8e3d0.
read и write.n целиком, она должна быть прочитана с помощью одного вызова read вместо n вызовов./simplesh своего репозитория.readread, читающий команду, может считать начало входных данных командыВам нужно написать существенно упрощённую версию демона sshd. Программа слушает подключения по TCP на заданном порту. Для каждого подключившегося клиента она открывает новый псевдотерминал, в котором будет запущен /bin/sh, и транслирует происходящее в нём клиенту. Программа должна демонизироваться и записывать свой pid в текстовом виде в файл /tmp/rshd.pid. Обслуживание множества клиентов реализовать с помощью select, poll или epoll.
Дополнителные процессы и/или потоки можно создавать только в целях демонизации и для запуска /bin/sh. Для передачи данных между клиентом и его шеллом завести два буфера фиксированного размера: от клиента к шеллу и в обратную сторону.
Несложно заметить, что в задании используется много новых вещей, которые не использовались в предыдущих заданиях: сеть, мультиплексирование ввода-вывода, псевдотерминалы и демонизация. Далее небольшой план, следуя которому можно реализовать требуемое, используя одновременно не более одной новой вещи. Более того, некоторые маленькие примеры работы с poll и с псевдотерминалами можно найти в шапке этого документа.
pipe-ы. Задание превращается в следующее:
/bin/sh;O_NONBLOCK);O_NONBLOCK на select, poll или epoll;/rshd/rshd.c/rshd/Makefilershd/rshdman 2 socket, man 2 bind, man 2 listen, man 2 acceptman 3 getaddrinfo: там можно найти пример работы с сетьюman 2 select, man 2 poll, man 2 epoll_{create,ctl,wait}man 3 posix_openpt, man 3 grantpt, man 3 unlockpt, man 3 ptsname./rshd 1234.nc localhost 1234. Должно появиться приглашение $.^D порожденный процесс sh-потомок rshd завершается и утилизируется (не висит как зомби).exit внутри sh-сессии (или при любом другом завершении шелла) не остается зомби.Запустить в удалённом шелле hexdump /dev/urandom, увидеть, что он работает. Запустить его же во втором терминале, увидеть, что оба работают одновременно.
Запустить echo "hexdump /dev/urandom" | nc localhost 1234 | (sleep 1000000; cat), убедиться, что компьютер не завис наглухо.