Esempio n. 1
0
/*
 * check_process_text
 *   check [process] text (memory)
 *
 *   in  : pid
 *   out : -1 if error
 *          0 if no match
 *          1 if match
 */
static int
check_process_text(fdOpenInfoRef info, int pid)
{
	int		status;
	int		buf_used;
	struct proc_regionwithpathinfo	rwpi;

	if (info->flags & PROC_LISTPIDSPATH_PATH_IS_VOLUME) {

		// ask for first memory region that matches mountpoint
		buf_used = proc_pidinfo(pid, PROC_PIDREGIONPATHINFO3, info->match_stat.st_dev, &rwpi, sizeof(rwpi));
		if (buf_used <= 0) {
			if ((errno == ESRCH) || (errno == EINVAL)) {
				// if no more text information is available for this process.
				return 0;
			}
			return -1;
		} else if (buf_used < sizeof(rwpi)) {
			// if we didn't get enough information
			return -1;
		}
		
		status = check_file(info, &rwpi.prp_vip.vip_vi.vi_stat);
		if (status != 0) {
			// if error or match
			return status;
		}
	} else {
		uint64_t	a	= 0;
		
		while (1) {	// for all memory regions
			// processing next address
			buf_used = proc_pidinfo(pid, PROC_PIDREGIONPATHINFO2, a, &rwpi, sizeof(rwpi));
			if (buf_used <= 0) {
				if ((errno == ESRCH) || (errno == EINVAL)) {
					// if no more text information is available for this process.
					break;
				}
				return -1;
			} else if (buf_used < sizeof(rwpi)) {
				// if we didn't get enough information
				return -1;
			}
			
			status = check_file(info, &rwpi.prp_vip.vip_vi.vi_stat);
			if (status != 0) {
				// if error or match
				return status;
			}
			
			a = rwpi.prp_prinfo.pri_address + rwpi.prp_prinfo.pri_size;
		}
	}

	return 0;
}
Esempio n. 2
0
void slay_impl(pid_t *pids, int n, int sig, pid_t pid, int include_children) {
	int i, hit = 0;

	DEBUG_V("slay %d with signal %d", pid, sig);
	kill(pid, sig);
	for (i = 0; i < n; i++) {
		struct proc_bsdinfo info;
		CHECK(proc_pidinfo(pids[i], PROC_PIDTBSDINFO, 0, &info, sizeof info));
		if (info.pbi_pid == pid) {
			if (info.pbi_status == SZOMB) {
				LOG_V("Not killing PID %d because it's already died (in state 'Z').", pid);
			}
			else {
				LOG_V("Kill PID %d (in state 0x%x) with signal %d", pid, info.pbi_status, sig);
				kill(pid, sig);
			}
			hit = 1;
		}
		if (include_children && (info.pbi_ppid == pid)) {
			if (info.pbi_status == SZOMB) {
				LOG_V("Not killing PID %d because it's already died (in state 'Z').", info.pbi_pid);
			}
			else
				slay_impl(pids, n, sig, info.pbi_pid, include_children);
		}
	}
	if (!hit) {
		LOG_V("PID %d was missing from the proc list (while sending signal %d)", pid, sig);
	}
}
Esempio n. 3
0
/*
 * check_process_text
 *   check [process] text (memory)
 *
 *   in  : pid
 *   out : -1 if error
 *          0 if no match
 *          1 if match
 */
static int
check_process_text(fdOpenInfoRef info, int pid)
{
	uint64_t	a	= 0;
	int		status;

	while (1) {	// for all memory regions
		int				buf_used;
		struct proc_regionwithpathinfo	rwpi;

		// processing next address
		buf_used = proc_pidinfo(pid, PROC_PIDREGIONPATHINFO, a, &rwpi, sizeof(rwpi));
		if (buf_used <= 0) {
			if ((errno == ESRCH) || (errno == EINVAL)) {
				// if no more text information is available for this process.
				break;
			}
			return -1;
		} else if (buf_used < sizeof(rwpi)) {
			// if we didn't get enough information
			return -1;
		}

		status = check_file(info, &rwpi.prp_vip.vip_vi.vi_stat);
		if (status != 0) {
			// if error or match
			return status;
		}

		a = rwpi.prp_prinfo.pri_address + rwpi.prp_prinfo.pri_size;
	}

	return 0;
}
Esempio n. 4
0
quint64 UtilObject::processTime() {
	static const pid_t pid = qApp->applicationPid();
	struct proc_taskinfo info;
	if (proc_pidinfo(pid, PROC_PIDTASKINFO, 0, &info, sizeof(info)) < 0)
		return 0;
	return info.pti_total_user/1000 + info.pti_total_system/1000;
}
Esempio n. 5
0
void tt_fs_status_dump_ntv(IN tt_u32_t flag)
{
    pid_t pid;
    int size;
    struct proc_fdinfo *fdinfo;

    pid = getpid();
    size = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
    if (size <= 0) {
        return;
    }

    fdinfo = (struct proc_fdinfo *)malloc(size);
    if (fdinfo == NULL) {
        return;
    }

    size = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fdinfo, size);
    if (size > 0) {
        int n, i;

        n = size / PROC_PIDLISTFD_SIZE;
        for (i = 0; i < n; ++i) {
            if (fdinfo[i].proc_fdtype == PROX_FDTYPE_VNODE) {
                struct vnode_fdinfowithpath vi;
                int vs = proc_pidfdinfo(pid,
                                        fdinfo[i].proc_fd,
                                        PROC_PIDFDVNODEPATHINFO,
                                        &vi,
                                        PROC_PIDFDVNODEPATHINFO_SIZE);
                if (vs == PROC_PIDFDVNODEPATHINFO_SIZE) {
                    tt_printf("%s[fd: %d] [%s]\n",
                              TT_COND(flag & TT_FS_STATUS_PREFIX,
                                      "<<FS>> ",
                                      ""),
                              fdinfo[i].proc_fd,
                              vi.pvip.vip_path);
                }
            }
        }
    }

    free(fdinfo);
}
int
get_proc_threadinfo (pid_t pid, uint64_t thread_handle, struct proc_threadinfo *pth)
{
  pth->pth_name[0] = '\0';
  int ret = proc_pidinfo (pid, PROC_PIDTHREADINFO, thread_handle,
                          pth, sizeof (struct proc_threadinfo));
  if (ret != 0)
    return 1;
  else
    return 0;
}
void genOpenDescriptors(int pid, descriptor_type type, QueryData& results) {
  int bufsize = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, 0, 0);
  if (bufsize == -1) {
    VLOG(1) << "Could not list descriptors for pid: " << pid;
    return;
  }

  // Allocate structs for each descriptor.
  std::vector<proc_fdinfo> fds(bufsize / PROC_PIDLISTFD_SIZE);
  proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds.data(), bufsize);

  for (auto fd_info : fds) {
    if (type == DESCRIPTORS_TYPE_VNODE &&
        fd_info.proc_fdtype == PROX_FDTYPE_VNODE) {
      genFileDescriptor(pid, fd_info.proc_fd, results);
    } else if (type == DESCRIPTORS_TYPE_SOCKET &&
               fd_info.proc_fdtype == PROX_FDTYPE_SOCKET) {
      genSocketDescriptor(pid, fd_info.proc_fd, results);
    }
  }
}
Esempio n. 8
0
int find_fd_for_pid(pid_t pid, int *fd_list, int max_fd)
{
int count = 0;
int bufferSize = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, 0, 0);
struct stat stat_buf;

