libreoffice-online/tools/map.cpp
Noel Grandin 4ed820d3d5 add a configure option for using clang compiler plugins
and apply the nullptr plugin.

Lots of hacking in my LO tree required to make this work, will probably
end up needing to add an extra parameter to the LO side.

Change-Id: I02ae1dcdece9d9ddf05f7757f6696e3a5d7d1f14
Reviewed-on: https://gerrit.libreoffice.org/32339
Reviewed-by: Tor Lillqvist <tml@collabora.com>
Tested-by: Tor Lillqvist <tml@collabora.com>
2016-12-22 14:23:42 +00:00

180 lines
5 KiB
C++

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <error.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <locale.h>
#define MAP_SIZE 20
#define PATH_SIZE 64
#define BUFFER_SIZE 9600
static int read_buffer(char *buffer, unsigned size,
const char *file, char sep)
{
int file_desc;
unsigned total_bytes = 0;
file_desc = open(file, O_RDONLY);
if (file_desc == -1)
return 0;
for (;;)
{
ssize_t number_bytes = read(file_desc,
buffer + total_bytes,
size - total_bytes);
if (number_bytes == -1)
{
if (errno==EINTR)
continue;
break;
}
total_bytes += number_bytes;
if (total_bytes == size)
{
--total_bytes;
break;
}
if (number_bytes==0)
break; // EOF
}
close(file_desc);
if (total_bytes)
{
int i=total_bytes;
while (i--)
if (buffer[i]=='\n' || buffer[i]=='\0')
buffer[i]=sep;
if (buffer[total_bytes-1]==' ')
buffer[total_bytes-1]='\0';
}
buffer[total_bytes] = '\0';
return total_bytes;
}
static void total_smaps(unsigned proc_id, const char *file, const char *cmdline)
{
FILE *file_pointer;
char buffer[BUFFER_SIZE];
unsigned long long total_private_dirty = 0ull;
unsigned long long total_private_clean = 0ull;
unsigned long long total_shared_dirty = 0ull;
unsigned long long total_shared_clean = 0ull;
unsigned long long smap_value;
char smap_key[MAP_SIZE];
if ((file_pointer = fopen(file, "r")) == nullptr)
error(EXIT_FAILURE, errno, "%s", file);
while (fgets(buffer, sizeof(buffer), file_pointer))
{
if (buffer[0] >= 'A' && buffer[0] <= 'Z')
{
if (sscanf(buffer, "%20[^:]: %llu", smap_key, &smap_value) == 2)
{
if (strncmp("Shared_Dirty", smap_key, 12) == 0)
{
total_shared_dirty += smap_value;
continue;
}
if (strncmp("Shared_Clean", smap_key, 12) == 0)
{
total_shared_clean += smap_value;
continue;
}
if (strncmp("Private_Dirty", smap_key, 13) == 0)
{
total_private_dirty += smap_value;
continue;
}
if (strncmp("Private_Clean", smap_key, 13) == 0)
{
total_private_clean += smap_value;
continue;
}
}
}
}
if (errno)
error(EXIT_FAILURE, errno, "%s\n", cmdline);
printf("%s\n", cmdline);
printf("Process ID :%20d\n", proc_id);
printf("--------------------------------------\n");
printf("Shared Clean :%20lld kB\n", total_shared_clean);
printf("Shared Dirty :%20lld kB\n", total_shared_dirty);
printf("Private Clean :%20lld kB\n", total_private_clean);
printf("Private Dirty :%20lld kB\n", total_private_dirty);
printf("--------------------------------------\n");
printf("Shared :%20lld kB\n", total_shared_clean + total_shared_dirty);
printf("Private :%20lld kB\n\n", total_private_clean + total_private_dirty);
}
int main(int argc, char **argv)
{
DIR *root_proc;
struct dirent *dir_proc;
unsigned pid_proc;
char path_proc[PATH_SIZE];
char cmdline[BUFFER_SIZE];
setlocale (LC_ALL, "");
getopt(argc, argv, "");
if (argc != 2)
error(EXIT_FAILURE, EINVAL, "incorrect arguments");
root_proc = opendir("/proc");
if (!root_proc)
error(EXIT_FAILURE, errno, "%s", "/proc");
while ((dir_proc = readdir(root_proc)))
{
if (!dir_proc && !dir_proc->d_name[0])
error(EXIT_FAILURE, ENOTDIR, "bad dir");
if (*dir_proc->d_name > '0' && *dir_proc->d_name <= '9')
{
pid_proc = strtoul(dir_proc->d_name, nullptr, 10);
snprintf(path_proc, sizeof(path_proc), "/proc/%s/%s", dir_proc->d_name, "cmdline");
if (read_buffer(cmdline, sizeof(cmdline), path_proc, ' ') &&
strstr(cmdline, argv[1]) &&
!strstr(cmdline, argv[0]))
{
snprintf(path_proc, sizeof(path_proc), "/proc/%s/%s", dir_proc->d_name, "smaps");
total_smaps(pid_proc, path_proc, cmdline);
}
}
}
if (errno)
error(EXIT_FAILURE, errno, "fail");
return EXIT_SUCCESS;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */