我正在尝试从Solaris10上的/proc/psinfo文件中获取信息。这是一个二进制文件,所以我想用Perl解包来解码它。不幸的是,我在构造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有人吗?
发布于 2018-04-04 16:52:16
为了不让读者对更多的编辑感到困惑,我将在这里发布答案。这其实很简单
typedef struct psinfo { int pr_flag;/*进程标志(已弃用;不使用) */ int pr_nlwp;/*进程中活动的lwp个数*/ pid_t pr_pid;/*唯一进程id */ pid_t pr_ppid;父进程的/*进程id */ pid_t pr_pgid;进程组长的/* pid */ pid_t pr_sid;/*会话id */ uid_t pr_uid;/*真实用户id */ uid_t pr_euid;/*有效用户id */ gid_t pr_gid;/*真实组id */ gid_t pr_egid;/*有效组id */ uintptr_t pr_addr;进程的/*地址*/ size_t pr_size;/*进程映像的大小(16) */ size_t pr_rssize;/*驻留集大小(16) */ size_t pr_pad1;dev_t pr_ttydev;/*控制tty设备(或PRNODEV) */ /*以下百分比数字为16位二进制*/ /*分数0.1将二进制指针指向高位的*/ /*右侧(1.0 == 0x8000) */ ushort_t pr_pctcpu;所有lwps */ ushort_t pr_pctmem最近使用的cpu时间的/* %;进程使用的系统内存的/* % */ timestruc_t pr_start;/*进程开始时间,从纪元开始*/ timestruc_t pr_time;/* usr+sys此进程的cpu时间*/ timestruc_t pr_ctime;/* usr+sys被收获子进程的cpu时间*/ char pr_fnamePRFNSZ;/*可执行文件的名称*/ char pr_psargsPRARGSZ;参数列表的/*初始字符*/ int pr_wstat;/*如果是僵尸,则等待()状态*/ int pr_argc;/*初始参数计数*/ uintptr_t pr_argv;初始参数向量的/*地址*/ uintptr_t pr_envp;初始环境向量的/*地址*/ char pr_dmodel;进程的/*数据模型*/ char pr_pad23;taskid_t pr_taskid;/*任务id */ projid_t pr_projid;/*项目id */ int pr_nzomb;进程中的僵尸lwp数量*/ poolid_t pr_poolid;/*池id */ zoneid_t pr_zoneid;/*区域id */ id_t pr_contract;/*进程合约*/ int pr_filler1;/*保留供将来使用*/ lwpsinfo_t pr_lwp;代表lwp的/*信息*/ }psinfo_t;
#include #include #include /* UNIX dirs POSIX */ #include /* error stf POSIX */ #include /* UNIX file ctrl UNIX */ #include /* Solaris proc SUN */ #include /* Strings C89 */#include /* UNIX stat POSIX */ #include /* UNIX types POSIX */ int main() { int integerType;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运算符用于计算变量printf的大小(“int的大小:%ld字节\n”,sizeof(integerType));printf(“长的大小:%ld字节\n”,sizeof(long_type));printf(“浮点数的大小:%ld字节\n”,sizeof(floatType));printf(“双精度大小:%ld字节\n”,sizeof(doubleType));printf(“字符大小:%ld字节\n”,sizeof(charType));printf(“pid_t大小:%ld字节\n”,sizeof(pid_t_type));printf(“uid_t大小:%ld字节\n”,sizeof(uid_t_type));printf(“gid_t大小:%ld字节\n”,sizeof(gid_t_type));printf(“uintptr_t大小:%ld字节\n”,sizeof(uintptr_t_type));printf(“size_t大小:%ld字节\n”,sizeof(size_t_type));printf(“dev_t大小:%ld字节\n”,sizeof(dev_t_type));printf(“ushort_t大小:%ld字节\n”,sizeof(ushort_t_type));printf(“timestruc_t大小:%ld字节\n”,sizeof(timestruc_t_type));printf(“lwpsinfo_t大小:%ld字节\n”,sizeof(lwpsinfo_t_type));printf(“taskid_t大小:%ld字节\n”,sizeof(taskid_t_type));printf(“projid_t大小:%ld字节\n”,sizeof(projid_t_type));printf(“poolid_t大小:%ld字节\n”,sizeof(poolid_t_type));printf(“zoneid_t大小:%ld字节\n”,sizeof(zoneid_t_type));printf(“ctid_t大小:%ld字节\n”,sizeof(ctid_t_type));printf(“time_t大小:%ld字节\n”,sizeof(time_t_type));返回0;}
https://stackoverflow.com/questions/49576093
复制相似问题