The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

Получить список процессов из C (proc vm)


<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: proc, vm,  (найти похожие документы)
- RU.UNIX.BSD (2:5077/15.22) ------------------------------------ RU.UNIX.BSD - From : Vadim Kolontsov 2:5020/400 27 Apr 00 15:50:40 Subj : Получить список процессов из C ------------------------------------------------------------------------------- From: nospam.vadim@tversu.ru (Vadim Kolontsov) Reply-To: nospam.vadim@tversu.ru In article <gq4ggso087d7le5s4l931o80ahtmjt4v8d@4ax.com>, Yury Lazarev wrote: >Каким образом можно вытащить командную строку, с которой были запущены >процессы в Unix (наподобие того, что выдает команда ps). в новых unix'ах для этого используется псевдо-FS: /proc. Там все просто: cd /proc; ls -l; cd 3354; cat cmdline.. В Linux и PicoBSD, если мне память не изменяет, 'ps' работает именно через /proc Традиционно же ps (и другие подобные вещи, скажем, netstat или top) делается через kernel virtual memory interface (KVM). kvm позволяет получить доступ к памяти ядра, погулять по внутренним структурам (например, списку процессов). Интерфейс прост: kvm_open и kvm_openfiles (позволяющие открыть не только ядро в памяти, но и мертвое ядро на диске); kvm_read, переносящая буфер произвольной длины из памяти ядра ко мне в приложение; kvm_write, выполняющая обратные функции; kvm_geterr (сообщение о произошедшей ошибке); kvm_close и прочее. В ядре много интересной информации. Hо как узнать смещения этих структур? С помощью kvm_nlist(3) (ее аналог для обычных файлов - nlist(3)). kvm_nlist позволяет получить адреса символических переменных. Используя эти адреса, мы считываем в нашу память содержимое областей памяти ядра. Примерчик: ---------------------------------------------------------------------- /* Как посмотреть load average на Solaris'е прямо в ядре */ struct nlist nlst[] ={ {"avenrun"}, {0} }; if (kvm_nlist(kd, nlst) == -1) { (сообщаем об ошибке; exit()) } if (nlst->n_type == 0) { (сообщаем об ошибке; exit()) } ---------------------------------------------------------------------- После того, как адрес массива avenrun выяснен, мы можем прочитать его в память: ---------------------------------------------------------------------- long avenrun[3]; if (kvm_read(kd, nlst->n_value, (char *)avenrun, sizeof(avenrun)) == -1) { (сообщаем об ошибке; exit()) } ---------------------------------------------------------------------- FreeBSD несколько облегает работу с KVM/procs, вводя дополнительные функции: kvm_getprocs, kvm_getargv etc. Однако kvm_read() приходится использовать часто. Пусть мы хотим выяснить, какие сетевые соединений какими процессами используется. Пишем: ---------------------------------------------------------------------- kp = kvm_getprocs(...KERN_PROC_ALL..., &cntproc); for( i = 0; i < cntproc; i++) { struct filedesc filedesc; struct file **files; struct file file; int fileslen; /* Список открытых файлов */ kvm_read(kd, kp[c].kp_proc.p_fd, &filedesc, sizeof(filedesc) ..) fileslen = filedesc.fd_nfiles*sizeof(struct file *); files = malloc(fileslen); /* Загружаем массив указатель на fd'ы */ kvm_read(kd, filedesc.fd_ofiles, files, fileslen); /* Пробегаем по файлам */ for (j = 0; j < filedesc.fd_nfiles; j++, files++) { дальше загружаем структуру 'file' для каждого fd.. kvm_read(kd, *files, &file, sizeof(struct file)); выясняем тип fd: if (file.f_type = DTYPE_SOCKET) ... далее загружаем file.f_data как структуру socket, для определения socket family загружаем socket.so_proto (protosw), загружаем protosw.pr_domain и проверяем: domain.dom_faimyly == AF_INET sock.so_type == SOCK_DGRAM/SOCK_STREAM; далее загружаем protocol control block (pcb) - socket.so_pcb, и так далее, пока не выясним все, что нам интересно.. довольно нудно, конечно; /proc - удобнее; но kvm дает доступ к чему угодно! } } ---------------------------------------------------------------------- в 97-м году я кидал такую программку в freebsd-hackers как пример использования KVM. Пример вывода: 21319 tcp:ESTABLISHED aa.bb.cc.dd:1339 aa.bb.dd.ee:119 451 tcp:LISTEN aa.bb.cc.dd:80 *:* 6622 udp *:NNNN *:* и т.д... >Может быть кто-нибудь подскажет, как это проще сделать? kvm_getargv() возвращает массив (а-ля argv[]), в которым указаны параметры запуска (= командная строка). ps использует именно kvm_getargv(). Можно извлечь те же данные и руками - через kvm_read() (см. описание структуры proc). char **a; a = kvm_getargv(...) if (a) while (*a) printf("%s ", *a++); >Пытался разобраться с исходниками ps - дохлый номер (маловато знаний). упорство и упорство - и все получится :) >В man как-то весьма невнятно описаны функции kvm. Где бы найти >какое-нибудь более подробное описание, желательно с примерами. 4.4BSD Daemon Book, исходники ядра, исходные тексты программ... V. P.S. KVM в man pages описан нормально :) --- ifmail v.2.15dev5 * Origin: Tver State University NOC (2:5020/400)

<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>

 Добавить комментарий
Имя:
E-Mail:
Заголовок:
Текст:




Спонсоры:
Слёрм
Inferno Solutions
Hosting by Ihor
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2019 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру