У, камрады, чо я токо что прочитал, это песдетс.
Значицца, есть функции setjmp() & longjmp(). Первая позволяет установить точку возврата и возвращает 0 в этом случае, вторая используется для возвращения в указанную точку возврата и несёт с собой ненулевой аргумент. Возврат происходит в точке вызова первой функции и поскольку аргумент ненулевой, программа понимает, что это был возврат из longjmp(), по сути переход. Нафиг это надо - если у тебя вызвана куча вложенных функций и где-то там в глубине произошла ошибка, которая похерила всю работу, то чтоб не возвращацца последовательно, можно такую херню применить. При этом longjmp() делает "раскрутку стека" - сбрасывает все стековые фреймы всех вызванных функций. Поэтому вызывать longjmp() не из вложенных и вызванных функций - категорически запрещаецца - поскоку стека нет и раскручивать нечего, произойдёт сбой или ещё какая херня.
читать дальшеОптимизирующие компиляторы могут поднасрать - соптимизировать код с этими функциями, что он начнёт работать неправильно - поэтому все переменные рядом с этими функциями надо объявлять как volatile -изменяемые. И ваще функции эти использовать только в крайнем случае.
Есть ещё похожие функции sigsetjmp() & siglongjmp() для возврата из обработчиков сигналов.
Переменные среды можно в Линухе прочитать в /proc/self/environ или /proc/PID/environ
аргументы командной строки в /proc/self/cmdline или /proc/PID/cmdline
Более традиционный способ предусматривает использование функций getenv & putenv
Функция getenv даёт тебе прям сцылу на саму переменную среды, которую ты не должен изменять, а putenv делает твою строку, которую ты сообщил, частью среды, поэтому её ты тоже не должен менять, пока не обнулишь переменную. Обнулить переменную можно путём передачи функции строки с именем переменной, но без знака =.
Есть функции setenv & unsetenv, которые не делают твою строку частью среды, но они менее популярны, т.к. пришли из BSD.
для получения параметров командной строки применяется функция getopt()
Пиды процессам назначаются (и ищутся), начиная с 300, т.к. выше 300 обычно всё занято системными процессами.
Ну там ещё рассказывается про структуру бинарного файла - раньше был формат a.out, COFF, а щас ELF. Бинарный файл в формате ELF содержит:
- признак двоичного формата - число, говорящее о том, что он бинарный исполняемый файл
- Код
- стартовый адрес
- данные - символьные константы и инициализированные переменные
- таблицы имён и переадресации - используются для отладки и динамического связывания
- инфа о совместно используемых библиотеках и динамической компоновке + путевое имя компоновщика (кто собирал LFS, тот его видел) а кто не видел - запустите команду readelf над любым бинарником
- другая инфа, описывающая "способ построения процесса"
Когда программа размещается в памяти - с нулевых адресов там есть системная область, потом идет:
- Текстовый сегмент - собсно код. Заканчивается по адресу &etext
- Сегмент инициализированных данных - текстовые строки, переменные. Конечный адрес &edata
- Сегмент неинициализированных данных (bss) - всякие буфера и прочее, которое изначально нулевое, поэтому на диске не хранится, а выделяется при загрузке и выполнении. Конечный адрес &end
- Куча - динамическая память, выделяется по мере необходимости (по запросу)
- Стек - растёт настречу куче, расположен в старших адресах памяти
- массивы argv & environ
- ядро в совсем старших адресах. Процесс его не видит, но ядро присутствует в адресном пространстве процесса (видимо для того, чтобы оно могло лазить в процесс, когда надо)
Системные регистры тут не указаны, хз, есть ли они ваще и есть ли к ним доступ в пространстве процесса
Вот скоко я всякой херни узнал и чо хочу сказать - бесполезно это читать, надо практиковать. Пейсать проги, например, тогда да, имеет смысл всю эту хрень читать и пытацца понять. А так - бесполезняк, всё забудецца довольно быстро.