diff options
Diffstat (limited to 'procfs/procfs_pid_files.c')
-rw-r--r-- | procfs/procfs_pid_files.c | 583 |
1 files changed, 0 insertions, 583 deletions
diff --git a/procfs/procfs_pid_files.c b/procfs/procfs_pid_files.c deleted file mode 100644 index 26a0af33..00000000 --- a/procfs/procfs_pid_files.c +++ /dev/null @@ -1,583 +0,0 @@ -/* procfs -- a translator for providing GNU/Linux compatible - proc pseudo-filesystem - - procfs_pid_files.c -- This file contains definitions to perform - file operations such as creating, writing to, - reading from and removing files that holds - information for each process with PID - - Copyright (C) 2008, FSF. - Written as a Summer of Code Project - - - procfs is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - procfs is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. - - A portion of the code in this file is based on ftpfs code - present in the hurd repositories copyrighted to FSF. The - Copyright notice from that file is given below. - -*/ - -#include <hurd/netfs.h> -#include <fcntl.h> -#include <string.h> -#include <stdio.h> -#include <mach/task_info.h> -#include <sys/resource.h> - -#include "procfs_pid.h" - -/* Update the files named NAME within the directory named - PID also with SYMLINK TARGET if necessary. */ -struct procfs_dir_entry* -update_pid_entries (struct procfs_dir *dir, const char *name, - time_t timestamp, - const char *symlink_target) -{ - struct stat stat; - - memset (&stat, 0, sizeof stat); - if (symlink_target) - { - stat.st_size = strlen (symlink_target); - stat.st_mode = S_IFLNK | 0777; - } - else - { - stat.st_size = 0; - stat.st_mode = S_IFREG | 0444; - } - - return update_entries_list (dir, name, &stat, timestamp, symlink_target); -} - -/* Creates files to store process information for DIR - whose names are pids and returns these files in *NODE. */ -error_t -procfs_create_files (struct procfs_dir *dir, - struct node **node, - time_t timestamp) -{ - int err; - char *file_name, *file_path; - struct procfs_dir_entry *dir_entry; - - if (asprintf (&file_name, "%s", "stat") == -1) - return errno; - if (asprintf (&file_path, "%s/%s", dir->node->nn->dir_entry->name, "stat") == -1) - return errno; - - dir_entry = update_pid_entries (dir, file_name, timestamp, NULL); - err = procfs_create_node (dir_entry, file_path, node); - - free (file_name); - free (file_path); - - if (asprintf (&file_name, "%s", "status") == -1) - return errno; - if (asprintf (&file_path, "%s/%s", dir->node->nn->dir_entry->name, "status") == -1) - return errno; - - dir_entry = update_pid_entries (dir, file_name, timestamp, NULL); - err = procfs_create_node (dir_entry, file_path, node); - - free (file_name); - free (file_path); - - if (asprintf (&file_name, "%s", "cmdline") == -1) - return errno; - if (asprintf (&file_path, "%s/%s", dir->node->nn->dir_entry->name, "cmdline") == -1) - return errno; - - dir_entry = update_pid_entries (dir, file_name, timestamp, NULL); - err = procfs_create_node (dir_entry, file_path, node); - - free (file_name); - free (file_path); - - if (asprintf (&file_name, "%s", "statm") == -1) - return errno; - if (asprintf (&file_path, "%s/%s", dir->node->nn->dir_entry->name, "statm") == -1) - return errno; - - dir_entry = update_pid_entries (dir, file_name, timestamp, NULL); - err = procfs_create_node (dir_entry, file_path, node); - - free (file_name); - free (file_path); - -#if 0 - nodes_list = &node_stat; - nodes_list++; - node = nodes_list; -#endif - - return err; -} - -/* Check if the PSTAT_FLAG is set in the corresponding PS - structure, if not set it and check again and return error - status accordingly. */ -error_t set_field_value (struct proc_stat *ps, int pstat_flag) -{ - error_t err; - - if (! (ps->flags & pstat_flag)) - { - err = proc_stat_set_flags (ps, pstat_flag); - if (err) - return err; - - /* This second check is done since ps.h specifies to - do so since the previous call would not have set - the required value. */ - if (! (ps->flags & pstat_flag)) - return EGRATUITOUS; - } - - return 0; -} - -/* Adjusts TIME_VAL structure having Seconds and - Microseconds into the value in jiffies. The - value of jiffy is a hack to adjust to what - procps uses. */ -jiffy_t adjust_jiffy_time (time_value_t time_val) -{ - jiffy_t jiffy_time = time_val.seconds * JIFFY_ADJUST; - jiffy_time += (time_val.microseconds * JIFFY_ADJUST) - / (1000 * 1000); - - return jiffy_time; -} - -/* Extract the user and system time for the live threads of - the process. This information is directly retrieved from - MACH since neither libps not proc makes this available. */ -error_t get_task_thread_times (task_t task, - struct task_thread_times_info *live_threads_times) -{ - error_t err; - size_t tkcount = TASK_THREAD_TIMES_INFO_COUNT; - - err = task_info (task, TASK_THREAD_TIMES_INFO, - (task_info_t) live_threads_times, &tkcount); - if (err == MACH_SEND_INVALID_DEST) - err = ESRCH; - - return err; -} - -/* Obtains the User Time in UTIME and System Time in STIME from - MACH directly since this is neither made available by libps - nor by proc server. */ -error_t get_live_threads_time (struct proc_stat *ps, - jiffy_t *utime, jiffy_t *stime) -{ - struct task_thread_times_info live_threads_times; - error_t err = set_field_value (ps, PSTAT_TASK); - - if (! err) - { - err = get_task_thread_times (ps->task, &live_threads_times); - if (! err) - { - *utime = adjust_jiffy_time ( - live_threads_times.user_time); - *stime = adjust_jiffy_time ( - live_threads_times.system_time); - } - } - - return err; -} - -/* Get the data for stat file into the structure - PROCFS_STAT. */ -error_t get_stat_data (pid_t pid, - struct procfs_stat **procfs_stat) -{ - error_t err; - struct procfs_stat *new = (struct procfs_stat *) - malloc (sizeof (struct procfs_stat)); - - struct proc_stat *ps; - jiffy_t utime, stime; - - err = _proc_stat_create (pid, ps_context, &ps); - - new->pid = pid; - - if (! err) - { - err = set_field_value (ps, PSTAT_ARGS); - if (! err) - asprintf (&new->comm, "%s", ps->args); - } - - err = set_field_value (ps, PSTAT_STATE); - if (! err) - { - if (ps->state & PSTAT_STATE_P_STOP) - new->state = strdup ("T"); - if (ps->state & PSTAT_STATE_P_ZOMBIE) - new->state = strdup ("Z"); - if (ps->state & PSTAT_STATE_P_FG) - new->state = strdup ("+"); - if (ps->state & PSTAT_STATE_P_SESSLDR) - new->state = strdup ("s"); - if (ps->state & PSTAT_STATE_P_LOGINLDR) - new->state = strdup ("l"); - if (ps->state & PSTAT_STATE_P_FORKED) - new->state = strdup ("f"); - if (ps->state & PSTAT_STATE_P_NOMSG) - new->state = strdup ("m"); - if (ps->state & PSTAT_STATE_P_NOPARENT) - new->state = strdup ("p"); - if (ps->state & PSTAT_STATE_P_ORPHAN) - new->state = strdup ("o"); - if (ps->state & PSTAT_STATE_P_TRACE) - new->state = strdup ("x"); - if (ps->state & PSTAT_STATE_P_WAIT) - new->state = strdup ("w"); - if (ps->state & PSTAT_STATE_P_GETMSG) - new->state = strdup ("g"); - } - - err = set_field_value (ps, PSTAT_PROC_INFO); - if (! err) - { - new->ppid = ps->proc_info->ppid; - new->pgid = ps->proc_info->pgrp; - new->sid = ps->proc_info->session; - new->tty_pgrp = ps->proc_info->pgrp; - } - else - { - new->ppid = 0; - new->pgid = 0; - new->sid = 0; - new->tty_pgrp = 0; - } - - err = set_field_value (ps, PSTAT_STATE); - if (! err) - new->flags = ps->state; - else - new->flags = 0; - - err = set_field_value (ps, PSTAT_TASK_EVENTS); - if (! err) - { - new->minflt = ps->task_events_info->faults; - new->majflt = ps->task_events_info->pageins; - } - else - { - new->minflt = 0; - new->majflt = 0; - } - - /* This seems to be a bit inconsistent with setting of other - fields in this code. There are two reasons for this. - 1. The actual information required is not made available - by libps which should be directly obtained from MACH. - 2. The same code which is required to get the information - have to be reused in procfs_nonpid_files.c */ - err = get_live_threads_time (ps, &utime, &stime); - if (! err) - { - new->utime = utime; - new->stime = stime; - } - else - { - new->utime = 0; - new->stime = 0; - } - - err = set_field_value (ps, PSTAT_TASK_BASIC); - if (! err) - { - new->cutime = adjust_jiffy_time ( - ps->task_basic_info->user_time); - new->cstime = adjust_jiffy_time ( - ps->task_basic_info->system_time); - - new->priority = ps->task_basic_info->base_priority; - new->starttime = adjust_jiffy_time ( - ps->task_basic_info->creation_time); - - new->vsize = ps->task_basic_info->virtual_size; - new->rss = ps->task_basic_info->resident_size; - } - else - { - new->cutime = 0; - new->cstime = 0; - new->priority = 0; - new->starttime = 0; - new->vsize = 0; - new->rss = 0; - } - - new->nice = getpriority (0, pid); - - err = set_field_value (ps, PSTAT_NUM_THREADS); - if (! err) - new->num_threads = ps->num_threads; - else - new->num_threads = 0; - - /* Not Supported in Linux 2.6 or later. */ - new->tty_nr = 0; - new->itrealvalue = 0; - new->nswap = 0; - new->cnswap = 0; - - /* Temporarily set to 0 until correct - values are found .*/ - new->cminflt = 0; - new->cmajflt = 0; - new->rlim = 0; - new->startcode = 0; - new->endcode = 0; - new->startstack = 0; - new->kstkesp = 0; - new->kstkeip = 0; - new->signal = 0; - new->blocked = 0; - new->sigignore = 0; - new->sigcatch = 0; - new->wchan = 0; - new->exit_signal = 0; - new->processor = 0; - new->rt_priority = 0; - new->policy = 0; - new->delayacct_blkio_ticks = 0; - - *procfs_stat = new; - _proc_stat_free (ps); - - return err; -} - -/* Reads required process information from stat file - within the directory represented by pid. Return - the data in DATA and actual length to be written - in LEN. */ -error_t -procfs_read_stat_file (struct procfs_dir_entry *dir_entry, - off_t offset, size_t *len, void *data) -{ - error_t err; - char *stat_data; - struct procfs_stat *procfs_stat; - pid_t pid = atoi (dir_entry->dir->node->nn->dir_entry->name); - - err = get_stat_data (pid, &procfs_stat); - - if (asprintf (&stat_data, "%d (%s) %s %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %llu %lu %ld %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu \n", - procfs_stat->pid, procfs_stat->comm, - procfs_stat->state, procfs_stat->ppid, - procfs_stat->pgid, procfs_stat->sid, - procfs_stat->tty_nr, procfs_stat->tty_pgrp, - procfs_stat->flags, procfs_stat->minflt, - procfs_stat->cminflt, procfs_stat->majflt, - procfs_stat->cmajflt, procfs_stat->utime, - procfs_stat->stime, procfs_stat->cutime, - procfs_stat->cstime, procfs_stat->priority, - procfs_stat->nice, procfs_stat->num_threads, - procfs_stat->itrealvalue, procfs_stat->starttime, - procfs_stat->vsize, BYTES_TO_PAGES(procfs_stat->rss), - procfs_stat->rlim, procfs_stat->startcode, - procfs_stat->endcode, procfs_stat->startstack, - procfs_stat->kstkesp, procfs_stat->kstkeip, - procfs_stat->signal, procfs_stat->blocked, - procfs_stat->sigignore, procfs_stat->sigcatch, - procfs_stat->wchan, procfs_stat->nswap, - procfs_stat->cnswap, procfs_stat->exit_signal, - procfs_stat->processor, procfs_stat->rt_priority, - procfs_stat->policy, - procfs_stat->delayacct_blkio_ticks) == -1) - return errno; - - - memcpy (data, stat_data, strlen(stat_data)); - *len = strlen (data); - - free (stat_data); - free (procfs_stat); - - return err; -} - -/* Reads required process's command line information - from cmline file within the directory represented - by pid. Return the data in DATA and actual length - to be written in LEN. */ -error_t -procfs_read_cmdline_file (struct procfs_dir_entry *dir_entry, - off_t offset, size_t *len, void *data) -{ - char *cmdline_data; - error_t err; - struct proc_stat *ps; - pid_t pid = atoi (dir_entry->dir->node->nn->dir_entry->name); - err = _proc_stat_create (pid, ps_context, &ps); - - err = set_field_value (ps, PSTAT_ARGS); - - if (! err) - if (asprintf (&cmdline_data, "%s \n", ps->args) == -1) - return errno; - - memcpy (data, cmdline_data, strlen(cmdline_data)); - *len = strlen (data); - - _proc_stat_free (ps); - free (cmdline_data); - return err; -} - -/* Reads required process's information that is represented by - stat and statm in a human readable format from status file - within the directory represented by pid. Return the data - in DATA and actual length to be written in LEN. */ -error_t -procfs_read_status_file (struct procfs_dir_entry *dir_entry, - off_t offset, size_t *len, void *data) -{ - char *status_data; - error_t err; - struct proc_stat *ps; - struct procfs_stat *procfs_stat; - - pid_t pid = atoi (dir_entry->dir->node->nn->dir_entry->name); - err = _proc_stat_create (pid, ps_context, &ps); - - err = get_stat_data (pid, &procfs_stat); - - if (! err) - if (asprintf (&status_data, "Name:\t%s\nState:\t%s\nTgid:\t%d\nPid:\t%d\n", procfs_stat->comm, procfs_stat->state, procfs_stat->pid, procfs_stat->pid) == -1) - return errno; - - memcpy (data, status_data, strlen(status_data)); - *len = strlen (data); - - _proc_stat_free (ps); - - free (status_data); - free (procfs_stat); - - return err; -} - -/* Reads required process information from statm file - within the directory represented by pid. Return - the data in DATA and actual length to be written - in LEN. */ -error_t -procfs_read_statm_file (struct procfs_dir_entry *dir_entry, - off_t offset, size_t *len, void *data) -{ - char *statm_data; - error_t err; - struct proc_stat *ps; - struct procfs_stat *procfs_stat; - - pid_t pid = atoi (dir_entry->dir->node->nn->dir_entry->name); - err = _proc_stat_create (pid, ps_context, &ps); - - err = get_stat_data (pid, &procfs_stat); - - if (! err) - if (asprintf (&statm_data, "%lu %ld %d %d %d %d %d\n", - BYTES_TO_PAGES(procfs_stat->vsize), - BYTES_TO_PAGES(procfs_stat->rss), - 0, 0, 0, 0, 0) == -1) - return errno; - - memcpy (data, statm_data, strlen(statm_data)); - *len = strlen (data); - - _proc_stat_free (ps); - - free (statm_data); - free (procfs_stat); - - return err; -} - -/* Reads required process information from each of files - within directory represented by pid, for files specified - by NODE. Return the data in DATA and actual length of - data in LEN. */ -error_t -procfs_read_files_contents (struct node *node, - off_t offset, size_t *len, void *data) -{ - error_t err; - - if (! strcmp (node->nn->dir_entry->name, "stat")) - if (! strcmp (node->nn->dir_entry->dir->fs_path, "")) - err = procfs_read_nonpid_stat (node->nn->dir_entry, - offset, len, data); - else - err = procfs_read_stat_file (node->nn->dir_entry, - offset, len, data); - - if (! strcmp (node->nn->dir_entry->name, "cmdline")) - err = procfs_read_cmdline_file (node->nn->dir_entry, - offset, len, data); - - if (! strcmp (node->nn->dir_entry->name, "status")) - err = procfs_read_status_file (node->nn->dir_entry, - offset, len, data); - - if (! strcmp (node->nn->dir_entry->name, "statm")) - err = procfs_read_statm_file (node->nn->dir_entry, - offset, len, data); - - if (! strcmp (node->nn->dir_entry->name, "meminfo")) - if (! strcmp (node->nn->dir_entry->dir->fs_path, "")) - err = procfs_read_nonpid_meminfo (node->nn->dir_entry, - offset, len, data); - else - err = ENOENT; - - if (! strcmp (node->nn->dir_entry->name, "loadavg")) - if (! strcmp (node->nn->dir_entry->dir->fs_path, "")) - err = procfs_read_nonpid_loadavg (node->nn->dir_entry, - offset, len, data); - else - err = ENOENT; - - if (! strcmp (node->nn->dir_entry->name, "uptime")) - if (! strcmp (node->nn->dir_entry->dir->fs_path, "")) - err = procfs_read_nonpid_uptime (node->nn->dir_entry, - offset, len, data); - else - err = ENOENT; - - if (! strcmp (node->nn->dir_entry->name, "version")) - if (! strcmp (node->nn->dir_entry->dir->fs_path, "")) - err = procfs_read_nonpid_version (node->nn->dir_entry, - offset, len, data); - else - err = ENOENT; - - return err; -} |