- •Введення
- •1. Структура та обсяг дисципліни
- •2. Основи програмування на мові с
- •2.1 Найпростіші конструкції мови
- •2.2 Типи даних
- •2.4 Операції мови с
- •2.5 Структура простої с програми
- •2.6 Організація введення-виведення
- •2.7 Компіляція в системі Linux
- •2.8 Організація розгалужень в програмі
- •2.9 Організація циклів
- •2.10 Оператор break
- •2.11 Оператор continue
- •2.11 Масиви
- •2.12 Функції
- •2.13 Вызов функции с переменным числом параметров
- •2.14 Рекурсивні функції
- •2.15 Читання і запис текстових файлів
- •2.16 Структури даних
- •2.17 Перелік|перерахування| (enumeration)
- •2.18 Об'єднання (union)
- •3. Операційні системи і системне програмування
- •3.1. Поняття операційної системи
- •4. Корисні команди Linux
- •4.1. Загальні|спільні| команди
- •4.1.1. Команда arch – виведення архітектури комп'ютера
- •4.1.2. Команда clear – очищення екрану
- •4.1.3. Команда date
- •4.1.9. Команда uptime – інформація про роботу системи
- •4.1.10. Команда users – інформація про користувачів
- •4.1.11. Команди w, who і whoami інформація про користувачів
- •4.1.12. Команда xf8config – настройка графічної підсистеми
- •4.2. Команди для роботи з текстом
- •4.2.1. Команди diff і cmp
- •4.2.2. Команди grep і egrep – текстовий фільтр
- •4.2.3. Команди more и less – посторінкове виведення
- •4.2.4. Команди head і tail – виведення начала і хвоста файлу
- •4.2.5. Команда wc – підрахунок слів у файлі
- •5. Захист інформації в інформаційних системах
- •5.1 Основні завдання забезпечення безпеки
- •5.2 Базові поняття криптографії
- •5.2.1 Поняття криптографічного алгоритму і протоколу
- •5.2.2 Криптосистеми з секретним ключем
- •5.2.3 Криптосистеми із відкритим ключем
- •5.2.4. Гибридні криптосистеми
- •5.2.5. Цифрові підписи
- •5.2.6. Сертифікати
- •5.3. Принципи аутентифіекації і керування доступом
- •5.3.1. Основи аутентифікації
- •5.3.2. Основи керування доступом
- •5.4. Аутентифікація та керування доступом в unix
- •5.4.1. Облікові записи користувачів
- •5.4.2. Аутентифікація
- •5.4.3. Керування доступом
- •6. Програмний інтерфейс unix. Системні виклики і функції стандартних бібліотек
- •6.1. Підтримка програмування в oc unix. Вивчення передачі інформації
- •6.2. Змінні оточення
- •6.3. Обробка помилок
- •6.4. Правила формування і засоби розбору командних рядків
- •7. Операції над файлами
- •7.1 Файлові операції posix
- •7.2. Збирання інформації про атрибути файла
- •7.3. Операції над каталогами
- •Література
6. Програмний інтерфейс unix. Системні виклики і функції стандартних бібліотек
Взаємодія прикладних завдань з ядром відбувається за допомогою стандартного інтерфейсу системних викликів. Інтерфейс системних викликів є набором послуг ядра і визначає формат запитів на послуги. Процес запрошує послугу посредствої системного виклику певної процедури ядра.
Всі версії UNIX надають строго певний обмежений набір входів в ядро операційної системи, через які прикладні завдання мають можливість скористатися базовими послугами, що надаються UNIX. Ці точки входів одержали назву системних викликів. (system calls).
Системний виклик, таким чином, визначає функцію, що виконується ядром операційної системи від імені процесу, що виконав виклик, і є інтерфейсом найнижчого рівня взаємодії прикладних процесів з ядром.
У середовищі програмування UNIX системні виклики визначаються як функції С, незалежно від фактичної реалізації виклику функції ядра операційної системи. У UNIX використовується підхід, при якому кожен системний виклик має відповідну функцію з тим же ім'ям, що зберігається в стандартній бібліотеці мови С. Функциі бібліотеки виконують необхідне перетворення аргументів і викликають необхідну процедуру ядра, використовуючи різні прийоми. В цьому випадку бібліотечний код виконує тільки роль оболонки, тоді як фактичні інструкції розташовані в ядрі операційної системи.
Крім системних викликів програмісту пропонується великий набір функцій загального призначення. Ці функції не є точками входу в ядро операційної системи, хоча в процесі виконання багато хто з них виконує системні виклики. Ці функції зберігаються в бібліотеці загального призначення мови С і разом з системними викликами складають основу середовища програмування в UNIX.
6.1. Підтримка програмування в oc unix. Вивчення передачі інформації
Як відомо, ядро операційної системи – це програма, яка виконує основні функції операційної системи. Воно взаємодіє з апаратними пристроями, виділяє пам'ять і інші ресурси, дозволяє декільком програмам працювати одночасно, управляє файловими системами і т.д.
Ядро саме по собі не має в своєму розпорядженні засобів взаємодії з користувачами. Воно не може навіть видати простий рядок з запрошенням на введення команд. Ядро не дозволяє користувачам редагувати файли, взаємодіяти з іншим комп'ютером або писати програми. Для вирішення всіх цих задач задач потрібне велике число інших програм, включаючи интерпретатори команд, редактори і компілятори. Багато хто з цих програм користується бібліотеками функцій загального призначення, не включеними в ядро.
У системах GNU/UNIX більшість таких програм розроблена в рамках проекту GNU (GNU – це рекурсивний акроним, який розшифровується як GNU’s Not UNIX (GNU – не це UNIX)). Багато хто з них був написаний раніше, ніж з'явилося ядро UNIX. Мета проекту GNU – «створення| повноцінної операційної системи на зразок UNIX, оснащеної безкоштовним програмним забезпеченням».
Ядро UNIX і GNU-програми складають дуже могутню комбінацію, яку найчастіше називають просто «UNIX». Але без GNU – програм система не працюватиме, як і без ядра. Тому у багатьох випадках ми говоримо GNU/UNIX.
Компілятори GCC
Компілятор перетворює вихідний вихідний текст програми, зрозумілий людині, в об'єктний код, що виконується комп'ютером. Компілятори, доступні в UNIX-системах, являються являються частиною колекції GNU-компіляторів, відомої як GCC (GNU Compiler Collection). У неї входять компілятори мов C, C++, Java, Objective-C, Fortran і Chill. Нас цікавитиме компілятор з мови С.
Компіляція вихідного вихідного файлу.
Компілятор мови С називається gcc. При компіляції вихідного вихідного файлу потрібно вказувати вказувати опцію –c.
От як, наприклад, в режимі командного рядка компілюється файл prog.c:
$gcc –c prog.c
Одержаний об'єктний файл називатиметься prog.o.
Компоновка об'єктних файлів
Для отримання виконуваного файлу потрібно викликати gcc з опцією –o.
$gcc prog.c –o hello
Створення простої програми prog.c:
#include<stdio.h>
main()
{
printf(«Hello, World!»);
}
Створили текст програми і зберегли її під ім'ям prog.c.
Відкомпілювали програму, використовуючи компілятор gcc.
$ gcc –c prog.c
Одержимо виконуваний файл з ім'ям hello, скориставшись опцією –o.
$ gcc prog.c –o hello
Перевіримо працездатність і правильність виконання програми:
$ ./hello
В результаті успішної роботи програми на екрані повинне з'явитися вітання Hello, world!
Базова обробка командного рядка
Програма на С дістає доступ до своїх аргументів через параметри argc і argv. Аргументи командного рядка - це інформація, слідуюча слідуюча за ім'ям програми в командному рядку операційної системи.
Є два звичайніі засоби визначення функції main() - головної функції програми на мові С:
int main(int argc, char *argv[])
і
int main(int argc, char **argv)
Параметр argc є являється цілим числом, вказуючим кількість наявних аргументів, включаючи ім'я команди.
Параметр argv - це покажчик на масив символьних покажчиків (інакше можна сказати так: argv є являється масивом покажчиків на символи).
Між двома цими оголошеннями немає різниці, хоча перше концептуально зрозуміліше, а друге технічно коректніше:
char ** char *
«cat»
«file1»
«file2»
Тут cat, file1, file2 – рядки мови С, що завершуються символом кінця рядка ‘\0’.
За угодою, argv[0] (у С індекси відлічуються з нуля) є являється ім'ям програми. Подальші елементи являються являються аргументами командного рядка. Останнім елементом масиву є являється покажчик NULL. Всі аргументи командного рядка - це рядки. Всі числа конвертуються програмою у внутрішній формат. Аргументи командного рядка повинні відокремлюватися відокремлюватися пропусками. Коми, точки точки з комами і їм подібні символи не розглядаються розглядуються як роздільники. Якщо необхідно передати рядок, що містить пропуски або табуляції, у вигляді одного аргументу, слід укласти його в подвійні лапки.
Приклад: Програма виводить Hello, а потім ім'я користувача, якщо його набрати прямо за ім'ям програми:
#include<stdio.h>
int main(int argc, char *argv[])
{
if (argc!=2)
{
printf(«You forgot to type your name!\n»);
return 1;
}
printf(«Hello, %s!», argv[1]);
return 0;
}
Якщо назвати дану програму name, а як ім'я вказати Sergey, то в результаті виконання програми на екрані буде
Hello, Sergey!
У випадку, якщо програма буде запущена без вказівки аргументу, на екран буде виведено повідомлення
You forgot to type your name!
Завдання 1: Написати програму, яка:
Виводить на екран ім'я програми;
Перевіряє, чи є хоч би один аргумент і якщо так, то скільки і які.
#include<stdio.h>
int main(int argc, char *argv[])
{
int i;
printf("The program name is %s\n", argv[0]);
if(argc>1)
{
printf("The program has %d params.\n",argc-1);
for( i=1; i<argc;i++)
printf("%d param is: %s\n",i,argv[i]);
}
else
printf("The program has not parametrs!");
return 0;}
Завдання 2: Написати програму, в якій перевіряється можливість відкриття на читання файлу(написаного на мові С).
Рекомендації до виконання:
Перед роботою з файлом його потрібно відкрити. Це можна зробити за допомогою функції fopen():
FILE *fopen(const char filename, const char mode);
Функція fopen() відкриває існуючий файл або створює новий.
У разі успіху вона повертає покажчик потоку, інакше повертає NULL.
Параметри функції:
сonst char filename – покажчик на рядок імені файлу. Може містити в собі інформацію про повний шлях до файлу;
const char mode – покажчик на один з можливих режимів роботи з файлом. Ось деякі з них:
r – читання;
w – запис;
а – додавання.
#include<stdio.h>
main(int argc, char *argv[])
{
FILE *fp;
if(argc>1)
{
if((fp=fopen(argv[1],"r"))==NULL)
{
printf("Cannot opened file %s", argv[1]);
exit(1);
}
else
printf("The file %s is opened",argv[1]);
}
else
printf("Enter file name.");}
Завдання 3: Модифікувати програму з завдання 1 так, щоб для виведення інформації на екран використовувався стандартний потік виведення stdout.
Рекомендації до виконання:
Для роботи з файлами можна використовувати функцію fprintf(), яка працює практично як printf(), але їй потрібен аргумент для посилання на файл.
Наприклад:
int a=87;
fprintf(fp,»a=%d»,a);
де fp - покажчик на файл.
#include<stdio.h>
int main(int argc, char *argv[])
{
int i;
printf("The program name is %s\n", argv[0]);
if(argc>1)
{
fprintf(stdout,"The program has %d params.\n",argc-1);
for( i=1; i<argc;i++)
fprintf(stdout,"%d param is: %s\n",i,argv[i]);
}
else
fprintf(stdout,"The program has not parametrs!");
return 0;}
Завдання 4: Написати програму, яка в інтерактивному режимі читає число аргументів і самі аргументи (рядки) і виводить їх довжину.
Рекомендації до виконання:
У цьому завданні доцільно працювати з стандартними потоками stdin і stdout.
Для прочитування можна використовувати функції fscanf() і fprintf(), fgets():
Функція fscanf() працює аналогічно fprintf(): прочитує дані з файлу і розносить їх по рядку, формату. Наприклад:
fscanf(fp, «%d»,&num);
Тут з файлу, на який указує файлова змінна fp, прочитується ціле число і поміщається за адресою змінної num.
Для роботи з рядками потрібно підключати файл заголовка string.h.
Функція fgets() зручна при порядковому порядковому прочитуванні рядків з файлу:
fgets(а,b,c);
де
а - рядок(покажчик), в який буде записана інформація;
b – кількість символів, які прочитуватимутьсяз рядка;
с – покажчик потоку файлів, тобто звідки прочитуємо.
#include<stdio.h>
#include<string.h>
int main(void)
{
char s[256];
int i,num;
fprintf(stdout,"Enter quantity of strings:");
fscanf(stdin,"%d",&num);
fprintf(stdout,"Input %d strings:\n",num);
for(i=1;i<=num;i++)
{
fprintf(stdout,"String number %d: ",i);
fscanf(stdin,"%s",s);
fprintf(stdout,"Length of this string is %d.\n",strlen(s));
}
fprintf(stdout,"\n");
return 0;
}
