17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*004388ebScasper * Common Development and Distribution License (the "License"). 6*004388ebScasper * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*004388ebScasper * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #include <stdio.h> 297c478bd9Sstevel@tonic-gate #include <stdlib.h> 307c478bd9Sstevel@tonic-gate #include <strings.h> 317c478bd9Sstevel@tonic-gate #include <sys/mman.h> 327c478bd9Sstevel@tonic-gate #include <fcntl.h> 337c478bd9Sstevel@tonic-gate #include <stdlib.h> 347c478bd9Sstevel@tonic-gate #include <unistd.h> 357c478bd9Sstevel@tonic-gate #include <errno.h> 367c478bd9Sstevel@tonic-gate #include <sys/types.h> 377c478bd9Sstevel@tonic-gate #include <sys/stat.h> 387c478bd9Sstevel@tonic-gate #include <sys/auxv.h> 397c478bd9Sstevel@tonic-gate #include <stdarg.h> 407c478bd9Sstevel@tonic-gate #include <syslog.h> 417c478bd9Sstevel@tonic-gate #include <sys/param.h> 427c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 437c478bd9Sstevel@tonic-gate #include <procfs.h> 447c478bd9Sstevel@tonic-gate #include <libintl.h> 457c478bd9Sstevel@tonic-gate #include <locale.h> 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate extern int gmatch(const char *s, const char *p); 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate #pragma init(__mpssmain) 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate static const char *mpssident = "mpss.so.1"; 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate /* environment variables */ 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate #define ENV_MPSSCFGFILE "MPSSCFGFILE" 567c478bd9Sstevel@tonic-gate #define ENV_MPSSSTACK "MPSSSTACK" 577c478bd9Sstevel@tonic-gate #define ENV_MPSSHEAP "MPSSHEAP" 587c478bd9Sstevel@tonic-gate #define ENV_MPSSERRFILE "MPSSERRFILE" 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate #define MPSSHEAP 0 617c478bd9Sstevel@tonic-gate #define MPSSSTACK 1 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate /* config file */ 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate #define DEF_MPSSCFGFILE "/etc/mpss.conf" 667c478bd9Sstevel@tonic-gate #define MAXLINELEN MAXPATHLEN + 64 677c478bd9Sstevel@tonic-gate #define CFGDELIMITER ':' 687c478bd9Sstevel@tonic-gate #define ARGDELIMITER ' ' 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate /* 717c478bd9Sstevel@tonic-gate * avoid malloc which causes certain applications to crash 727c478bd9Sstevel@tonic-gate */ 737c478bd9Sstevel@tonic-gate static char lbuf[MAXLINELEN]; 747c478bd9Sstevel@tonic-gate static char pbuf[MAXPATHLEN]; 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate #ifdef MPSSDEBUG 777c478bd9Sstevel@tonic-gate #define ENV_MPSSDEBUG "MPSSDEBUG" 787c478bd9Sstevel@tonic-gate #define MPSSPRINT(x, y) if (mpssdebug & x) (void) fprintf y; 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate static int mpssdebug; 817c478bd9Sstevel@tonic-gate #else 827c478bd9Sstevel@tonic-gate #define MPSSPRINT(x, y) 837c478bd9Sstevel@tonic-gate #endif 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 867c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 877c478bd9Sstevel@tonic-gate #endif 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate /*PRINTFLIKE2*/ 907c478bd9Sstevel@tonic-gate static void 917c478bd9Sstevel@tonic-gate mpsserr(FILE *fp, char *fmt, ...) 927c478bd9Sstevel@tonic-gate { 937c478bd9Sstevel@tonic-gate va_list ap; 947c478bd9Sstevel@tonic-gate va_start(ap, fmt); 957c478bd9Sstevel@tonic-gate if (fp) 967c478bd9Sstevel@tonic-gate (void) vfprintf(fp, fmt, ap); 977c478bd9Sstevel@tonic-gate else 987c478bd9Sstevel@tonic-gate vsyslog(LOG_ERR, fmt, ap); 997c478bd9Sstevel@tonic-gate va_end(ap); 1007c478bd9Sstevel@tonic-gate } 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate /* 1037c478bd9Sstevel@tonic-gate * Return the pointer to the fully-resolved path name of the process's 1047c478bd9Sstevel@tonic-gate * executable file obtained from the AT_SUN_EXECNAME aux vector entry. 1057c478bd9Sstevel@tonic-gate */ 1067c478bd9Sstevel@tonic-gate static const char * 1077c478bd9Sstevel@tonic-gate mygetexecname(void) 1087c478bd9Sstevel@tonic-gate { 1097c478bd9Sstevel@tonic-gate const char *execname = NULL; 1107c478bd9Sstevel@tonic-gate static auxv_t auxb; 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate /* 1137c478bd9Sstevel@tonic-gate * The first time through, read the initial aux vector that was 1147c478bd9Sstevel@tonic-gate * passed to the process at exec(2). Only do this once. 1157c478bd9Sstevel@tonic-gate */ 1167c478bd9Sstevel@tonic-gate int fd = open("/proc/self/auxv", O_RDONLY); 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate if (fd >= 0) { 1197c478bd9Sstevel@tonic-gate while (read(fd, &auxb, sizeof (auxv_t)) == sizeof (auxv_t)) { 1207c478bd9Sstevel@tonic-gate if (auxb.a_type == AT_SUN_EXECNAME) { 1217c478bd9Sstevel@tonic-gate execname = auxb.a_un.a_ptr; 1227c478bd9Sstevel@tonic-gate break; 1237c478bd9Sstevel@tonic-gate } 1247c478bd9Sstevel@tonic-gate } 1257c478bd9Sstevel@tonic-gate (void) close(fd); 1267c478bd9Sstevel@tonic-gate } 1277c478bd9Sstevel@tonic-gate return (execname); 1287c478bd9Sstevel@tonic-gate } 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate static size_t 1317c478bd9Sstevel@tonic-gate atosz(char *szstr) 1327c478bd9Sstevel@tonic-gate { 1337c478bd9Sstevel@tonic-gate size_t sz; 1347c478bd9Sstevel@tonic-gate char *endptr, c; 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate sz = strtoll(szstr, &endptr, 0); 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate while (c = *endptr++) { 1397c478bd9Sstevel@tonic-gate switch (c) { 1407c478bd9Sstevel@tonic-gate case 't': 1417c478bd9Sstevel@tonic-gate case 'T': 1427c478bd9Sstevel@tonic-gate sz *= 1024; 1437c478bd9Sstevel@tonic-gate /*FALLTHRU*/ 1447c478bd9Sstevel@tonic-gate case 'g': 1457c478bd9Sstevel@tonic-gate case 'G': 1467c478bd9Sstevel@tonic-gate sz *= 1024; 1477c478bd9Sstevel@tonic-gate /*FALLTHRU*/ 1487c478bd9Sstevel@tonic-gate case 'm': 1497c478bd9Sstevel@tonic-gate case 'M': 1507c478bd9Sstevel@tonic-gate sz *= 1024; 1517c478bd9Sstevel@tonic-gate /*FALLTHRU*/ 1527c478bd9Sstevel@tonic-gate case 'k': 1537c478bd9Sstevel@tonic-gate case 'K': 1547c478bd9Sstevel@tonic-gate sz *= 1024; 1557c478bd9Sstevel@tonic-gate default: 1567c478bd9Sstevel@tonic-gate break; 1577c478bd9Sstevel@tonic-gate } 1587c478bd9Sstevel@tonic-gate } 1597c478bd9Sstevel@tonic-gate return (sz); 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate #define PGSZELEM (8 * sizeof (void *)) 1647c478bd9Sstevel@tonic-gate static size_t pgsz[PGSZELEM]; 1657c478bd9Sstevel@tonic-gate static int nelem; 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate static int 1687c478bd9Sstevel@tonic-gate pgszok(size_t sz) 1697c478bd9Sstevel@tonic-gate { 1707c478bd9Sstevel@tonic-gate int i; 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate if (sz == 0) 1737c478bd9Sstevel@tonic-gate return (1); 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate for (i = 0; i < nelem; i++) { 1767c478bd9Sstevel@tonic-gate if (sz == pgsz[i]) 1777c478bd9Sstevel@tonic-gate break; 1787c478bd9Sstevel@tonic-gate } 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate return (i < nelem); 1817c478bd9Sstevel@tonic-gate } 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate static void 1847c478bd9Sstevel@tonic-gate pgszinit() 1857c478bd9Sstevel@tonic-gate { 1867c478bd9Sstevel@tonic-gate nelem = getpagesizes(NULL, 0); 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate if (!nelem) 1897c478bd9Sstevel@tonic-gate return; 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate if (nelem > PGSZELEM) 1927c478bd9Sstevel@tonic-gate nelem = PGSZELEM; 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate (void) getpagesizes(pgsz, nelem); 1957c478bd9Sstevel@tonic-gate #ifdef MPSSDEBUG 1967c478bd9Sstevel@tonic-gate pgsz[nelem] = 0x800000; 1977c478bd9Sstevel@tonic-gate nelem++; 1987c478bd9Sstevel@tonic-gate #endif 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate static int 2037c478bd9Sstevel@tonic-gate pgszset(size_t sz, uint_t flags) 2047c478bd9Sstevel@tonic-gate { 2057c478bd9Sstevel@tonic-gate struct memcntl_mha mpss; 2067c478bd9Sstevel@tonic-gate int rc; 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate mpss.mha_cmd = (flags == MPSSHEAP) ? 2097c478bd9Sstevel@tonic-gate MHA_MAPSIZE_BSSBRK: MHA_MAPSIZE_STACK; 2107c478bd9Sstevel@tonic-gate mpss.mha_pagesize = sz; 2117c478bd9Sstevel@tonic-gate mpss.mha_flags = 0; 2127c478bd9Sstevel@tonic-gate rc = memcntl(NULL, 0, MC_HAT_ADVISE, (caddr_t)&mpss, 0, 0); 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate return (rc); 2157c478bd9Sstevel@tonic-gate } 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate /* 2187c478bd9Sstevel@tonic-gate * check if exec name matches cfgname found in mpss cfg file. 2197c478bd9Sstevel@tonic-gate */ 2207c478bd9Sstevel@tonic-gate static int 2217c478bd9Sstevel@tonic-gate fnmatch(const char *execname, char *cfgname, char *cwd) 2227c478bd9Sstevel@tonic-gate { 2237c478bd9Sstevel@tonic-gate const char *ename; 2247c478bd9Sstevel@tonic-gate int rc; 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate /* cfgname should not have a '/' unless it begins with one */ 2277c478bd9Sstevel@tonic-gate if (cfgname[0] == '/') { 2287c478bd9Sstevel@tonic-gate /* 2297c478bd9Sstevel@tonic-gate * if execname does not begin with a '/', prepend the 2307c478bd9Sstevel@tonic-gate * current directory. 2317c478bd9Sstevel@tonic-gate */ 2327c478bd9Sstevel@tonic-gate if (execname[0] != '/') { 2337c478bd9Sstevel@tonic-gate ename = (const char *)strcat(cwd, execname); 2347c478bd9Sstevel@tonic-gate } else 2357c478bd9Sstevel@tonic-gate ename = execname; 2367c478bd9Sstevel@tonic-gate } else { /* simple cfg name */ 2377c478bd9Sstevel@tonic-gate if (ename = strrchr(execname, '/')) 2387c478bd9Sstevel@tonic-gate /* execname is a path name - get the base name */ 2397c478bd9Sstevel@tonic-gate ename++; 2407c478bd9Sstevel@tonic-gate else 2417c478bd9Sstevel@tonic-gate ename = execname; 2427c478bd9Sstevel@tonic-gate } 2437c478bd9Sstevel@tonic-gate rc = gmatch(ename, cfgname); 2447c478bd9Sstevel@tonic-gate MPSSPRINT(2, (stderr, "gmatch: %s %s %s %d\n", 2457c478bd9Sstevel@tonic-gate cfgname, ename, execname, rc)); 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate return (rc); 2487c478bd9Sstevel@tonic-gate } 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate /* 2517c478bd9Sstevel@tonic-gate * Check if string matches any of exec arguments. 2527c478bd9Sstevel@tonic-gate */ 2537c478bd9Sstevel@tonic-gate static int 2547c478bd9Sstevel@tonic-gate argmatch(char *str, FILE *errfp) 2557c478bd9Sstevel@tonic-gate { 2567c478bd9Sstevel@tonic-gate int fd; 2577c478bd9Sstevel@tonic-gate psinfo_t pi; 2587c478bd9Sstevel@tonic-gate int rc = 0; 2597c478bd9Sstevel@tonic-gate int arg; 2607c478bd9Sstevel@tonic-gate char **argv; 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate fd = open("/proc/self/psinfo", O_RDONLY); 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate if (fd >= 0) { 2657c478bd9Sstevel@tonic-gate if (read(fd, &pi, sizeof (pi)) == sizeof (pi)) { 2667c478bd9Sstevel@tonic-gate argv = (char **)pi.pr_argv; 2677c478bd9Sstevel@tonic-gate argv++; 2687c478bd9Sstevel@tonic-gate MPSSPRINT(2, (stderr, "argmatch: %s ", str)); 2697c478bd9Sstevel@tonic-gate for (arg = 1; arg < pi.pr_argc; arg++, argv++) { 2707c478bd9Sstevel@tonic-gate if (rc = gmatch(*argv, str)) { 2717c478bd9Sstevel@tonic-gate MPSSPRINT(2, (stderr, "%s ", *argv)); 2727c478bd9Sstevel@tonic-gate break; 2737c478bd9Sstevel@tonic-gate } 2747c478bd9Sstevel@tonic-gate } 2757c478bd9Sstevel@tonic-gate MPSSPRINT(2, (stderr, "%d\n", rc)); 2767c478bd9Sstevel@tonic-gate } else { 2777c478bd9Sstevel@tonic-gate mpsserr(errfp, dgettext(TEXT_DOMAIN, 2787c478bd9Sstevel@tonic-gate "%s: /proc/self/psinfo read failed [%s]\n"), 2797c478bd9Sstevel@tonic-gate mpssident, strerror(errno)); 2807c478bd9Sstevel@tonic-gate } 2817c478bd9Sstevel@tonic-gate (void) close(fd); 2827c478bd9Sstevel@tonic-gate } else { 2837c478bd9Sstevel@tonic-gate mpsserr(errfp, dgettext(TEXT_DOMAIN, 2847c478bd9Sstevel@tonic-gate "%s: /proc/self/psinfo open failed [%s]\n"), 2857c478bd9Sstevel@tonic-gate mpssident, strerror(errno)); 2867c478bd9Sstevel@tonic-gate } 2877c478bd9Sstevel@tonic-gate return (rc); 2887c478bd9Sstevel@tonic-gate } 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate static int 2917c478bd9Sstevel@tonic-gate empty(char *str) 2927c478bd9Sstevel@tonic-gate { 2937c478bd9Sstevel@tonic-gate char c; 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate while ((c = *str) == '\n' || c == ' ' || c == '\t') 2967c478bd9Sstevel@tonic-gate str++; 2977c478bd9Sstevel@tonic-gate return (*str == '\0'); 2987c478bd9Sstevel@tonic-gate } 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate void 3017c478bd9Sstevel@tonic-gate __mpssmain() 3027c478bd9Sstevel@tonic-gate { 3037c478bd9Sstevel@tonic-gate static size_t heapsz = (size_t)-1, stacksz = (size_t)-1, sz; 3047c478bd9Sstevel@tonic-gate char *cfgfile, *errfile; 3057c478bd9Sstevel@tonic-gate const char *execname; 3067c478bd9Sstevel@tonic-gate char *cwd; 3077c478bd9Sstevel@tonic-gate int cwdlen; 3087c478bd9Sstevel@tonic-gate FILE *fp = NULL, *errfp = NULL; 3097c478bd9Sstevel@tonic-gate char *tok, *tokheap = NULL, *tokstack = NULL, *tokarg; 3107c478bd9Sstevel@tonic-gate char *str, *envheap, *envstack; 3117c478bd9Sstevel@tonic-gate int lineno = 0; 3127c478bd9Sstevel@tonic-gate char *locale; 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate /* 3157c478bd9Sstevel@tonic-gate * If a private error file is indicated then set the locale 3167c478bd9Sstevel@tonic-gate * for error messages for the duration of this routine. 3177c478bd9Sstevel@tonic-gate * Error messages destined for syslog should not be translated 3187c478bd9Sstevel@tonic-gate * and thus come from the default C locale. 3197c478bd9Sstevel@tonic-gate */ 3207c478bd9Sstevel@tonic-gate if ((errfile = getenv(ENV_MPSSERRFILE)) != NULL) { 321*004388ebScasper errfp = fopen(errfile, "aF"); 3227c478bd9Sstevel@tonic-gate if (errfp) { 3237c478bd9Sstevel@tonic-gate locale = setlocale(LC_MESSAGES, ""); 3247c478bd9Sstevel@tonic-gate } else { 3257c478bd9Sstevel@tonic-gate mpsserr(NULL, dgettext(TEXT_DOMAIN, 3267c478bd9Sstevel@tonic-gate "%s: cannot open error file: %s [%s]\n"), 3277c478bd9Sstevel@tonic-gate mpssident, errfile, strerror(errno)); 3287c478bd9Sstevel@tonic-gate } 3297c478bd9Sstevel@tonic-gate } 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate #ifdef MPSSDEBUG 3327c478bd9Sstevel@tonic-gate if (str = getenv(ENV_MPSSDEBUG)) 3337c478bd9Sstevel@tonic-gate mpssdebug = atosz(str); 3347c478bd9Sstevel@tonic-gate #endif 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate pgszinit(); 3377c478bd9Sstevel@tonic-gate 3387c478bd9Sstevel@tonic-gate if (envstack = getenv(ENV_MPSSSTACK)) { 3397c478bd9Sstevel@tonic-gate sz = atosz(envstack); 3407c478bd9Sstevel@tonic-gate if (pgszok(sz)) 3417c478bd9Sstevel@tonic-gate stacksz = sz; 3427c478bd9Sstevel@tonic-gate else 3437c478bd9Sstevel@tonic-gate mpsserr(errfp, dgettext(TEXT_DOMAIN, 3447c478bd9Sstevel@tonic-gate "%s: invalid stack page size specified:" 3457c478bd9Sstevel@tonic-gate " MPSSSTACK=%s\n"), 3467c478bd9Sstevel@tonic-gate mpssident, envstack); 3477c478bd9Sstevel@tonic-gate } 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate if (envheap = getenv(ENV_MPSSHEAP)) { 3507c478bd9Sstevel@tonic-gate sz = atosz(envheap); 3517c478bd9Sstevel@tonic-gate if (pgszok(sz)) 3527c478bd9Sstevel@tonic-gate heapsz = sz; 3537c478bd9Sstevel@tonic-gate else 3547c478bd9Sstevel@tonic-gate mpsserr(errfp, dgettext(TEXT_DOMAIN, 3557c478bd9Sstevel@tonic-gate "%s: invalid heap page size specified:" 3567c478bd9Sstevel@tonic-gate " MPSSHEAP=%s\n"), 3577c478bd9Sstevel@tonic-gate mpssident, envheap); 3587c478bd9Sstevel@tonic-gate } 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate /* 3617c478bd9Sstevel@tonic-gate * Open specified cfg file or default one. 3627c478bd9Sstevel@tonic-gate */ 3637c478bd9Sstevel@tonic-gate if (cfgfile = getenv(ENV_MPSSCFGFILE)) { 364*004388ebScasper fp = fopen(cfgfile, "rF"); 3657c478bd9Sstevel@tonic-gate if (!fp) { 3667c478bd9Sstevel@tonic-gate mpsserr(errfp, dgettext(TEXT_DOMAIN, 3677c478bd9Sstevel@tonic-gate "%s: cannot open configuration file: %s [%s]\n"), 3687c478bd9Sstevel@tonic-gate mpssident, cfgfile, strerror(errno)); 3697c478bd9Sstevel@tonic-gate } 3707c478bd9Sstevel@tonic-gate } else { 3717c478bd9Sstevel@tonic-gate cfgfile = DEF_MPSSCFGFILE; 372*004388ebScasper fp = fopen(cfgfile, "rF"); 3737c478bd9Sstevel@tonic-gate } 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate execname = mygetexecname(); 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate if (fp) { 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate cwd = getcwd(pbuf, MAXPATHLEN); 3807c478bd9Sstevel@tonic-gate if (!cwd) 3817c478bd9Sstevel@tonic-gate return; 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate cwd = strcat(cwd, "/"); 3847c478bd9Sstevel@tonic-gate cwdlen = strlen(cwd); 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate while (fgets(lbuf, MAXLINELEN, fp)) { 3877c478bd9Sstevel@tonic-gate lineno++; 3887c478bd9Sstevel@tonic-gate if (empty(lbuf)) 3897c478bd9Sstevel@tonic-gate continue; 3907c478bd9Sstevel@tonic-gate /* 3917c478bd9Sstevel@tonic-gate * Make sure line wasn't truncated. 3927c478bd9Sstevel@tonic-gate */ 3937c478bd9Sstevel@tonic-gate if (strlen(lbuf) >= MAXLINELEN - 1) { 3947c478bd9Sstevel@tonic-gate mpsserr(errfp, dgettext(TEXT_DOMAIN, 3957c478bd9Sstevel@tonic-gate "%s: invalid entry, " 3967c478bd9Sstevel@tonic-gate "line too long - cfgfile:" 3977c478bd9Sstevel@tonic-gate " %s, line: %d\n"), 3987c478bd9Sstevel@tonic-gate mpssident, cfgfile, lineno); 3997c478bd9Sstevel@tonic-gate continue; 4007c478bd9Sstevel@tonic-gate } 4017c478bd9Sstevel@tonic-gate /* 4027c478bd9Sstevel@tonic-gate * parse right to left in case delimiter is 4037c478bd9Sstevel@tonic-gate * in name. 4047c478bd9Sstevel@tonic-gate */ 4057c478bd9Sstevel@tonic-gate if (!(tokstack = strrchr(lbuf, CFGDELIMITER))) { 4067c478bd9Sstevel@tonic-gate mpsserr(errfp, dgettext(TEXT_DOMAIN, 4077c478bd9Sstevel@tonic-gate "%s: no delimiters specified - cfgfile:" 4087c478bd9Sstevel@tonic-gate " %s, line: %d\n"), 4097c478bd9Sstevel@tonic-gate mpssident, cfgfile, lineno); 4107c478bd9Sstevel@tonic-gate continue; 4117c478bd9Sstevel@tonic-gate } 4127c478bd9Sstevel@tonic-gate /* found delimiter in lbuf */ 4137c478bd9Sstevel@tonic-gate *tokstack++ = '\0'; 4147c478bd9Sstevel@tonic-gate /* remove for error message */ 4157c478bd9Sstevel@tonic-gate if (str = strrchr(tokstack, '\n')) 4167c478bd9Sstevel@tonic-gate *str = '\0'; 4177c478bd9Sstevel@tonic-gate if (!(tokheap = strrchr(lbuf, CFGDELIMITER))) { 4187c478bd9Sstevel@tonic-gate mpsserr(errfp, dgettext(TEXT_DOMAIN, 4197c478bd9Sstevel@tonic-gate "%s: invalid entry, " 4207c478bd9Sstevel@tonic-gate "missing delimiter - cfgfile: %s," 4217c478bd9Sstevel@tonic-gate " line: %d\n"), 4227c478bd9Sstevel@tonic-gate mpssident, cfgfile, lineno); 4237c478bd9Sstevel@tonic-gate continue; 4247c478bd9Sstevel@tonic-gate } 4257c478bd9Sstevel@tonic-gate *tokheap++ = '\0'; 4267c478bd9Sstevel@tonic-gate 4277c478bd9Sstevel@tonic-gate /* exec-args is optional */ 4287c478bd9Sstevel@tonic-gate if (tokarg = strrchr(lbuf, ARGDELIMITER)) { 4297c478bd9Sstevel@tonic-gate *tokarg++ = '\0'; 4307c478bd9Sstevel@tonic-gate } 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate tok = lbuf; 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate if (!fnmatch(execname, tok, cwd)) { 4357c478bd9Sstevel@tonic-gate tokheap = tokstack = tokarg = NULL; 4367c478bd9Sstevel@tonic-gate cwd[cwdlen] = '\0'; 4377c478bd9Sstevel@tonic-gate continue; 4387c478bd9Sstevel@tonic-gate } 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate if (tokarg && 4417c478bd9Sstevel@tonic-gate !empty(tokarg) && 4427c478bd9Sstevel@tonic-gate !argmatch(tokarg, errfp)) { 4437c478bd9Sstevel@tonic-gate tokheap = tokstack = tokarg = NULL; 4447c478bd9Sstevel@tonic-gate cwd[cwdlen] = '\0'; 4457c478bd9Sstevel@tonic-gate continue; 4467c478bd9Sstevel@tonic-gate } 4477c478bd9Sstevel@tonic-gate 4487c478bd9Sstevel@tonic-gate /* heap token */ 4497c478bd9Sstevel@tonic-gate if (empty(tokheap)) { 4507c478bd9Sstevel@tonic-gate /* empty cfg entry */ 4517c478bd9Sstevel@tonic-gate heapsz = (size_t)-1; 4527c478bd9Sstevel@tonic-gate } else { 4537c478bd9Sstevel@tonic-gate sz = atosz(tokheap); 4547c478bd9Sstevel@tonic-gate if (pgszok(sz)) 4557c478bd9Sstevel@tonic-gate heapsz = sz; 4567c478bd9Sstevel@tonic-gate else { 4577c478bd9Sstevel@tonic-gate mpsserr(errfp, dgettext(TEXT_DOMAIN, 4587c478bd9Sstevel@tonic-gate "%s: invalid heap page size" 4597c478bd9Sstevel@tonic-gate " specified (%s) for %s - " 4607c478bd9Sstevel@tonic-gate "cfgfile: %s, line: %d\n"), 4617c478bd9Sstevel@tonic-gate mpssident, tokheap, 4627c478bd9Sstevel@tonic-gate execname, cfgfile, 4637c478bd9Sstevel@tonic-gate lineno); 4647c478bd9Sstevel@tonic-gate heapsz = (size_t)-1; 4657c478bd9Sstevel@tonic-gate } 4667c478bd9Sstevel@tonic-gate } 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate /* stack token */ 4697c478bd9Sstevel@tonic-gate if (empty(tokstack)) { 4707c478bd9Sstevel@tonic-gate stacksz = (size_t)-1; 4717c478bd9Sstevel@tonic-gate break; 4727c478bd9Sstevel@tonic-gate } else { 4737c478bd9Sstevel@tonic-gate sz = atosz(tokstack); 4747c478bd9Sstevel@tonic-gate if (pgszok(sz)) 4757c478bd9Sstevel@tonic-gate stacksz = sz; 4767c478bd9Sstevel@tonic-gate else { 4777c478bd9Sstevel@tonic-gate mpsserr(errfp, dgettext(TEXT_DOMAIN, 4787c478bd9Sstevel@tonic-gate "%s: invalid stack page size" 4797c478bd9Sstevel@tonic-gate " specified (%s) for %s - " 4807c478bd9Sstevel@tonic-gate "cfgfile: %s, line: %d\n"), 4817c478bd9Sstevel@tonic-gate mpssident, tokstack, 4827c478bd9Sstevel@tonic-gate execname, cfgfile, lineno); 4837c478bd9Sstevel@tonic-gate stacksz = (size_t)-1; 4847c478bd9Sstevel@tonic-gate } 4857c478bd9Sstevel@tonic-gate } 4867c478bd9Sstevel@tonic-gate break; 4877c478bd9Sstevel@tonic-gate } 4887c478bd9Sstevel@tonic-gate (void) fclose(fp); 4897c478bd9Sstevel@tonic-gate } 4907c478bd9Sstevel@tonic-gate 4917c478bd9Sstevel@tonic-gate if ((heapsz != (size_t)-1) && (pgszset(heapsz, MPSSHEAP) < 0)) 4927c478bd9Sstevel@tonic-gate mpsserr(errfp, dgettext(TEXT_DOMAIN, 4937c478bd9Sstevel@tonic-gate "%s: memcntl() failed [%s]: heap page size (%s)" 4947c478bd9Sstevel@tonic-gate " for %s not set\n"), 4957c478bd9Sstevel@tonic-gate mpssident, strerror(errno), (tokheap) ? tokheap : envheap, 4967c478bd9Sstevel@tonic-gate execname); 4977c478bd9Sstevel@tonic-gate if ((stacksz != (size_t)-1) && (pgszset(stacksz, MPSSSTACK) < 0)) 4987c478bd9Sstevel@tonic-gate mpsserr(errfp, dgettext(TEXT_DOMAIN, 4997c478bd9Sstevel@tonic-gate "%s: memcntl() failed [%s]: stack page size (%s)" 5007c478bd9Sstevel@tonic-gate " for %s not set\n"), 5017c478bd9Sstevel@tonic-gate mpssident, strerror(errno), (tokstack) ? tokstack: envstack, 5027c478bd9Sstevel@tonic-gate execname); 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate if (errfp) { 5057c478bd9Sstevel@tonic-gate (void) fclose(errfp); 5067c478bd9Sstevel@tonic-gate (void) setlocale(LC_MESSAGES, locale); 5077c478bd9Sstevel@tonic-gate } else { 5087c478bd9Sstevel@tonic-gate /* close log file: no-op if nothing logged to syslog */ 5097c478bd9Sstevel@tonic-gate closelog(); 5107c478bd9Sstevel@tonic-gate } 5117c478bd9Sstevel@tonic-gate } 512