/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <signal.h>
#include <stropts.h>
#include <errno.h>
#include <libproc.h>
#include "ramdata.h"
#include "proto.h"
/*
* Routines related to interprocess communication
* among the truss processes which are controlling
* multiple traced processes.
*/
/*
* Function prototypes for static routines in this module.
*/
void Ecritical(int);
void Xcritical(int);
/*
* Ensure everyone keeps out of each other's way
* while writing lines of trace output.
*/
void
Flush()
{
/*
* Except for regions bounded by Eserialize()/Xserialize(),
* this is the only place anywhere in the program where a
* write() to the trace output file takes place, so here
* is where we detect errors writing to the output.
*/
errno = 0;
Ecritical(0);
Xcritical(0);
}
/*
* Eserialize() and Xserialize() are used to bracket
* a region which may produce large amounts of output,
* such as showargs()/dumpargs().
*/
void
{
/* serialize output */
Ecritical(0);
}
void
{
Xcritical(0);
}
/*
* Enter critical region --- Wait on mutex, lock out other processes.
* Lock zero is used to serialize output in situations where multiple processes
* are in expound.c
* Lock one is used to protect the table of processes currently being traced
* every time a pid is added or removed from the table Ecritical(1)/Xcritical(1)
* get called.
*/
void
{
int rv;
if (num == 0)
else if (num == 1)
else
if (rv != 0) {
}
}
/*
* Exit critical region ---
* Release other processes waiting on mutex.
*/
void
{
int rv;
if (num == 0)
else if (num == 1)
else
if (rv != 0) {
}
}
/*
* Add process to set of those being traced.
*/
void
{
int i;
int j = -1;
return;
Ecritical(1);
if (j == -1) /* remember first vacant slot */
j = i;
break;
}
}
j = i;
if (j >= 0) {
}
Xcritical(1);
}
/*
* Delete process from set of those being traced.
*/
void
procdel()
{
int i;
return;
Ecritical(1);
break;
}
}
Xcritical(1);
}
/*
* Determine if the lwp for this process should be traced.
*/
int
{
int i;
const char *lwps;
return (0);
Ecritical(1);
break;
}
Xcritical(1);
}
/*
* Return 0 if this is not an open of a /proc file.
* Return 1 if the process opened itself.
* Return 2 if the process failed to open another process
* in truss's set of controlled processes.
* Return 3 if the process successfully opened another process
* in truss's set of controlled processes.
* We notify and wait for the other controlling truss process
* to terminate before returning in cases 2 and 3.
*/
/* ARGSUSED */
int
{
int pid;
int i;
const char *dirname;
char *next;
char *sp1;
char *sp2;
/*
* A bit heuristic ...
* Test for the cases:
* 1234
* 1234/as
* 1234/ctl
* 1234/lwp/24/lwpctl
* .../1234
* .../1234/as
* .../1234/ctl
* .../1234/lwp/24/lwpctl
* Insert a '\0', if necessary, so the path becomes ".../1234".
*
*/
/* EMPTY */;
;
if (*sp1 != '/')
return (0);
*sp1 = '\0';
/*
* .../1234/lwp/24/lwpctl
* ............ ^-- sp1
*/
sp1 -= 6;
else {
;
}
if (*sp1 != '/' ||
return (0);
*sp1 = '\0';
return (0);
}
else
*sp1 = '/';
return (0);
}
dirname = ".";
else {
*sp2 = '\0';
}
pid == 0) { /* process opened process 0 */
*sp1 = '/';
*sp2 = '/';
return (0);
}
*sp1 = '/';
*sp2 = '/';
/*
* Process did open a /proc file ---
*/
/*
* In SunOS 5.6 and beyond, self-opens always succeed.
*/
return (1);
}
/*
* Search for a matching pid in our set of controlled processes.
*/
break;
}
}
/*
* The process opened a /proc file, but not one we care about.
*/
return (0);
}
/*
* Notify and wait for the controlling process to terminate.
*/
break;
(void) usleep(1000000);
}
Ecritical(1);
Xcritical(1);
if (err) { /* prepare to reissue the failed open() system call */
#if defined(__sparc)
if (pri->sys_indirect) {
for (i = 0; i < 5; i++)
} else {
for (i = 0; i < 6; i++)
}
#else
#error "unrecognized architecture"
#endif
return (2);
}
return (3);
}