Добавим новые записи в учетный файл, запустив еще несколько команд:

$ sleep 15 &

[1] 18063

$ ulimit — c unlimited Разрешаем создание дампов памяти (команда встроена в оболочку)

$ cat Создаем процесс

Нажимаем Ctrl+\ (генерирует SIGQUIT, сигнал 3), чтобы завершить процесс cat

Quit (core dumped)

$

Нажимаем Enter, чтобы увидеть уведомление командной оболочки о завершении программы sleep перед появлением приглашения командной строки

[1]+ Done sleep 15

$ grep xxx badfile grep завершается ошибкой со статусом 2

grep: badfile: No such file or directory

$ echo $? Командная оболочка получила статус grep

(команда встроена в оболочку)

2

Следующие две команды запускают программы, представленные в предыдущих главах (листинги 27.1 и 24.1). Первая из них выполняет файл /bin/echo, в результате чего в учетный файл попадает запись о процессе с именем echo. Вторая создает дочерний процесс, который не выполняет вызов exec().

$ ./t_execve /bin/echo

hello world goodbye

$ ./t_fork

PID=18350 (child) idata=333 istack=666

PID=18349 (parent) idata=111 istack=222

Наконец, выведем содержимое учетного файла, воспользовавшись программой из листинга 28.2:

$ ./acct_view pacct

Command flags term. user start time CPU elapsed

status time time

acct_on — S- 0 root 2010-07-23 17:19:05 0.00 0.00

bash — 0 root 2010-07-23 17:18:55 0.02 21.10

su — S- 0 root 2010-07-23 17:18:51 0.01 24.94

cat — XC 0x83 mtk 2010-07-23 17:19:55 0.00 1.72

sleep — 0 mtk 2010-07-23 17:19:42 0.00 15.01

grep — 0x200 mtk 2010-07-23 17:20:12 0.00 0.00

echo — 0 mtk 2010-07-23 17:21:15 0.01 0.01

t_fork F- 0 mtk 2010-07-23 17:21:36 0.00 0.00

t_fork — 0 mtk 2010-07-23 17:21:36 0.00 3.01

В вышеприведенном выводе для каждого процесса, созданного в сессии командной оболочки, выделяется отдельная строка. Команды ulimit и echo встроены в оболочку, поэтому они не приводят к созданию новых процессов. Обратите внимание на то, что команда sleep идет после записи с командой cat, потому что именно в таком порядке они были завершены.

Большая часть этого вывода не нуждается в дополнительных объяснениях. Столбец flags хранит одиночные буквы, указывая на то, какие биты ac_flag установлены для каждой записи (см. табл. 28.1). О том, как интерпретировать значения кода завершения, хранящиеся в столбце term. status, шла речь в подразделе 26.1.3.

Листинг 28.2. Вывод данных из учетного файла

procexec/acct_view.c

#include

#include

#include

#include

#include

#include "ugid_functions.h" /* Объявление функции userNameFromId() */

#include "tlpi_hdr.h"

#define TIME_BUF_SIZE 100

static long long /* Приводим значение comp_t к типу long long */

comptToLL(comp_t ct)

{

const int EXP_SIZE = 3; /* Трехбитная экспонента с основанием 8 */

const int MANTISSA_SIZE = 13; /* За ней следует 13-битная мантисса */

const int MANTISSA_MASK = (1 << MANTISSA_SIZE) — 1;

long long mantissa, exp;

mantissa = ct & MANTISSA_MASK;

exp = (ct >> MANTISSA_SIZE) & ((1 << EXP_SIZE) — 1);

return mantissa << (exp * 3); /* Степень 8 означает сдвиг влево на три бита */

}

int

main(int argc, char *argv[])

{

int acctFile;

struct acct ac;

ssize_t numRead;

char *s;

char timeBuf[TIME_BUF_SIZE];

struct tm *loc;

time_t t;

if (argc!= 2 || strcmp(argv[1], "-help") == 0)

usageErr("%s file\n", argv[0]);

acctFile = open(argv[1], O_RDONLY);

if (acctFile == –1)

errExit("open");

printf("command flags term. user "

"start time CPU elapsed\n");

printf(" status "

" time time\n");

while ((numRead = read(acctFile, ∾, sizeof(struct acct))) > 0) {

if (numRead!= sizeof(struct acct))

fatal("partial read");

printf("%-8.8s", ac.ac_comm);

printf("%c", (ac.ac_flag & AFORK)? 'F': '-');

printf("%c", (ac.ac_flag & ASU)? 'S': '-');

printf("%c", (ac.ac_flag & AXSIG)? 'X': '-');

printf("%c", (ac.ac_flag & ACORE)? 'C': '-');

#ifdef __linux__

printf(" %#6lx", (unsigned long) ac.ac_exitcode);

#else

/* Во многих других реализациях вместо этого предоставляется поле ac_stat */

printf(" %#6lx", (unsigned long) ac.ac_stat);

#endif

s = userNameFromId(ac.ac_uid);

printf("%-8.8s", (s == NULL)?"???": s);

t = ac.ac_btime;

loc = localtime(&t);

if (loc == NULL) {

printf("???Unknown time??? ");

} else {

strftime(timeBuf, TIME_BUF_SIZE, "%Y-%m-%d %T", loc);

printf("%s", timeBuf);

}

printf("%5.2f %7.2f", (double) (comptToLL(ac.ac_utime) +

comptToLL(ac.ac_stime)) / sysconf(_SC_CLK_TCK), (double)

comptToLL(ac.ac_etime) / sysconf(_SC_CLK_TCK));

printf("\n");

}

if (numRead == –1)

errExit("read");

exit(EXIT_SUCCESS);

}

procexec/acct_view.c

Формат учетного файла версии 3

Перейти на страницу:

Похожие книги