if (bufferSize < 0) {
    printf("Error :/, cannot proc_pidinfo\n");
    return 0;
}
struct proc_fdinfo *procFDInfo = (struct proc_fdinfo *)malloc(bufferSize);
proc_pidinfo(pid, PROC_PIDLISTFDS, 0, procFDInfo, bufferSize);
int numberOfProcFDs = bufferSize / PROC_PIDLISTFD_SIZE;
int i;

for(i = 0; i < numberOfProcFDs; i++) {
    if(procFDInfo[i].proc_fdtype == PROX_FDTYPE_VNODE) {
        struct vnode_fdinfowithpath vnodeInfo;
        proc_pidfdinfo(pid, procFDInfo[i].proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo, PROC_PIDFDVNODEPATHINFO_SIZE);
        if (stat(vnodeInfo.pvip.vip_path, &stat_buf) < 0) {
            if (flag_debug)
                perror("sstat");
            continue;
        }
        if (!S_ISREG(stat_buf.st_mode) && !S_ISBLK(stat_buf.st_mode))
            continue;

        if (is_ignored_file(vnodeInfo.pvip.vip_path))
            continue;

        // OK, we've found a potential interesting file.

        fd_list[count++] = procFDInfo[i].proc_fd;
        //~ printf("[debug] %s\n",vnodeInfo.pvip.vip_path);
        if(count == max_fd)
            break;
    }
}
return count;
}
Esempio n. 9
0
inline bool getProcCred(int pid, proc_cred &cred) {
  struct proc_bsdshortinfo bsdinfo;

  if (proc_pidinfo(pid, PROC_PIDT_SHORTBSDINFO, 0, &bsdinfo, sizeof(bsdinfo)) ==
      sizeof(bsdinfo)) {
    cred.real.uid = bsdinfo.pbsi_ruid;
    cred.real.gid = bsdinfo.pbsi_ruid;
    cred.effective.uid = bsdinfo.pbsi_uid;
    cred.effective.gid = bsdinfo.pbsi_gid;
    return true;
  }
  return false;
}
Esempio n. 10
0
inline bool getProcCred(int pid, proc_cred& cred) {
  struct proc_bsdinfo bsdinfo;
  struct proc_bsdshortinfo bsdinfo_short;

  if (proc_pidinfo(pid, PROC_PIDTBSDINFO, 1, &bsdinfo, PROC_PIDTBSDINFO_SIZE) ==
      PROC_PIDTBSDINFO_SIZE) {
    cred.parent = bsdinfo.pbi_ppid;
    cred.group = bsdinfo.pbi_pgid;
    cred.status = bsdinfo.pbi_status;
    cred.nice = bsdinfo.pbi_nice;
    cred.real.uid = bsdinfo.pbi_ruid;
    cred.real.gid = bsdinfo.pbi_rgid;
    cred.effective.uid = bsdinfo.pbi_uid;
    cred.effective.gid = bsdinfo.pbi_gid;
    cred.saved.uid = bsdinfo.pbi_svuid;
    cred.saved.gid = bsdinfo.pbi_svgid;
    return true;
  } else if (proc_pidinfo(pid,
                          PROC_PIDT_SHORTBSDINFO,
                          1,
                          &bsdinfo_short,
                          PROC_PIDT_SHORTBSDINFO_SIZE) ==
             PROC_PIDT_SHORTBSDINFO_SIZE) {
    cred.parent = bsdinfo_short.pbsi_ppid;
    cred.group = bsdinfo_short.pbsi_pgid;
    cred.status = bsdinfo_short.pbsi_status;
    cred.real.uid = bsdinfo_short.pbsi_ruid;
    cred.real.gid = bsdinfo_short.pbsi_rgid;
    cred.effective.uid = bsdinfo_short.pbsi_uid;
    cred.effective.gid = bsdinfo_short.pbsi_gid;
    cred.saved.uid = bsdinfo_short.pbsi_svuid;
    cred.saved.gid = bsdinfo_short.pbsi_svgid;
    return true;
  }
  return false;
}
Esempio n. 11
0
char *
osdep_get_cwd(pid_t pid)
{
	static char 			wd[PATH_MAX];
	struct proc_vnodepathinfo	pathinfo;
	int				ret;

	ret = proc_pidinfo(
	    pid, PROC_PIDVNODEPATHINFO, 0, &pathinfo, sizeof pathinfo);
	if (ret == sizeof pathinfo) {
		strlcpy(wd, pathinfo.pvi_cdir.vip_path, sizeof wd);
		return (wd);
	}
	return (NULL);
}
Esempio n. 12
0
bool iszombie(pid_t p)
{
    int ret;
    struct proc_bsdshortinfo bsdinfo;

    ret = proc_pidinfo(p, PROC_PIDT_SHORTBSDINFO, 1, &bsdinfo, sizeof(bsdinfo));
    if (ret != sizeof(bsdinfo)) {
        return false;
    }

    if (bsdinfo.pbsi_status == SZOMB) {
        return true;
    } else {
        return false;
    }
}
Esempio n. 13
0
char *
osdep_get_name(int fd, __unused char *tty)
{
	struct proc_bsdinfo		bsdinfo;
	pid_t				pgrp;
	int				ret;

	if ((pgrp = tcgetpgrp(fd)) == -1)
		return (NULL);

	ret = proc_pidinfo(pgrp, PROC_PIDTBSDINFO, 0,
	    &bsdinfo, sizeof bsdinfo);
	if (ret == sizeof bsdinfo && *bsdinfo.pbi_comm != '\0')
		return (strdup(bsdinfo.pbi_comm));
	return (NULL);
}
Esempio n. 14
0
static void close_all_fds() {
#if HAVE_FDWALK
  fdwalk(fdwalker_close, NULL);
#elif defined(linux) || defined(__linux) || defined(__linux__)
  char path[PATH_MAX];
  DIR *root;
  struct dirent *de, *entry;
  int size = 0;

  snprintf(path, sizeof(path), "/proc/%d/fd", getpid());
#ifdef _PC_NAME_MAX
  size = pathconf(path, _PC_NAME_MAX);
#endif
  size = MAX(size, PATH_MAX + 128);
  de = alloca(size);
  close(3); /* hoping opendir uses 3 */
  root = opendir(path);
  if(!root) return;
  while(portable_readdir_r(root, de, &entry) == 0 && entry != NULL) {
    if(entry->d_name[0] >= '1' && entry->d_name[0] <= '9') {
      int tgt;
      tgt = atoi(entry->d_name);
      if(tgt != 3) close(tgt);
    }
  }
  close(3);
#elif defined(__MACH__) && defined(__APPLE__)
  struct proc_fdinfo files[1024*16];
  int rv, i = 0;

  rv = proc_pidinfo(getpid(), PROC_PIDLISTFDS, 0, files, sizeof(files));
  if(rv > 0 && (rv % sizeof(files[0])) == 0) {
    rv /= sizeof(files[0]);
    for(i=0;i<rv;i++) {
      (void) close(files[i].proc_fd);
    }
  }
#else
  struct rlimit rl;
  int i, reasonable_max;

  getrlimit(RLIMIT_NOFILE, &rl);
  reasonable_max = MIN(1<<14, rl.rlim_max);
  for (i = 0; i < reasonable_max; i++)
    (void) close(i);
#endif
}
Esempio n. 15
0
void genProcRootAndCWD(int pid, Row &r) {
  r["cwd"] = "";
  r["root"] = "";

  struct proc_vnodepathinfo pathinfo;
  if (proc_pidinfo(
          pid, PROC_PIDVNODEPATHINFO, 0, &pathinfo, sizeof(pathinfo)) ==
      sizeof(pathinfo)) {
    if (pathinfo.pvi_cdir.vip_vi.vi_stat.vst_dev != 0) {
      r["cwd"] = std::string(pathinfo.pvi_cdir.vip_path);
    }

    if (pathinfo.pvi_rdir.vip_vi.vi_stat.vst_dev != 0) {
      r["root"] = std::string(pathinfo.pvi_rdir.vip_path);
    }
  }
}
static int getProcessInfo(RTPROCESS process, struct proc_taskinfo *tinfo)
{
    LogAleksey(("getProcessInfo() getting info for %d", process));
    int nb = proc_pidinfo(process, PROC_PIDTASKINFO, 0,  tinfo, sizeof(*tinfo));
    if (nb <= 0)
    {
        int rc = errno;
        Log(("proc_pidinfo() -> %s", strerror(rc)));
        return RTErrConvertFromDarwin(rc);
    }
    else if ((unsigned int)nb < sizeof(*tinfo))
    {
        Log(("proc_pidinfo() -> too few bytes %d", nb));
        return VERR_INTERNAL_ERROR;
    }
    return VINF_SUCCESS;
}
Esempio n. 17
0
bool LibProc::GetProcessInfo(ProcessId pid, ProcessInfo &info) {
  int res;
  struct proc_taskallinfo ti;

  res = proc_pidinfo(pid, PROC_PIDTASKALLINFO, 0, &ti, sizeof(ti));
  if (res <= 0)
    return false;

  info.pid = pid;
  info.parentPid = ti.pbsd.pbi_ppid;
  info.realUid = ti.pbsd.pbi_ruid;
  info.effectiveUid = ti.pbsd.pbi_uid;
  info.realGid = ti.pbsd.pbi_rgid;
  info.effectiveGid = ti.pbsd.pbi_svgid;
  info.name = std::string(ti.pbsd.pbi_comm);

  return true;
}
Esempio n. 18
0
/*
 * Return process open files as a Python tuple.
 * References:
 * - lsof source code: http://goo.gl/SYW79 and http://goo.gl/m78fd
 * - /usr/include/sys/proc_info.h
 */
