我正在尝试从Solaris 10上的/ proc / psinfo文件获取信息。这是一个二进制文件,所以想用Perl unpack解码它。 不幸的是,我在为Perl unpack命令构建模板时遇到了麻烦。 psinfo结构如下
typedef struct psinfo {
int pr_flag; /* process flags (DEPRECATED: see below) */
int pr_nlwp; /* number of active lwps in the process */
int pr_nzomb; /* number of zombie lwps in the process */
pid_t pr_pid; /* process id */
pid_t pr_ppid; /* process id of parent */
pid_t pr_pgid; /* process id of process group leader */
pid_t pr_sid; /* session id */
uid_t pr_uid; /* real user id */
uid_t pr_euid; /* effective user id */
gid_t pr_gid; /* real group id */
gid_t pr_egid; /* effective group id */
uintptr_t pr_addr; /* address of process */
size_t pr_size; /* size of process image in Kbytes */
size_t pr_rssize; /* resident set size in Kbytes */
dev_t pr_ttydev; /* controlling tty device (or PRNODEV) */
ushort_t pr_pctcpu; /* % of recent cpu time used by all lwps */
ushort_t pr_pctmem; /* % of system memory used by process */
timestruc_t pr_start; /* process start time, from the epoch */
timestruc_t pr_time; /* cpu time for this process */
timestruc_t pr_ctime; /* cpu time for reaped children */
char pr_fname[PRFNSZ]; /* name of exec'ed file */
char pr_psargs[PRARGSZ]; /* initial characters of arg list */
int pr_wstat; /* if zombie, the wait() status */
int pr_argc; /* initial argument count */
uintptr_t pr_argv; /* address of initial argument vector */
uintptr_t pr_envp; /* address of initial environment vector */
char pr_dmodel; /* data model of the process */
lwpsinfo_t pr_lwp; /* information for representative lwp */
taskid_t pr_taskid; /* task id */
projid_t pr_projid; /* project id */
poolid_t pr_poolid; /* pool id */
zoneid_t pr_zoneid; /* zone id */
ctid_t pr_contract; /* process contract id */
} psinfo_t;
但由于我对C一无所知,因此解锁模板中各种psinfo数据类型的表示确实存在问题。 我还尝试用hexdump / xxd来查看psinfo文件,看看我能期待什么数据,但它对我帮助不大。
到目前为止,我已经设法准备好了
#!/usr/bin/perl -w
use strict;
use warnings;
use Data::Dumper;
opendir(PROC,"/proc") or die "Unable to open /proc:$!\n";
while (defined($_= readdir(PROC))){
next if ($_ eq "." or $_ eq "..");
next unless /^\d+$/; # filter out any random non-pid files
open(PSINFO, "/proc/$_/psinfo");
local $/;
read(PSINFO, my $psinfo,1000);
close PSINFO;
my @psinfoInfo = unpack("iiiiiiiiiiIiiiiSSi2i2i2Z16Z80iiIIaa3iiiiii", $psinfo);
print "'@psinfoInfo'\n";
}
closedir(PROC);
使用以下输出
'33554432 1 7871 4646 7871 4646 3339 3339 1087 1087 0 0 0 0 6291464 1 0 1522419148 159507010 0 113016534 0 0 top top 0 1 0 0 986003 3 0 0 0 924925'
'33554432 1 8323 9639 8323 9639 3339 3339 1087 1087 0 4116 2812 0 6291463 0 0 1522419159 626531984 0 39242598 0 0 processChecker. /usr/bin/perl -w ./processChecker.pl 0 3 134511508 134511524 986024 3 0 0 0 924944'
'33554432 1 8147 8146 2165 2165 3339 3339 1087 1087 0 6668 4060 0 -1 0 0 1522408545 333100499 0 513142054 0 0 sshd /usr/lib/ssh/sshd 0 1 134512284 134512292 984753 3 0 0 0 923830'
'33554432 1 21997 8153 21997 8153 3339 3339 1087 1087 0 2400 1504 0 6291458 0 0 1522410593 434583624 0 204410711 0 0 vi vi processChecker.pl 0 2 134511556 134511568 984753 3 0 0 0 923830'
但它与psinfo定义并不真正对应。例如,进程名称被截断,时间值为NOK等。
我知道,有Proc :: processTable可用,我不是要重新发明轮子,但我不能因为各种原因使用该模块,这很重要。
我检查了http://perldoc.perl.org/perlpacktut.html和http://perldoc.perl.org/functions/pack.html,但仍然......
编辑:根据@borodins建议使用短C代码,我也设法在我的机器上获取数据类型的长度Size of int: 4 bytes
Size of long: 4 bytes
Size of float: 4 bytes
Size of double: 8 bytes
Size of char: 1 byte
Size of pid_t: 4 bytes
Size of uid_t: 4 bytes
Size of gid_t: 4 bytes
Size of uintptr_t: 4 bytes
Size of size_t: 4 bytes
Size of dev_t: 4 bytes
Size of ushort_t: 2 bytes
Size of timestruc_t: 8 bytes
Size of lwpsinfo_t: 104 bytes
Size of taskid_t: 4 bytes
Size of projid_t: 4 bytes
Size of poolid_t: 4 bytes
Size of zoneid_t: 4 bytes
Size of ctid_t: 4 bytes
Size of time_t: 4 bytes
任何人
答案 0 :(得分:2)
为了不让观众与更多编辑混淆,我会在这里发布答案。其实非常简单
我从我的系统获得了正确的psinfo信息。在我的系统(Solaris 10 1/13 s10x_u11wos_24a X86)上,它存储在/usr/local/include/sys/procfs.h
中typedef struct psinfo {
int pr_flag; /* process flags (DEPRECATED; do not use) */
int pr_nlwp; /* number of active lwps in the process */
pid_t pr_pid; /* unique process id */
pid_t pr_ppid; /* process id of parent */
pid_t pr_pgid; /* pid of process group leader */
pid_t pr_sid; /* session id */
uid_t pr_uid; /* real user id */
uid_t pr_euid; /* effective user id */
gid_t pr_gid; /* real group id */
gid_t pr_egid; /* effective group id */
uintptr_t pr_addr; /* address of process */
size_t pr_size; /* size of process image in Kbytes */
size_t pr_rssize; /* resident set size in Kbytes */
size_t pr_pad1;
dev_t pr_ttydev; /* controlling tty device (or PRNODEV) */
/* The following percent numbers are 16-bit binary */
/* fractions [0 .. 1] with the binary point to the */
/* right of the high-order bit (1.0 == 0x8000) */
ushort_t pr_pctcpu; /* % of recent cpu time used by all lwps */
ushort_t pr_pctmem; /* % of system memory used by process */
timestruc_t pr_start; /* process start time, from the epoch */
timestruc_t pr_time; /* usr+sys cpu time for this process */
timestruc_t pr_ctime; /* usr+sys cpu time for reaped children */
char pr_fname[PRFNSZ]; /* name of execed file */
char pr_psargs[PRARGSZ]; /* initial characters of arg list */
int pr_wstat; /* if zombie, the wait() status */
int pr_argc; /* initial argument count */
uintptr_t pr_argv; /* address of initial argument vector */
uintptr_t pr_envp; /* address of initial environment vector */
char pr_dmodel; /* data model of the process */
char pr_pad2[3];
taskid_t pr_taskid; /* task id */
projid_t pr_projid; /* project id */
int pr_nzomb; /* number of zombie lwps in the process */
poolid_t pr_poolid; /* pool id */
zoneid_t pr_zoneid; /* zone id */
id_t pr_contract; /* process contract */
int pr_filler[1]; /* reserved for future use */
lwpsinfo_t pr_lwp; /* information for representative lwp */
} psinfo_t;
解压缩psinfo二进制文件的代码是好的。只有我没有意识到timestruc_t有两个元素,秒和纳秒。两种LONG型。 (感谢鲍罗丁)
显示使用的不同数据类型大小的C代码
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h> /* UNIX dirs POSIX */
#include <errno.h> /* error stf POSIX */
#include <fcntl.h> /* UNIX file ctrl UNIX */
#include <procfs.h> /* Solaris proc SUN */
#include <string.h> /* Strings C89 */
#include <sys/stat.h> /* UNIX stat POSIX */
#include <sys/types.h> /* UNIX types POSIX */
int main()
{
int integerType;
long long_type;
float floatType;
double doubleType;
char charType;
pid_t pid_t_type;
uid_t uid_t_type;
gid_t gid_t_type;
uintptr_t uintptr_t_type;
size_t size_t_type;
dev_t dev_t_type;
ushort_t ushort_t_type;
timestruc_t timestruc_t_type;
lwpsinfo_t lwpsinfo_t_type;
taskid_t taskid_t_type;
projid_t projid_t_type;
poolid_t poolid_t_type;
zoneid_t zoneid_t_type;
ctid_t ctid_t_type;
time_t time_t_type;
// Sizeof operator is used to evaluate the size of a variable
printf("Size of int: %ld bytes\n",sizeof(integerType));
printf("Size of long: %ld bytes\n",sizeof(long_type));
printf("Size of float: %ld bytes\n",sizeof(floatType));
printf("Size of double: %ld bytes\n",sizeof(doubleType));
printf("Size of char: %ld byte\n",sizeof(charType));
printf("Size of pid_t: %ld bytes\n",sizeof(pid_t_type));
printf("Size of uid_t: %ld bytes\n",sizeof(uid_t_type));
printf("Size of gid_t: %ld bytes\n",sizeof(gid_t_type));
printf("Size of uintptr_t: %ld bytes\n",sizeof(uintptr_t_type));
printf("Size of size_t: %ld bytes\n",sizeof(size_t_type));
printf("Size of dev_t: %ld bytes\n",sizeof(dev_t_type));
printf("Size of ushort_t: %ld bytes\n",sizeof(ushort_t_type));
printf("Size of timestruc_t: %ld bytes\n",sizeof(timestruc_t_type));
printf("Size of lwpsinfo_t: %ld bytes\n",sizeof(lwpsinfo_t_type));
printf("Size of taskid_t: %ld bytes\n",sizeof(taskid_t_type));
printf("Size of projid_t: %ld bytes\n",sizeof(projid_t_type));
printf("Size of poolid_t: %ld bytes\n",sizeof(poolid_t_type));
printf("Size of zoneid_t: %ld bytes\n",sizeof(zoneid_t_type));
printf("Size of ctid_t: %ld bytes\n",sizeof(ctid_t_type));
printf("Size of time_t: %ld bytes\n",sizeof(time_t_type));
return 0;
}