- •6.080401 «Інформаційні управляючи системи і технології» 6.080402 «Інформаційні технології проектування»
- •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 Структури даних
- •3. Операційні системи
- •3.1. Поняття операційної системи
- •3.1.1 Призначення операційної системи
- •3.1.2 Операційна система як розширена машина
- •3.1.3 Операційна система як розподілювач ресурсів
- •3.2 Класифікація сучасних операційних систем
- •4 Архітектура операційних систем
- •4.1 Базові поняття архітектури операційних систем
- •4.1.1 Ядро системи. Привілейований режим і режим користувача
- •4.2 Реалізація архітектури операційних систем
- •4.2.1 Монолітні системи
- •4.2.2 Багаторівневі системи
- •4.3 Системи з мікроядром
- •4.4 Концепція віртуальних машин
- •5. Підтримка програмування в oc unix.
- •5.1. Вивчення передачі інформації
- •5.2. Змінні оточення
- •5.3. Обробка помилок
- •5.4. Правила формування і засоби розбору командних рядків
- •6. Логічна організація файлових систем
- •6. 1. Поняття файла і файлової системи
- •6.1.1. Поняття файла
- •6.1.2. Поняття файлової системи
- •6.1.3. Типи файлів
- •6.1.4. Імена файлів
- •6. 2. Організація інформації у файловій системі
- •6.2.1. Розділи
- •6.2.2. Каталоги
- •6.2.3. Зв’язок розділів і структури каталогів
- •6. 3. Зв’язки
- •6. 3. 1. Жорсткі зв’язки
- •6. 3. 2. Символічні зв’язки
- •6. 4. Атрибути файлів
- •6. 5. Операції над файлами і каталогами
- •6. 5. 1. Підходи до використання файлів процесами
- •6. 5. 2. Загальні відомості про файлові операції
- •7. Файлові операції posix
- •7.1. Відкриття і створення файлів
- •7.2. Закриття файла
- •7.3. Читання і записування даних
- •7.4. Збирання інформації про атрибути файла
- •7.5 Операції над каталогами
- •Література
5.2. Змінні оточення
Операційна система Linux надає кожній запущеній програмі середовище оточенняя. Під середовищем розуміється сукупність пар змінна-значення. Імена змінних і їх значення є рядками. По тому, що існує угода, змінні середовища записуються прописними буквами.
Інтерпретатор команд, як і будь-яка інша програма, має в своєму розпорядженні своє середовище. Наприклад, деякі змінні оточення SHELL-інтерпретатора: HOME, PATH, SHELL, MAIL і т.д.
Функція main() є першою функцією, визначеною користувачем (тобто явно описаною в початковому тексті програми), якої буде передане управління після створення відповідного оточення програми, що запускається на виконання. Традиційно функція main() визначається таким чином:
main(int argc,char *argv[],char *envp[]);
Тут масив envp[] містить покажчики на змінні оточення, передавані програмі. Кожна змінна є рядком виду им’я_зміннойй=значення_змінной.
Стандарт ANSI C визначає тільки два перші аргументи функції main() - argc і argv. Стандарт POSIX.1 визначає також аргуменнт envp, хоча рекомендує передачу оточення програми проводити через глобальну змінну environ:
extern char **environ;
Рекомендується слідувати останньому формату передачі для поліпшення переносимості програм на інші платформи UNIX.
Приведемо приклад фрагмента програми, відповідної стандарту POSIX.1, який виводить значення змінних оточення.
#include<stddef.h>
extern char **environ;
main(int argc, char *argv[])
{
………………….
int i;
for(i=0; i<8;i++)
if(environ[i]!=NULL)
printf(“environ[%d]: %s \n”,i environ[i]);
return 0;
}
Для отримання|здобуття| і установки з програми значень конкретних змінних середовища|середи| оточення можна використовувати функції getenv() і putenv():
#include<stdlib.h>
char *getenv(const char *name);
Повертає значення змінної середовища name.
int putenv(const char *string);
Поміщає змінну і її значення в оточення програми.
5.3. Обробка помилок
Системні виклики і бібліотечні функції розрізняються за способом передачі процесу інформації про помилку, що відбулася під час виконання системного виклику або функції бібліотеки.
Звичайно у разі виникнення помилки системні виклики повертають -1 і встановлюють значення змінної errno, вказуюче причину виникнення помилки. Так, наприклад, існує більше десятка причин завершення системного виклику open(2) з помилкою, і всі вони можуть бути визначені за допомогою змінної errno. Файл заголовків <errno.h> містить коди помилок, значень яких може приймати змінна errno, з короткими коментарями.
Бібліотечні функції, як правило, не встановлюють значення змінної errno, а код повернення різний для різних функцій. Для уточнення повертаного значення бібліотечної функції необхідно звернутися до електронного довідника man(1). Довідник розбитий на розділи:
1 - прикладні утиліти;
2 - системні виклики;
3 - бібліотечні функції;
4 - спеціальні файли, драйвери пристроїв і апаратне забезпечення;
5 - формати різних конфігураційних файлів;
7 - всяка всячина: типи файлових систем, визначення типів даних і т.п.
8 - адміністративні утиліти.
Наприклад:
$ man -3 atoi
Оскільки базовим способом полученяї послуг ядра є системні виклики, розглянемо детальніше обробку помилок в цьому випадку. Змінна errno визначена таким чином:
#include<errno.h>
external int errno;
Слід звернути увагу на те, що значення errno не обнуляється наступним системним викликом, що нормально завершився. Т. о., значення errno має сенс тільки після системного виклику, який завершився з помилкою.
Стандарт ANSI C визначає дві функції, що допомагають повідомити причину помилкової ситуації: strerror(3C) і perror(3C).
Функція strerror(3C) має вигляд:
#include<errno.h>
#include<string.h>
char *strerror(int errnum);
Функція приймає як аргументу errnum номер помилки і повертає покажчик на рядок, що містить повідомлення про причину помилкової ситуації.
Функція perror(3C) оголошена таким чином:
#include<errno.h>
#include<strdio.h>
void perror(const char *s);
Функція виводить в стандартний потік повідомлень про помилки інформацію про помилкову ситуацію, грунтуючись на значенні змінної errno. Сторока s, передавана функції, передує цьому повідомленню і може служити додатковою інформацією, наприклад, містячи назву функції або програми, в якій відбулася помилка.
Наступний приклад ілюструє використання цих двох функцій:
#include<errno.h>
#include<string.h>
#include<stdio.h>
main(int argc, char *argv[])
{
fprintf(stderr,”ENOMEM: %s \n”,strerror(ENOMEM));
errno=ENOEXEC;
perror(argv[0]);
return 0;
}
Існує таблиця, в якій приведені найбільш загальні помилки системних викликів, включаючи повідомлення, які звичайно виводять функції strerror(3C) і perror(3C), а також їх короткий опис. Наприклад:
Код помилки і повідомлення |
Повідомлення |
ENOMEM Not enough space |
При спробі запуску програми (exec(2)) розмір запрошуваної пам'яті перевищив максимально можливий в системі. |
ENOEXEC Exec format error |
Спроба запуску на виконання файлу, який має права на виконання, але не є файлом допустимого виконуваного формату. |
Запустивши програму, ми отримаємо наступний результат:
$ a.out
ENOMEM: Not enough space a.out: Exec format error