static PyObject*
get_process_open_files(PyObject* self, PyObject* args)
{
    long pid;
    int pidinfo_result;
    int iterations;
    int i;
    int nb;

    struct proc_fdinfo *fds_pointer;
    struct proc_fdinfo *fdp_pointer;
    struct vnode_fdinfowithpath vi;

    PyObject *retList = PyList_New(0);
    PyObject *tuple = NULL;

    if (! PyArg_ParseTuple(args, "l", &pid)) {
        return NULL;
    }

    pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
    if (pidinfo_result <= 0) {
        goto error;
    }

    fds_pointer = malloc(pidinfo_result);
    pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds_pointer,
                                  pidinfo_result);
    free(fds_pointer);

    if (pidinfo_result <= 0) {
        goto error;
    }

    iterations = (pidinfo_result / PROC_PIDLISTFD_SIZE);

    for (i = 0; i < iterations; i++) {
        fdp_pointer = &fds_pointer[i];

        //
        if (fdp_pointer->proc_fdtype == PROX_FDTYPE_VNODE)
        {
            nb = proc_pidfdinfo(pid,
                                fdp_pointer->proc_fd,
                                PROC_PIDFDVNODEPATHINFO,
                                &vi,
                                sizeof(vi));

            // --- errors checking
            if (nb <= 0) {
                if ((errno == ENOENT) || (errno == EBADF)) {
                    // no such file or directory or bad file descriptor;
                    // let's assume the file has been closed or removed
                    continue;
                }
                if (errno != 0) {
                    return PyErr_SetFromErrno(PyExc_OSError);
                }
                else
                    return PyErr_Format(PyExc_RuntimeError,
                                "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed");
            }
            if (nb < sizeof(vi)) {
                return PyErr_Format(PyExc_RuntimeError,
                 "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed (buffer mismatch)");
            }
            // --- /errors checking

            // --- construct python list
            tuple = Py_BuildValue("(si)", vi.pvip.vip_path,
                                          (int)fdp_pointer->proc_fd);
            PyList_Append(retList, tuple);
            Py_DECREF(tuple);
            // --- /construct python list
        }
    }

    return retList;

