4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
28 #include <stdio_ext.h>
31 #include <sys/corectl.h>
32 #include <sys/sysmacros.h>
33 #include <sys/types.h>
43 convert_path(const char *path
, char *fname
, size_t size
,
44 struct ps_prochandle
*P
)
48 const psinfo_t
*pip
= Ppsinfo(P
);
53 fname
[size
- 1] = '\0';
56 while ((p
= strchr(path
, '%')) != NULL
&& size
!= 0) {
57 len
= MIN(size
, p
- path
);
58 bcopy(path
, fname
, len
);
61 if ((size
-= len
) == 0)
67 len
= snprintf(fname
, size
, "%d", (int)pip
->pr_pid
);
70 len
= snprintf(fname
, size
, "%d", (int)pip
->pr_uid
);
73 len
= snprintf(fname
, size
, "%d", (int)pip
->pr_gid
);
76 len
= snprintf(fname
, size
, "%s", pip
->pr_fname
);
80 if (Pexecname(P
, exec
, sizeof (exec
)) == NULL
||
81 exec
[0] != '/' || (s
= strrchr(exec
, '/')) == NULL
)
85 len
= snprintf(fname
, size
, "%s", &exec
[1]);
90 len
= snprintf(fname
, size
, "%s", uts
.nodename
);
95 len
= snprintf(fname
, size
, "%s", uts
.machine
);
98 len
= snprintf(fname
, size
, "%ld", (long)time(NULL
));
102 * getzonenamebyid() returns the size including the
103 * terminating null byte so we need to adjust len.
105 if ((len
= getzonenamebyid(pip
->pr_zoneid
, fname
,
107 len
= snprintf(fname
, size
, "%d",
108 (int)pip
->pr_zoneid
);
117 len
= snprintf(fname
, size
, "%%%c", *p
);
129 (void) strncpy(fname
, path
, size
);
133 gcore(struct ps_prochandle
*P
, const char *fname
, core_content_t content
,
136 if (Pgcore(P
, fname
, content
) == 0) {
137 (void) printf("%s: %s dumped\n", pname
, fname
);
139 (void) fprintf(stderr
, "%s: %s dump failed: %s\n", pname
,
140 fname
, errno
== EBADE
? "unexpected short write" :
147 main(int argc
, char **argv
)
149 struct ps_prochandle
*P
;
153 int opt_p
= 0, opt_g
= 0, opt_c
= 0;
156 char fname
[MAXPATHLEN
];
157 char path
[MAXPATHLEN
];
159 core_content_t content
= CC_CONTENT_DEFAULT
;
162 if ((pname
= strrchr(argv
[0], '/')) == NULL
)
165 argv
[0] = ++pname
; /* for getopt() */
167 while ((opt
= getopt(argc
, argv
, "o:Fgpc:")) != EOF
) {
173 if (proc_str2content(optarg
, &content
) != 0) {
174 (void) fprintf(stderr
, "%s: invalid "
175 "content string '%s'\n", pname
, optarg
);
181 oflags
|= PGRAB_FORCE
;
194 if ((opt_p
| opt_g
) == 0) {
200 if ((options
= core_get_options()) == -1) {
201 perror("core_get_options()");
205 if (opt_p
&& !(options
& CC_PROCESS_PATH
)) {
206 (void) fprintf(stderr
, "%s: per-process core dumps "
207 "are disabled (ignoring -p)\n", pname
);
211 if (opt_g
&& !(options
& CC_GLOBAL_PATH
)) {
212 (void) fprintf(stderr
, "%s: global core dumps "
213 "are disabled (ignoring -g)\n", pname
);
217 if ((opt_p
| opt_g
) == 0 && prefix
== NULL
)
228 * Make sure we'll have enough file descriptors to handle a target
229 * that has many many mappings.
231 if (getrlimit(RLIMIT_NOFILE
, &rlim
) == 0) {
232 rlim
.rlim_cur
= rlim
.rlim_max
;
233 (void) setrlimit(RLIMIT_NOFILE
, &rlim
);
234 (void) enable_extended_FILE_stdio(-1, -1);
237 for (i
= 0; i
< argc
; i
++) {
238 P
= proc_arg_grab(argv
[i
], PR_ARG_PIDS
, oflags
, &gerr
);
240 (void) fprintf(stderr
, "%s: cannot grab %s: %s\n",
241 pname
, argv
[i
], Pgrab_error(gerr
));
246 if (prefix
!= NULL
) {
247 (void) snprintf(path
, sizeof (path
), "%s.%%p", prefix
);
248 convert_path(path
, fname
, sizeof (fname
), P
);
250 gcore(P
, fname
, content
, &err
);
254 pid_t pid
= Pstatus(P
)->pr_pid
;
255 (void) core_get_process_path(path
, sizeof (path
), pid
);
256 convert_path(path
, fname
, sizeof (fname
), P
);
258 (void) core_get_process_content(&content
, pid
);
260 gcore(P
, fname
, content
, &err
);
265 * Global core files are always just readable and
266 * writable by their owner so we temporarily change
269 mode_t oldmode
= umask(S_IXUSR
| S_IRWXG
| S_IRWXO
);
271 (void) core_get_global_path(path
, sizeof (path
));
272 convert_path(path
, fname
, sizeof (fname
), P
);
274 (void) core_get_global_content(&content
);
276 gcore(P
, fname
, content
, &err
);
278 (void) umask(oldmode
);
287 (void) fprintf(stderr
, "usage: %s "
288 "[ -pgF ] [ -o filename ] [ -c content ] pid ...\n", pname
);