/* * Copyright (c) 2009, Giampaolo Rodola', Oleksii Shevchuk. * All rights reserved. Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. * * Functions specific for Process.environ(). */ #define _STRUCTURED_PROC 1 #include #if !defined(_LP64) && _FILE_OFFSET_BITS == 64 #undef _FILE_OFFSET_BITS #undef _LARGEFILE64_SOURCE #endif #include #include #include #include #include "environ.h" #define STRING_SEARCH_BUF_SIZE 512 /* * Open address space of specified process and return file descriptor. * @param pid a pid of process. * @param procfs_path a path to mounted procfs filesystem. * @return file descriptor or -1 in case of error. */ static int open_address_space(pid_t pid, const char *procfs_path) { int fd; char proc_path[PATH_MAX]; snprintf(proc_path, PATH_MAX, "%s/%i/as", procfs_path, pid); fd = open(proc_path, O_RDONLY); if (fd < 0) PyErr_SetFromErrno(PyExc_OSError); return fd; } /* * Read chunk of data by offset to specified buffer of the same size. * @param fd a file descriptor. * @param offset an required offset in file. * @param buf a buffer where to store result. * @param buf_size a size of buffer where data will be stored. * @return amount of bytes stored to the buffer or -1 in case of * error. */ static int read_offt(int fd, off_t offset, char *buf, size_t buf_size) { size_t to_read = buf_size; size_t stored = 0; int r; while (to_read) { r = pread(fd, buf + stored, to_read, offset + stored); if (r < 0) goto error; else if (r == 0) break; to_read -= r; stored += r; } return stored; error: PyErr_SetFromErrno(PyExc_OSError); return -1; } /* * Read null-terminated string from file descriptor starting from * specified offset. * @param fd a file descriptor of opened address space. * @param offset an offset in specified file descriptor. * @return allocated null-terminated string or NULL in case of error. */ static char * read_cstring_offt(int fd, off_t offset) { int r; int i = 0; off_t end = offset; size_t len; char buf[STRING_SEARCH_BUF_SIZE]; char *result = NULL; if (lseek(fd, offset, SEEK_SET) == (off_t)-1) { PyErr_SetFromErrno(PyExc_OSError); goto error; } // Search end of string for (;;) { r = read(fd, buf, sizeof(buf)); if (r == -1) { PyErr_SetFromErrno(PyExc_OSError); goto error; } else if (r == 0) { break; } else { for (i=0; i= 0 && count) *count = env_count; if (env_count > 0) result = read_cstrings_block( as, info.pr_envp, ptr_size, env_count); close(as); return result; } /* * Free array of cstrings. * @param array an array of cstrings returned by psutil_read_raw_env, * psutil_read_raw_args or any other function. * @param count a count of strings in the passed array */ void psutil_free_cstrings_array(char **array, size_t count) { int i; if (!array) return; for (i=0; i