error:
    if (errno != 0) {
        return PyErr_SetFromErrno(PyExc_OSError);
    }

    else if (! pid_exists(pid) ) {
        return NoSuchProcess();
    }

    else {
        return PyErr_Format(PyExc_RuntimeError,
                            "proc_pidinfo(PROC_PIDLISTFDS) failed");
    }
}
Esempio n. 19
0
/*
 * Return process TCP and UDP connections as a list of tuples.
 * References:
 * - lsof source code: http://goo.gl/SYW79 and http://goo.gl/wNrC0
 * - /usr/include/sys/proc_info.h
 */
static PyObject*
get_process_connections(PyObject* self, PyObject* args)
{
    long pid;
    int pidinfo_result;
    int iterations;
    int i;
    int nb;

    struct proc_fdinfo *fds_pointer;
    struct proc_fdinfo *fdp_pointer;
    struct socket_fdinfo si;

    PyObject *retList = PyList_New(0);
    PyObject *tuple = NULL;
    PyObject *laddr = NULL;
    PyObject *raddr = NULL;
    PyObject *af_filter = NULL;
    PyObject *type_filter = NULL;

    if (! PyArg_ParseTuple(args, "lOO", &pid, &af_filter, &type_filter)) {
        return NULL;
    }

    if (!PySequence_Check(af_filter) || !PySequence_Check(type_filter)) {
        PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence");
        return NULL;
    }

    if (pid == 0) {
        return retList;
    }

    pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
    if (pidinfo_result <= 0) {
        goto error;
    }

    fds_pointer = malloc(pidinfo_result);
    pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds_pointer,
                                  pidinfo_result);
    free(fds_pointer);

    if (pidinfo_result <= 0) {
        goto error;
    }

    iterations = (pidinfo_result / PROC_PIDLISTFD_SIZE);

    for (i = 0; i < iterations; i++) {
        errno = 0;
        fdp_pointer = &fds_pointer[i];

        //
        if (fdp_pointer->proc_fdtype == PROX_FDTYPE_SOCKET)
        {
            nb = proc_pidfdinfo(pid, fdp_pointer->proc_fd, PROC_PIDFDSOCKETINFO,
                                &si, sizeof(si));

            // --- errors checking
            if (nb <= 0) {
                if (errno == EBADF) {
                    // let's assume socket has been closed
                    continue;
                }
                if (errno != 0) {
                    return PyErr_SetFromErrno(PyExc_OSError);
                }
                else {
                    return PyErr_Format(PyExc_RuntimeError,
                                "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed");
                }
            }
            if (nb < sizeof(si)) {
                return PyErr_Format(PyExc_RuntimeError,
                 "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed (buffer mismatch)");
            }
            // --- /errors checking

            //
            int fd, family, type, lport, rport;
            char lip[200], rip[200];
            char *state;
            int inseq;
            PyObject* _family;
            PyObject* _type;

            fd = (int)fdp_pointer->proc_fd;
            family = si.psi.soi_family;
            type = si.psi.soi_kind;

            if (type == 2) {
                type = SOCK_STREAM;
            }

            else if (type == 1) {
                type = SOCK_DGRAM;
            }

            else {
                continue;
            }

            // apply filters
            _family = PyLong_FromLong((long)family);
            inseq = PySequence_Contains(af_filter, _family);
            Py_DECREF(_family);
            if (inseq == 0) {
                continue;
            }

            _type = PyLong_FromLong((long)type);
            inseq = PySequence_Contains(type_filter, _type);
            Py_DECREF(_type);
            if (inseq == 0) {
                continue;
            }

            if (errno != 0) {
                return PyErr_SetFromErrno(PyExc_OSError);
            }

            if (family == AF_INET) {
                inet_ntop(AF_INET,
                          &si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_laddr.ina_46.i46a_addr4,
                          lip,
                          sizeof(lip));
                inet_ntop(AF_INET,
                          &si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_faddr.ina_46.i46a_addr4,
                          rip,
                          sizeof(lip));
            }

            else {
                inet_ntop(AF_INET6,
                          &si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_laddr.ina_6,
                          lip, sizeof(lip));
                inet_ntop(AF_INET6,
                          &si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_faddr.ina_6,
                          lip, sizeof(rip));
            }

            // check for inet_ntop failures
            if (errno != 0) {
                return PyErr_SetFromErrno(PyExc_OSError);
            }

            lport = ntohs(si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_lport);
            rport = ntohs(si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_fport);
            if (type == SOCK_STREAM) {
                state = get_connection_status((int)si.psi.soi_proto.pri_tcp.tcpsi_state);
            }

            else {
                state = "";
            }

            laddr = Py_BuildValue("(si)", lip, lport);
            if (rport != 0) {
                raddr = Py_BuildValue("(si)", rip, rport);
            }

            else {
                raddr = PyTuple_New(0);
            }

            // --- construct python list
            tuple = Py_BuildValue("(iiiNNs)", fd, family, type, laddr, raddr,
                                              state);
            PyList_Append(retList, tuple);
            Py_DECREF(tuple);
            // --- /construct python list
        }
    }

    return retList;

