Commit 5e0695d7 authored by Arnaud Blanchard's avatar Arnaud Blanchard
Browse files

Rename blc_processes in blc_process

parent 9e0cc30c
......@@ -19,18 +19,18 @@ find_package(blc_channel REQUIRED)
find_package(blc_program REQUIRED)
#source files
set(sources src/blc_processes.cpp)
set(sources src/blc_process.cpp)
add_definitions(${BL_DEFINITIONS})
include_directories(include ${BL_INCLUDE_DIRS})
#define the shared library
add_library(blc_processes SHARED ${sources})
target_link_libraries(blc_processes ${BL_LIBRARIES})
add_library(blc_process SHARED ${sources})
target_link_libraries(blc_process ${BL_LIBRARIES})
add_library(static_blc_processes STATIC ${sources})
set_target_properties(static_blc_processes PROPERTIES OUTPUT_NAME blc_processes)
add_library(static_blc_process STATIC ${sources})
set_target_properties(static_blc_process PROPERTIES OUTPUT_NAME blc_process)
#Describe what will be to install or in the package by default the prefix (CMAKE_INSTALL_PREFIX) is '/usr/’
install(DIRECTORY include/ DESTINATION include/${PROJECT_NAME})
......
find_package(blc_core REQUIRED)
find_path(BLC_PROCESSES_INCLUDE_DIR blc_processes.h PATH_SUFFIXES blc_processes)
find_library(BLC_PROCESSES_LIBRARY blc_processes )
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(blc_image DEFAULT_MSG BLC_PROCESSES_LIBRARY BLC_PROCESSES_INCLUDE_DIR)
mark_as_advanced(BLC_PROCESSES_INCLUDE_DIR BLC_PROCESSES_LIBRARY )
set(BL_INCLUDE_DIRS ${BLC_PROCESSES_INCLUDE_DIR} ${BL_INCLUDE_DIRS} )
set(BL_LIBRARIES ${BLC_PROCESSES_LIBRARY} ${BL_LIBRARIES} )
......@@ -28,11 +28,20 @@ typedef struct blc_file
typedef struct blc_process
{
#ifdef __cplusplus
blc_process();
~blc_process();
void destroy_children();
void update_children();
#endif
char command[NAME_MAX+1];
char full_command_line[LINE_MAX];
float cpu_percent, mem_percent;
int mem;
pid_t pid, parent_pid;
struct blc_process *children;
int children_nb;
blc_channel **input_channels;
int input_channels_nb;
......
//
// lsof.hpp
// blc_channels
//
// Created by Arnaud Blanchard on 18/04/2016.
//
//
#ifndef BLC_PROCESSES_H
#define BLC_PROCESSES_H
#include "blc_channel.h"
#include <limits.h> //NAME_MAX LINE_MAX
struct file_opening
{
struct blc_process *process;
char access;
char type[8];
};
typedef struct blc_file
{
blc_channel *channel;
struct file_opening *openings;
int openings_nb;
}blc_file;
typedef struct blc_process
{
char command[NAME_MAX+1];
char full_command_line[LINE_MAX];
float cpu_percent, mem_percent;
int mem;
pid_t pid;
blc_channel **input_channels;
int input_channels_nb;
blc_channel **output_channels;
int output_channels_nb;
blc_channel **bidirectional_channels;
int bidirectional_channels_nb;
}blc_process;
extern blc_process *blc_processes;
extern int blc_processes_nb;
blc_file *blc_find_file(char const *name);
blc_process *blc_find_process(pid_t pid);
void blc_update_shared_files(blc_process **processes, int *processes_nb, blc_channel *channels, int channels_nb);
//void blc_update_shared_files(blc_channel *channels, int channels_nb);
void blc_processes_refresh(blc_process *processes, int processes_nb);
#endif /* lsof_hpp */
......@@ -14,8 +14,7 @@
#include <errno.h> //EINTR
#include <sys/wait.h> //waitpid
extern char** environ; //From unistd
extern char** environ; //From unistd for env var
blc_file *blc_files=NULL;
int files_nb=0;
......@@ -23,6 +22,45 @@ int files_nb=0;
blc_process *blc_processes=NULL;
int blc_processes_nb=0;
blc_process::blc_process():children(NULL), children_nb(0), input_channels(NULL), input_channels_nb(0), output_channels(NULL), output_channels_nb(0), bidirectional_channels(0), bidirectional_channels_nb(0){
}
void blc_process::update_children(){
blc_process tmp_process, *child;
char *command;
FILE *pgrep_file;
destroy_children();
SYSTEM_ERROR_CHECK(asprintf(&command, "pgrep -P %d", pid), -1, NULL);
SYSTEM_ERROR_CHECK(pgrep_file=popen(command, "r"), NULL, "Command is: '%s'", command);
FREE(command);
while(fscanf(pgrep_file, "%d\n", &tmp_process.pid)==1){
APPEND_ITEM(&children, &children_nb, &tmp_process);
}
pclose(pgrep_file);
blc_processes_refresh(children, children_nb);
FOR_EACH(child, children, children_nb) child->update_children();
}
blc_process::~blc_process(){
destroy_children();
FREE(input_channels);
FREE(output_channels);
FREE(bidirectional_channels);
}
void blc_process::destroy_children(){
blc_process *child;
FOR_EACH(child, children, children_nb){
child->~blc_process();
}
FREE(children);
children_nb=0;
}
void destroy_file_infos(blc_file **files_infos, int *files_infos_nb)
{
......@@ -58,7 +96,7 @@ void blc_update_shared_files(blc_process **processes, int *processes_nb, blc_cha
char letter, access;
ssize_t n;
int status, pos, len;
blc_process *process=NULL, tmp_process={{0}};
blc_process *process=NULL, tmp_process;
blc_channel tmp_info;
blc_channel *channel;
......@@ -185,11 +223,12 @@ void blc_processes_refresh(blc_process *processes, int processes_nb)
SYSTEM_ERROR_CHECK(setenv("LANG", "C", 1), -1, NULL);
blc_add_arg(&argc, &argv, "ps", NULL);
blc_add_arg(&argc, &argv, "-o", "pid");
blc_add_arg(&argc, &argv, "-o", "ppid");
blc_add_arg(&argc, &argv, "-o", "pid");
blc_add_arg(&argc, &argv, "-o", "%cpu");
blc_add_arg(&argc, &argv, "-o", "rss");
blc_add_arg(&argc, &argv, "-o", "%mem");
blc_add_arg(&argc, &argv, "-o", "comm");
blc_add_arg(&argc, &argv, "-o", "command");
if (processes==NULL) blc_add_arg(&argc, &argv, "-A", NULL);
......@@ -200,7 +239,7 @@ void blc_processes_refresh(blc_process *processes, int processes_nb)
blc_add_arg(&argc, &argv, "-p", arg);
}
}
blc_add_arg(&argc, &argv, NULL, NULL);//The memory will never be freed but it is small. We keep it during all the program.
blc_add_arg(&argc, &argv, NULL, NULL);//The memory will never be freed but it is small. We keep it during all the program (i.e. until execvp).
SYSTEM_ERROR_RETRY_ON_SPECIFIC_ERRNO(dup2(stdout_pipe[1], STDOUT_FILENO), -1, EINTR, NULL);
blc_close_pipe(stdout_pipe);
......@@ -224,12 +263,12 @@ void blc_processes_refresh(blc_process *processes, int processes_nb)
if (mem.size>1)
{
line=mem.chars+pos;
fprintf(stderr, "%s\n", line);
while((ret=sscanf(line, " %d %d %f %d %f %"STRINGIFY_CONTENT(LINE_MAX)"[^\n]\n%n", &tmp_process.pid, &tmp_process.parent_pid, &tmp_process.cpu_percent, &tmp_process.mem, &tmp_process.mem_percent, tmp_process.full_command_line, &length))==5){
// fprintf(stderr, "%s\n", line);
while((ret=sscanf(line, " %d %d %f %d %f %s %"STRINGIFY_CONTENT(LINE_MAX)"[^\n]\n%n", &tmp_process.parent_pid, &tmp_process.pid, &tmp_process.cpu_percent, &tmp_process.mem, &tmp_process.mem_percent, tmp_process.command, tmp_process.full_command_line, &length))==7){
FOR_EACH_INV(process, processes, processes_nb) if (process->pid == tmp_process.pid) *process=tmp_process; //not very efficient
line+=length;
}
if (ret!=-1) EXIT_ON_ERROR("Parsing only '%d' args in '%s'", line);
if (ret!=-1) EXIT_ON_ERROR("Parsing '%d' args instead of 7 in '%s'", ret, line);
}
mem.allocate(0);
}
......
//
// lsof.cpp
// blc_channels
//
// Created by Arnaud Blanchard on 18/04/2016.
//
//
#include "blc_processes.h"
#include "blc_program.h"
#include "blc_command.h"
#include "blc_core.h"
#include <unistd.h> //read
#include <errno.h> //EINTR
#include <sys/wait.h> //waitpid
blc_file *blc_files=NULL;
int files_nb=0;
blc_process *blc_processes=NULL;
int blc_processes_nb=0;
void destroy_file_infos(blc_file **files_infos, int *files_infos_nb)
{
blc_file *current_file;
FOR_EACH(current_file, *files_infos, *files_infos_nb) FREE(current_file->openings);
FREE(*files_infos);
*files_infos_nb=0;
}
blc_process *blc_find_process(pid_t pid)
{
int i;
FOR_INV(i, blc_processes_nb) if (blc_processes[i].pid==pid) return &blc_processes[i];
return NULL;
}
/*
blc_file *blc_find_file(char const *name)
{
int i;
FOR_INV(i, files_nb) if (strcmp(files[i].channel->name, name)==0) return &files[i];
return NULL;
}*/
void blc_update_shared_files(blc_process **processes, int *processes_nb, blc_channel *channels, int channels_nb)
{
blc_mem mem;
char buf[LINE_MAX];
char *path, *str;
int stdout_pipe[2];
pid_t pid;
char letter, access;
ssize_t n;
int status, pos, len;
blc_process *process=NULL, tmp_process={{0}};
blc_channel tmp_info;
blc_channel *channel;
SYSTEM_ERROR_CHECK(pipe(stdout_pipe), -1, NULL);
pid=fork();
if (pid==0)
{
//SPRINTF(buf, "-p^%d", blaar_pid); Exclude itself
SYSTEM_ERROR_RETRY_ON_SPECIFIC_ERRNO(dup2(stdout_pipe[1], STDOUT_FILENO), -1, EINTR, NULL);
blc_close_pipe(stdout_pipe);
SYSTEM_ERROR_CHECK(execlp("lsof", "lsof", "-wlnP", "-F", "actn", "-d", "1-999", NULL), -1, NULL);
}
else
{
mem.chars=NULL;
close(stdout_pipe[1]);
// destroy_file_infos(&files, &files_nb);
do{
SYSTEM_ERROR_RETRY_ON_SPECIFIC_ERRNO(n=read(stdout_pipe[0], buf, sizeof(buf)), -1, EINTR, "read lsof stdout");
mem.append(buf, n);
}while(n!=0);
waitpid(pid, &status, 0);
close(stdout_pipe[0]);
mem.append("", 1); //end of string
str=mem.chars;
do{
letter=str[0];
pos=0;
str++;
switch (letter){
case 'p':
CLEAR(tmp_process);
SYSTEM_SUCCESS_CHECK(sscanf(str, "%d\n%n", &tmp_process.pid, &pos), 1, NULL);
process=NULL;
break;
case 'c':
SYSTEM_SUCCESS_CHECK(sscanf(str, "%"STRINGIFY_CONTENT(NAME_MAX)"s\n", tmp_process.command), 1, NULL);
str=strchr(str, '\n')+1;
break;
case 'a':
access=str[0];
str+=3; //[acces]\nt
len=0;
if (strncmp(str, "PSXSHM\nn", strlen("PSXSHM\nn"))==0) len=strlen("PSXSHM\nn"); //on OSX it is <channel_name with />
if (strncmp(str, "REG\nn/run/shm", strlen("REG\nn/run/shm"))==0) len=strlen("REG\nn/run/shm"); //On Linux it is /dev/shm<channel_name with />
if(len) {
str+=len;
path=str;
str=strchr(str, '\n');
*str=0;
FOR_EACH_INV(channel, channels, channels_nb){
if (strcmp(channel->name, path)==0){
FOR_EACH_INV(process, *processes, *processes_nb) if (process->pid == tmp_process.pid) break;
if(process==*processes-1){//Process not found
process=(blc_process*)APPEND_ITEM(processes, processes_nb, &tmp_process);
}
switch(access){
case 'r':APPEND_ITEM(&process->input_channels, &process->input_channels_nb, &channel);break;
case 'w':APPEND_ITEM(&process->output_channels, &process->output_channels_nb, &channel);break;
case 'u':APPEND_ITEM(&process->bidirectional_channels, &process->bidirectional_channels_nb, &channel);break;
default :EXIT_ON_ERROR("Acces '%c' for channel '%s' is not managed.", access, channel->name);
}
break;
}
}
str++;
//We have not found channel
/* if (channel != channels-1){
if (process==NULL) // It is a new process session.
{
process=blc_find_process(tmp_process.pid);
if (process==NULL) APPEND_ITEM(&blc_processes, &blc_processes_nb, &tmp_process);
}
file=blc_find_file(path);
if (file==NULL)//the file has never been referenced
{
tmp_file.openings=NULL;
tmp_file.openings_nb=0;
tmp_file.channel=channel;
file=(blc_file*)APPEND_ITEM(&files, &files_nb, &tmp_file);
}
tmp_file_opening.process=process;
APPEND_ITEM(&file->openings, &file->openings_nb, &tmp_file_opening);
}*/
}
else str=strchr(str, '\n')+1; //We pass the non shared memory file
break;
default:
str=strchr(str, '\n')+1;
break;
}
str+=pos;
}while(str[0]!=0);
mem.allocate(0);
}
}
void blc_processes_refresh(blc_process *processes, int processes_nb)
{
blc_mem mem;
char buf[4096];
int stdout_pipe[2], n, status, length, pos;
pid_t pid;
char **argv=NULL;
int argc=0;
int ret;
char *arg;
char *line;
blc_process *process, tmp_process;
char tmp_arg[NAME_MAX];
SYSTEM_ERROR_CHECK(pipe(stdout_pipe), -1, NULL);
pid=fork();
if (pid==0){
blc_add_arg(&argc, &argv, "ps", NULL);
blc_add_arg(&argc, &argv, "-o", "pid");
blc_add_arg(&argc, &argv, "-o", "%cpu");
blc_add_arg(&argc, &argv, "-o", "rss");
blc_add_arg(&argc, &argv, "-o", "%mem");
blc_add_arg(&argc, &argv, "-o", "command");
if (processes==NULL) blc_add_arg(&argc, &argv, "-A", NULL);
else{
FOR_EACH_INV(process, processes, processes_nb){
SPRINTF(tmp_arg, "%d", process->pid);
arg=strdup(tmp_arg); //Do not need to be freed, it will be freed when execvp
blc_add_arg(&argc, &argv, "-p", arg);
}
}
blc_add_arg(&argc, &argv, NULL, NULL);//The memory will never be freed but it is small. We keep it during all the program.
SYSTEM_ERROR_RETRY_ON_SPECIFIC_ERRNO(dup2(stdout_pipe[1], STDOUT_FILENO), -1, EINTR, NULL);
blc_close_pipe(stdout_pipe);
SYSTEM_ERROR_CHECK(execvp("ps", argv), -1, NULL);
}
else
{
close(stdout_pipe[1]);
do
{
SYSTEM_ERROR_RETRY_ON_SPECIFIC_ERRNO(n=read(stdout_pipe[0], buf, sizeof(buf)), -1, EINTR, "read ps stdout");
mem.append(buf, n);
}while(n!=0);
close(stdout_pipe[0]);
mem.append("", 1); //end of string
waitpid(pid, &status, 0);
sscanf(mem.chars, "%*[^\n]\n%n", &pos); // remove title
if (mem.size>1)
{
line=mem.chars+pos;
while((ret=sscanf(line, " %d %f %d %f %"STRINGIFY_CONTENT(LINE_MAX)"[^\n]\n%n", &tmp_process.pid, &tmp_process.cpu_percent, &tmp_process.mem, &tmp_process.mem_percent, tmp_process.full_command_line, &length))==4){
FOR_EACH_INV(process, processes, processes_nb) if (process->pid == tmp_process.pid) *process=tmp_process; //not very efficient
line+=length;
}
}
mem.allocate(0);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment