Хрестоматия по программированию на Си в Unix




Системные вызовы и взаимодействие с UNIX. Хрестоматия по программированию на Си в Unix - стр. 8


Обратите внимание, что при возврате ответа через второй аргумент longjmp мы прибавили 1, а при печати ответа мы эту единицу отняли. Это сделано на случай ответа j==0, чтобы функция setjmp не вернула бы в этом случае значение 0 (признак установки контрольной точки).

6.7.2. В чем ошибка?

#include <setjmp.h>

jmp_buf jmp; main(){ g(); longjmp(jmp,1); } g(){ printf("Вызвана g\n"); f(); printf("Выхожу из g\n"); } f(){ static n; printf( "Вызвана f\n"); setjmp(jmp); printf( "Выхожу из f %d-ый раз\n", ++n); }

Ответ: longjmp делает прыжок в функцию f(), из которой уже произошел возврат управления. При переходе в тело функции в обход ее заголовка не выполняются машинные команды "пролога" функции - функция остается "неактивированной". При возврате из вызванной таким "нелегальным" путем функции возникает ошибка, и программа падает. Мораль: в функцию, которая НИКЕМ НЕ ВЫЗВАНА, нельзя передавать управление. Обратный прыжок из f() в main() - был бы законен, поскольку функция main() является активной, когда управление находится в теле функции f(). Т.е. можно "прыгать" из вызванной функции в вызывающую: из f() в main() или в g(); и из g() в main();

-- -| f | стек прыгать | g | вызовов сверху вниз | main | функций можно - это соответствует ---------- выкидыванию нескольких верхних слоев стека

но нельзя наоборот: из main() в g() или f(); а также из g() в f(). Можно также совершать прыжок в пределах одной и той же функции:

f(){ ... A: setjmp(jmp); ... longjmp(jmp, ...); ... /* это как бы goto A; */ }

Хозяин файла, процесса, и проверка привелегий.

UNIX - многопользовательская система. Это значит, что одновременно на разных терминалах, подключенных к машине, могут работать разные пользователи (а может и один на нескольких терминалах). На каждом терминале работает свой интерпретатор команд, являющийся потомком процесса /etc/init.

6.8.1. Теперь - про функции, позволяющие узнать некоторые данные про любого пользователя системы. Каждый пользователь в UNIX имеет уникальный номер: идентификатор пользователя (user id), а также уникальное имя: регистрационное имя, которое он набирает для входа в систему. Вся информация о пользователях хранится в файле /etc/passwd. Существуют функции, позволяющие по номеру пользователя узнать регистрационное имя и наоборот, а заодно получить еще некоторую информацию из passwd:

#include <stdio.h>




Содержание  Назад  Вперед