error:
    if (errno != 0) {
        return PyErr_SetFromErrno(PyExc_OSError);
    }

    else if (! pid_exists(pid) ) {
        return NoSuchProcess();
    }

    else {
        return PyErr_Format(PyExc_RuntimeError,
                            "proc_pidinfo(PROC_PIDLISTFDS) failed");
    }
}
Esempio n. 20
0
/*
 * check_process_fds
 *   check [process] open file descriptors
 *
 *   in  : pid
 *   out : -1 if error
 *          0 if no match
 *          1 if match
 */
static int
check_process_fds(fdOpenInfoRef info, int pid)
{
	int	buf_used;
	int	i;
	int	status;

	// get list of open file descriptors
	buf_used = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
	if (buf_used <= 0) {
		return -1;
	}

	while (1) {
		if (buf_used > info->fds_size) {
			// if we need to allocate [more] space
			while (buf_used > info->fds_size) {
				info->fds_size += (sizeof(struct proc_fdinfo) * 32);
			}

			if (info->fds == NULL) {
				info->fds = malloc(info->fds_size);
			} else {
				info->fds = reallocf(info->fds, info->fds_size);
			}
			if (info->fds == NULL) {
				return -1;
			}
		}

		buf_used = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, info->fds, (int)info->fds_size);
		if (buf_used <= 0) {
			return -1;
		}

		if ((buf_used + sizeof(struct proc_fdinfo)) >= info->fds_size) {
			// if not enough room in the buffer for an extra fd
			buf_used = (int)(info->fds_size + sizeof(struct proc_fdinfo));
			continue;
		}

		info->fds_count = (int)(buf_used / sizeof(struct proc_fdinfo));
		break;
	}

	// iterate through each file descriptor
	for (i = 0; i < info->fds_count; i++) {
		struct proc_fdinfo	*fdp;

		fdp = &info->fds[i];
		switch (fdp->proc_fdtype) {
			case PROX_FDTYPE_VNODE : {
				int			buf_used;
				struct vnode_fdinfo	vi;

				buf_used = proc_pidfdinfo(pid, fdp->proc_fd, PROC_PIDFDVNODEINFO, &vi, sizeof(vi));
				if (buf_used <= 0) {
					if (errno == ENOENT) {
						/*
						 * The file descriptor's vnode may have been revoked. This is a
						 * bit of a hack, since an ENOENT error might not always mean the
						 * descriptor's vnode has been revoked. As the libproc API
						 * matures, this code may need to be revisited.
						 */
						continue;
					}
					return -1;
				} else if (buf_used < sizeof(vi)) {
					// if we didn't get enough information
					return -1;
				}

				if ((info->flags & PROC_LISTPIDSPATH_EXCLUDE_EVTONLY) &&
				    (vi.pfi.fi_openflags & O_EVTONLY)) {
					// if this file should be excluded
					continue;
				}

				status = check_file(info, &vi.pvi.vi_stat);
				if (status != 0) {
					// if error or match
					return status;
				}
				break;
			}
			default :
				break;
		}
	}

	return 0;
}
Esempio n. 21
0
/*
 * check_process_threads
 *   check [process] thread working directories
 *
 *   in  : pid
 *   out : -1 if error
 *          0 if no match
 *          1 if match
 */
