4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
35 skip_group(ea_file_t
*ef
, uint_t nobjs
)
39 if (ea_previous_object(ef
, &curr_obj
) == -1) {
40 (void) fprintf(stderr
, gettext("lastcomm: "
41 "corrupted exacct file\n"));
47 ok(int argc
, char *argv
[], int index
, uid_t uid
, dev_t tty
, char *command
)
51 for (j
= index
; j
< argc
; j
++)
52 if (strcmp(getname(uid
), argv
[j
]) &&
53 strcmp(getdev(tty
), argv
[j
]) &&
54 strncmp(command
, argv
[j
], fldsiz(acct
, ac_comm
)))
60 disp_group(ea_file_t
*ef
, uint_t nobjs
, int argc
, char *argv
[], int index
)
64 double cpu_usr_secs
= 0.;
65 double cpu_usr_nsecs
= 0.;
66 double cpu_sys_secs
= 0.;
67 double cpu_sys_nsecs
= 0.;
70 major_t tty_major
= 0;
71 minor_t tty_minor
= 0;
76 for (i
= 0; i
< nobjs
; i
++) {
79 if (ea_get_object(ef
, &curr_obj
) == -1) {
80 (void) fprintf(stderr
, gettext("lastcomm: "
81 "corrupted exacct file\n"));
85 switch (curr_obj
.eo_catalog
) {
86 case EXT_STRING
| EXC_DEFAULT
| EXD_PROC_COMMAND
:
87 command
= curr_obj
.eo_item
.ei_string
;
89 case EXT_UINT32
| EXC_DEFAULT
| EXD_PROC_UID
:
90 uid
= curr_obj
.eo_item
.ei_uint32
;
92 case EXT_UINT64
| EXC_DEFAULT
| EXD_PROC_CPU_SYS_SEC
:
93 cpu_sys_secs
= curr_obj
.eo_item
.ei_uint64
;
95 case EXT_UINT64
| EXC_DEFAULT
| EXD_PROC_CPU_USER_SEC
:
96 cpu_usr_secs
= curr_obj
.eo_item
.ei_uint64
;
98 case EXT_UINT64
| EXC_DEFAULT
| EXD_PROC_CPU_SYS_NSEC
:
99 cpu_sys_nsecs
= curr_obj
.eo_item
.ei_uint64
;
101 case EXT_UINT64
| EXC_DEFAULT
| EXD_PROC_CPU_USER_NSEC
:
102 cpu_usr_nsecs
= curr_obj
.eo_item
.ei_uint64
;
104 case EXT_UINT32
| EXC_DEFAULT
| EXD_PROC_TTY_MAJOR
:
105 tty_major
= curr_obj
.eo_item
.ei_uint32
;
107 case EXT_UINT32
| EXC_DEFAULT
| EXD_PROC_TTY_MINOR
:
108 tty_minor
= curr_obj
.eo_item
.ei_uint32
;
110 case EXT_UINT32
| EXC_DEFAULT
| EXD_PROC_ACCT_FLAGS
:
111 flag
= curr_obj
.eo_item
.ei_uint32
;
113 case EXT_UINT64
| EXC_DEFAULT
| EXD_PROC_START_SEC
:
114 time
= (uint32_t)curr_obj
.eo_item
.ei_uint64
;
120 if (curr_obj
.eo_type
== EO_GROUP
)
121 disp_group(ef
, curr_obj
.eo_group
.eg_nobjs
,
125 if (command
== NULL
) {
126 (void) fprintf(stderr
, gettext("lastcomm: "
127 "corrupted exacct file\n"));
132 * If a 64-bit kernel returns a major or minor value that would exceed
133 * the capacity of a 32-bit dev_t (and these also become visible in the
134 * filesystem), then the 32-bit makedev may be inaccurate and return
135 * NODEV. When this occurs, we can remedy the problem by providing
136 * either a function which returns "dev64_t"'s or by providing an LP64
137 * version of lastcomm.
139 tty
= makedev(tty_major
, tty_minor
);
142 * If this record doesn't match the optional arguments, go on to the
145 if (argc
> index
&& !ok(argc
, argv
, index
, uid
, tty
, command
))
149 cpu_usr_secs
+ cpu_usr_nsecs
/ NANOSEC
+
150 cpu_sys_secs
+ cpu_sys_nsecs
/ NANOSEC
;
152 (void) printf("%-*.*s %s %-*s %-*s %6.2f secs %.16s\n",
153 fldsiz(acct
, ac_comm
), fldsiz(acct
, ac_comm
), command
,
154 flagbits(flag
), NMAX
, getname(uid
), LMAX
, getdev(tty
),
155 totalsecs
, ctime(&time
));
159 lc_exacct(char *filename
, int argc
, char *argv
[], int index
)
162 ea_object_t curr_obj
;
164 if (ea_open(&ef
, filename
, EXACCT_CREATOR
,
165 EO_TAIL
| EO_VALID_HDR
, O_RDONLY
, 0) < 0) {
166 switch (ea_error()) {
167 case EXR_CORRUPT_FILE
:
168 (void) fprintf(stderr
, gettext("lastcomm: "
169 "exacct file corrupted\n"));
171 case EXR_SYSCALL_FAIL
:
172 (void) fprintf(stderr
, gettext("lastcomm: "
173 "cannot open %s: %s\n"), filename
,
183 while (ea_previous_object(&ef
, &curr_obj
) != -1) {
184 if (ea_get_object(&ef
, &curr_obj
) == -1) {
185 (void) fprintf(stderr
, gettext("lastcomm: "
186 "exacct file corrupted\n"));
191 * lc_exacct(), in parsing the extended process accounting file,
192 * has knowledge of the fact that process records are top-level
195 if ((curr_obj
.eo_catalog
& EXT_TYPE_MASK
) == EXT_GROUP
) {
196 if (curr_obj
.eo_catalog
==
197 (EXT_GROUP
| EXC_DEFAULT
| EXD_GROUP_PROC
))
198 disp_group(&ef
, curr_obj
.eo_group
.eg_nobjs
,
201 skip_group(&ef
, curr_obj
.eo_group
.eg_nobjs
);
205 * Back up to the head of the object we just consumed.
207 if (ea_previous_object(&ef
, &curr_obj
) == -1) {
208 if (ea_error() == EXR_EOF
)
211 (void) fprintf(stderr
, gettext("lastcomm: "
212 "exacct file corrupted\n"));
217 if (ea_error() != EXR_EOF
) {
218 (void) fprintf(stderr
, gettext("lastcomm: "
219 "exacct file corrupted\n"));
223 (void) ea_close(&ef
);