static int
check_process_threads(fdOpenInfoRef info, int pid)
{
	int				buf_used;
	int				status;
	struct proc_taskallinfo		tai;

	buf_used = proc_pidinfo(pid, PROC_PIDTASKALLINFO, 0, &tai, sizeof(tai));
	if (buf_used <= 0) {
		if (errno == ESRCH) {
			// if the process is gone
			return 0;
		}
		return -1;
	} else if (buf_used < sizeof(tai)) {
		// if we didn't get enough information
		return -1;
	}

	// check thread info
	if (tai.pbsd.pbi_flags & PROC_FLAG_THCWD) {
		int	i;

		// get list of threads
		buf_used = tai.ptinfo.pti_threadnum * sizeof(uint64_t);

		while (1) {
			if (buf_used > info->thr_size) {
				// if we need to allocate [more] space
				while (buf_used > info->thr_size) {
					info->thr_size += (sizeof(uint64_t) * 32);
				}

				if (info->threads == NULL) {
					info->threads = malloc(info->thr_size);
				} else {
					info->threads = reallocf(info->threads, info->thr_size);
				}
				if (info->threads == NULL) {
					return -1;
				}
			}

			buf_used = proc_pidinfo(pid, PROC_PIDLISTTHREADS, 0, info->threads, (int)info->thr_size);
			if (buf_used <= 0) {
				return -1;
			}

			if ((buf_used + sizeof(uint64_t)) >= info->thr_size) {
				// if not enough room in the buffer for an extra thread
				buf_used = (int)(info->thr_size + sizeof(uint64_t));
				continue;
			}

			info->thr_count = buf_used / sizeof(uint64_t);
			break;
		}

		// iterate through each thread
		for (i = 0; i < info->thr_count; i++) {
			uint64_t			thr	= info->threads[i];
			struct proc_threadwithpathinfo	tpi;

			buf_used = proc_pidinfo(pid, PROC_PIDTHREADPATHINFO, thr, &tpi, sizeof(tpi));
			if (buf_used <= 0) {
				if ((errno == ESRCH) || (errno == EINVAL)) {
					// if the process or thread is gone
					continue;
				}
			} else if (buf_used < sizeof(tai)) {
				// if we didn't get enough information
				return -1;
			}

			status = check_file(info, &tpi.pvip.vip_vi.vi_stat);
			if (status != 0) {
				// if error or match
				return status;
			}
		}
	}

	return 0;
}
Esempio n. 22
0
QueryData genProcesses(QueryContext& context) {
  QueryData results;

  // Initialize time conversions.
  static mach_timebase_info_data_t time_base;
  if (time_base.denom == 0) {
    mach_timebase_info(&time_base);
  }

  auto pidlist = getProcList(context);
  int argmax = genMaxArgs();

  for (auto& pid : pidlist) {
    Row r;
    r["pid"] = INTEGER(pid);

    {
      // The command line invocation including arguments.
      auto args = getProcRawArgs(pid, argmax);
      std::string cmdline = boost::algorithm::join(args.args, " ");
      r["cmdline"] = cmdline;
    }

    // The process relative root and current working directory.
    genProcRootAndCWD(pid, r);

    proc_cred cred;
    if (getProcCred(pid, cred)) {
      r["parent"] = BIGINT(cred.parent);
      r["pgroup"] = BIGINT(cred.group);
      // check if process state is one of the expected ones
      r["state"] = (1 <= cred.status && cred.status <= 5)
                       ? TEXT(kProcessStateMapping[cred.status])
                       : TEXT('?');
      r["nice"] = INTEGER(cred.nice);
      r["uid"] = BIGINT(cred.real.uid);
      r["gid"] = BIGINT(cred.real.gid);
      r["euid"] = BIGINT(cred.effective.uid);
      r["egid"] = BIGINT(cred.effective.gid);
      r["suid"] = BIGINT(cred.saved.uid);
      r["sgid"] = BIGINT(cred.saved.gid);
    } else {
      continue;
    }

    // If the process is not a Zombie, try to find the path and name.
    if (cred.status != 5) {
      r["path"] = getProcPath(pid);
      // OS X proc_name only returns 16 bytes, use the basename of the path.
      r["name"] = fs::path(r["path"]).filename().string();
    } else {
      r["path"] = "";
      std::vector<char> name(17);
      proc_name(pid, name.data(), 16);
      r["name"] = std::string(name.data());
    }

    // If the path of the executable that started the process is available and
    // the path exists on disk, set on_disk to 1. If the path is not
    // available, set on_disk to -1. If, and only if, the path of the
    // executable is available and the file does NOT exist on disk, set on_disk
    // to 0.
    if (r["path"].empty()) {
      r["on_disk"] = INTEGER(-1);
    } else if (pathExists(r["path"])) {
      r["on_disk"] = INTEGER(1);
    } else {
      r["on_disk"] = INTEGER(0);
    }

    // systems usage and time information
    struct rusage_info_v2 rusage_info_data;
    int status =
        proc_pid_rusage(pid, RUSAGE_INFO_V2, (rusage_info_t*)&rusage_info_data);
    // proc_pid_rusage returns -1 if it was unable to gather information
    if (status == 0) {
      // size/memory information
      r["wired_size"] = TEXT(rusage_info_data.ri_wired_size);
      r["resident_size"] = TEXT(rusage_info_data.ri_resident_size);
      r["total_size"] = TEXT(rusage_info_data.ri_phys_footprint);

      // time information
      r["user_time"] = TEXT(rusage_info_data.ri_user_time / CPU_TIME_RATIO);
      r["system_time"] = TEXT(rusage_info_data.ri_system_time / CPU_TIME_RATIO);
      // Convert the time in CPU ticks since boot to seconds.
      // This is relative to time not-sleeping since boot.
      r["start_time"] =
          TEXT((rusage_info_data.ri_proc_start_abstime / START_TIME_RATIO) *
               time_base.numer / time_base.denom);
    } else {
      r["wired_size"] = "-1";
      r["resident_size"] = "-1";
      r["total_size"] = "-1";
      r["user_time"] = "-1";
      r["system_time"] = "-1";
      r["start_time"] = "-1";
    }

    struct proc_taskinfo task_info;
    status =
        proc_pidinfo(pid, PROC_PIDTASKINFO, 0, &task_info, sizeof(task_info));
    if (status == sizeof(task_info)) {
      r["threads"] = INTEGER(task_info.pti_threadnum);
    } else {
      r["threads"] = "-1";
    }

    results.push_back(r);
  }

  return results;
}
/**
 * Read all processes to initialize the information tree.
 * @param reference reference of ProcessTree
 * @param pflags Process engine flags
 * @return treesize > 0 if succeeded otherwise 0
 */
int initprocesstree_sysdep(ProcessTree_T **reference, ProcessEngine_Flags pflags) {
        size_t pinfo_size = 0;
        int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
        if (sysctl(mib, 4, NULL, &pinfo_size, NULL, 0) < 0) {
                LogError("system statistic error -- sysctl failed: %s\n", STRERROR);
                return 0;
        }
        struct kinfo_proc *pinfo = CALLOC(1, pinfo_size);
        if (sysctl(mib, 4, pinfo, &pinfo_size, NULL, 0)) {
                FREE(pinfo);
                LogError("system statistic error -- sysctl failed: %s\n", STRERROR);
                return 0;
        }
        size_t treesize = pinfo_size / sizeof(struct kinfo_proc);
        ProcessTree_T *pt = CALLOC(sizeof(ProcessTree_T), treesize);

        char *args = NULL;
        StringBuffer_T cmdline = NULL;
        if (pflags & ProcessEngine_CollectCommandLine) {
                cmdline = StringBuffer_create(64);
                args = CALLOC(1, systeminfo.argmax + 1);
        }
        for (int i = 0; i < treesize; i++) {
                pt[i].uptime    = systeminfo.time / 10. - pinfo[i].kp_proc.p_starttime.tv_sec;
                pt[i].zombie    = pinfo[i].kp_proc.p_stat == SZOMB ? true : false;
                pt[i].pid       = pinfo[i].kp_proc.p_pid;
                pt[i].ppid      = pinfo[i].kp_eproc.e_ppid;
                pt[i].cred.uid  = pinfo[i].kp_eproc.e_pcred.p_ruid;
                pt[i].cred.euid = pinfo[i].kp_eproc.e_ucred.cr_uid;
                pt[i].cred.gid  = pinfo[i].kp_eproc.e_pcred.p_rgid;
                if (pflags & ProcessEngine_CollectCommandLine) {
                        size_t size = systeminfo.argmax;
                        mib[0] = CTL_KERN;
                        mib[1] = KERN_PROCARGS2;
                        mib[2] = pt[i].pid;
                        if (sysctl(mib, 3, args, &size, NULL, 0) != -1) {
                                /* KERN_PROCARGS2 sysctl() returns following pseudo structure:
                                 *        struct {
                                 *                int argc
                                 *                char execname[];
                                 *                char argv[argc][];
                                 *                char env[][];
                                 *        }
                                 * The strings are terminated with '\0' and may have variable '\0' padding
                                 */
                                int argc = *args;
                                char *p = args + sizeof(int); // arguments beginning
                                StringBuffer_clear(cmdline);
                                p += strlen(p); // skip exename
                                while (argc && p < args + systeminfo.argmax) {
                                        if (*p == 0) { // skip terminating 0 and variable length 0 padding
                                                p++;
                                                continue;
                                        }
                                        StringBuffer_append(cmdline, argc-- ? "%s " : "%s", p);
                                        p += strlen(p);
                                }
                                if (StringBuffer_length(cmdline))
                                        pt[i].cmdline = Str_dup(StringBuffer_toString(StringBuffer_trim(cmdline)));
                        }
                        if (! pt[i].cmdline || ! *pt[i].cmdline) {
                                FREE(pt[i].cmdline);
                                pt[i].cmdline = Str_dup(pinfo[i].kp_proc.p_comm);
                        }
                }
                if (! pt[i].zombie) {
                        struct proc_taskinfo tinfo;
                        int rv = proc_pidinfo(pt[i].pid, PROC_PIDTASKINFO, 0, &tinfo, sizeof(tinfo)); // If the process is zombie, skip this
                        if (rv <= 0) {
                                if (errno != EPERM)
                                        DEBUG("proc_pidinfo for pid %d failed -- %s\n", pt[i].pid, STRERROR);
                        } else if (rv < sizeof(tinfo)) {
                                LogError("proc_pidinfo for pid %d -- invalid result size\n", pt[i].pid);
                        } else {
                                pt[i].memory.usage = (uint64_t)tinfo.pti_resident_size;
                                pt[i].cpu.time     = (double)(tinfo.pti_total_user + tinfo.pti_total_system) / 100000000.; // The time is in nanoseconds, we store it as 1/10s
                                pt[i].threads      = tinfo.pti_threadnum;
                        }
                }
        }
        if (pflags & ProcessEngine_CollectCommandLine) {
                StringBuffer_free(&cmdline);
                FREE(args);
        }
        FREE(pinfo);

        *reference = pt;
        
        return (int)treesize;
}
Esempio n. 24
0
JNIEXPORT jlong JNICALL
Java_com_sun_management_UnixOperatingSystem_getOpenFileDescriptorCount
  (JNIEnv *env, jobject mbean)
{
#ifdef __APPLE__
    // This code is influenced by the darwin lsof source
    pid_t my_pid;
    struct proc_bsdinfo bsdinfo;
    struct proc_fdinfo *fds;
    int nfiles;
    kern_return_t kres;
    int res;
    size_t fds_size;

    kres = pid_for_task(mach_task_self(), &my_pid);
    if (res != KERN_SUCCESS) {
        throw_internal_error(env, "pid_for_task failed");
        return -1;
    }

    // get the maximum number of file descriptors
    res = proc_pidinfo(my_pid, PROC_PIDTBSDINFO, 0, &bsdinfo, PROC_PIDTBSDINFO_SIZE);
    if (res <= 0) {
        throw_internal_error(env, "proc_pidinfo with PROC_PIDTBSDINFO failed");
        return -1;
    }

    // allocate memory to hold the fd information (we don't acutally use this information
    // but need it to get the number of open files)
    fds_size = bsdinfo.pbi_nfiles * sizeof(struct proc_fdinfo);
    fds = malloc(fds_size);
    if (fds == NULL) {
        JNU_ThrowOutOfMemoryError(env, "could not allocate space for file descriptors");
        return -1;
    }

    // get the list of open files - the return value is the number of bytes
    // proc_pidinfo filled in
    res = proc_pidinfo(my_pid, PROC_PIDLISTFDS, 0, fds, fds_size);
    if (res <= 0) {
        free(fds);
        throw_internal_error(env, "proc_pidinfo failed for PROC_PIDLISTFDS");
        return -1;
    }
    nfiles = res / sizeof(struct proc_fdinfo);
    free(fds);

    return nfiles;
#elif defined(_ALLBSD_SOURCE)
    /*
     * XXXBSD: there's no way available to do it in FreeBSD, AFAIK.
     */
    // throw_internal_error(env, "Unimplemented in FreeBSD");
    return (100);
#else /* solaris/linux */
    DIR *dirp;
    struct dirent dbuf;
    struct dirent* dentp;
    jlong fds = 0;

    dirp = opendir("/proc/self/fd");
    if (dirp == NULL) {
        throw_internal_error(env, "Unable to open directory /proc/self/fd");
        return -1;
    }

    // iterate through directory entries, skipping '.' and '..'
    // each entry represents an open file descriptor.
    while ((dentp = read_dir(dirp, &dbuf)) != NULL) {
        if (isdigit(dentp->d_name[0])) {
            fds++;
        }
    }

    closedir(dirp);
    // subtract by 1 which was the fd open for this implementation
    return (fds - 1);
#endif
}
Esempio n. 25
0
int
netsnmp_arch_swrun_container_load( netsnmp_container *container, u_int flags)
{
    int	                 mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};
    size_t               buf_size, mib_size = sizeof(mib)/sizeof(mib[0]);
    struct kinfo_proc   *processes = NULL;
    struct proc_taskallinfo taskinfo;
    netsnmp_swrun_entry *entry;
    int                  rc, num_entries, i;

    DEBUGMSGTL(("swrun:load:arch"," load\n"));

    /*
     * get size to allocate. This introduces a bit of a race condition,
     * as the size could change between this call and the next...
     */
    rc = sysctl(mib, mib_size, NULL, &buf_size, NULL, 0);
    if (rc < 0) {
        snmp_log(LOG_ERR, "KERN_PROC_ALL size sysctl failed: %d\n", rc);
        return -1;
    }

    processes = (struct kinfo_proc*) malloc(buf_size);
    if (NULL == processes) {
        snmp_log(LOG_ERR, "malloc failed\n");
        return -1;
    }

    rc = sysctl(mib, mib_size, processes, &buf_size, NULL, 0);
    if (rc < 0) {
        snmp_log(LOG_ERR, "KERN_PROC_ALL sysctl failed: %d\n", rc);
        free(processes);
        return -1;
    }
    
    num_entries = buf_size / sizeof(struct kinfo_proc);
    
    for (i = 0; i < num_entries; i++) {
        /*
         * skip empty names.
         * p_stat = (SIDL|SRUN|SSLEEP|SSTOP|SZOMB)
         */
        if (('\0' == processes[i].kp_proc.p_comm[0]) ||
            (0 == processes[i].kp_proc.p_pid)) {
            DEBUGMSGTL(("swrun:load:arch",
                        " skipping p_comm '%s', pid %5d, p_pstat %d\n",
                        processes[i].kp_proc.p_comm ? 
                        processes[i].kp_proc.p_comm : "NULL",
                        processes[i].kp_proc.p_pid,
                        processes[i].kp_proc.p_stat));
            continue;
        }

        DEBUGMSGTL(("swrun:load:arch"," %s pid %5d\n",
                    processes[i].kp_proc.p_comm,
                    processes[i].kp_proc.p_pid));

        entry = netsnmp_swrun_entry_create(processes[i].kp_proc.p_pid);
        if (NULL == entry)
            continue; /* error already logged by function */
        rc = CONTAINER_INSERT(container, entry);

        /*
         * p_comm is a partial name, but it is all we have at this point.
         */
        entry->hrSWRunName_len = snprintf(entry->hrSWRunName,
                                          sizeof(entry->hrSWRunName)-1,
                                          "%s", processes[i].kp_proc.p_comm);

        /** sysctl for name, path, params */
        rc = _set_command_name(entry);

        /*
         * map p_stat to RunStatus. Odd that there is no 'running' status.
         */
        switch(processes[i].kp_proc.p_stat) {
            case SRUN:
                entry->hrSWRunStatus = HRSWRUNSTATUS_RUNNABLE;
                break;
            case SSLEEP:
            case SSTOP:
                entry->hrSWRunStatus = HRSWRUNSTATUS_NOTRUNNABLE;
                break;
            case SIDL:
            case SZOMB:
            default:
                entry->hrSWRunStatus = HRSWRUNSTATUS_INVALID;
                break;
        } 

        /*
         * check for system processes
         */
        if (P_SYSTEM & processes[i].kp_proc.p_flag) {
            entry->hrSWRunType = HRSWRUNTYPE_OPERATINGSYSTEM;
            DEBUGMSGTL(("swrun:load:arch", SWRUNINDENT "SYSTEM\n"));
        }
        else entry->hrSWRunType = HRSWRUNTYPE_APPLICATION;

        /*
         * get mem size, run time
         */
        rc = proc_pidinfo( processes[i].kp_proc.p_pid, PROC_PIDTASKALLINFO, 0,
                           &taskinfo, sizeof(taskinfo));
        if (sizeof(taskinfo) != rc) {
            DEBUGMSGTL(("swrun:load:arch", " proc_pidinfo returned %d\n", rc));
        }
        else {
            uint64_t task_mem = taskinfo.ptinfo.pti_resident_size / 1024;
            union {
                u_quad_t     uq; /* u_int64_t */
                UnsignedWide uw; /* struct u_int32_t hi/lo */
            } at, ns;
            at.uq = taskinfo.ptinfo.pti_total_user +
                    taskinfo.ptinfo.pti_total_system;
            ns = at;
            ns.uq = ns.uq / 10000000LL; /* nano to deci */
            if (task_mem > INT32_MAX) {
                DEBUGMSGTL(("swrun:load:arch", SWRUNINDENT "mem overflow\n"));
                task_mem = INT32_MAX;
            }
            if (ns.uq > INT32_MAX) {
                DEBUGMSGTL(("swrun:load:arch", SWRUNINDENT "time overflow\n"));
                ns.uq = INT32_MAX;
            }
            entry->hrSWRunPerfMem = task_mem;
            entry->hrSWRunPerfCPU = ns.uq;
        }
    }
    free(processes);

    DEBUGMSGTL(("swrun:load:arch"," loaded %d entries\n",
                (int)CONTAINER_SIZE(container)));

    return 0;
}
Esempio n. 26
-2
/*
 * check_process_vnodes
 *   check [process] current working directory
 *   check [process] root directory
 *
 *   in  : pid
 *   out : -1 if error
 *          0 if no match
 *          1 if match
 */
static int
check_process_vnodes(fdOpenInfoRef info, int pid)
{
	int				buf_used;
	int				status;
	struct proc_vnodepathinfo	vpi;

	buf_used = proc_pidinfo(pid, PROC_PIDVNODEPATHINFO, 0, &vpi, sizeof(vpi));
	if (buf_used <= 0) {
		if (errno == ESRCH) {
			// if the process is gone
			return 0;
		}
		return -1;
	} else if (buf_used < sizeof(vpi)) {
		// if we didn't get enough information
		return -1;
	}

	// processing current working directory
	status = check_file(info, &vpi.pvi_cdir.vip_vi.vi_stat);
	if (status != 0) {
		// if error or match
		return status;
	}

	// processing root directory
	status = check_file(info, &vpi.pvi_rdir.vip_vi.vi_stat);
	if (status != 0) {
		// if error or match
		return status;
	}

	return 0;
}