start making thread-safe

This commit is contained in:
Doug MacEachern 2005-03-11 21:20:30 +00:00
parent 94f842e473
commit 6d2f12c6b9
2 changed files with 81 additions and 76 deletions

View File

@ -47,18 +47,6 @@ static char copyright[] =
#include <stropts.h> #include <stropts.h>
#include <unistd.h> #include <unistd.h>
/*
* Local static values
*/
static char *Db = NULL; /* data buffer */
static int Dbl = 0; /* data buffer length */
static char *Smb = NULL; /* stream message buffer */
static size_t Smbl = 0; /* size of Smb[] */
static int Sd = -1; /* stream device descriptor; not open
* if -1 */
static char ErrMsg[GET_MIB2_ERRMSGL]; /* error message buffer */
/* /*
* close_mib2() - close MIB2 access * close_mib2() - close MIB2 access
* *
@ -70,27 +58,27 @@ static char ErrMsg[GET_MIB2_ERRMSGL]; /* error message buffer */
*/ */
int int
close_mib2(char **errmsg) close_mib2(solaris_mib2_t *mib2, char **errmsg)
{ {
*errmsg = ErrMsg; *errmsg = mib2->errmsg;
if (Sd < 0) { if (mib2->sd < 0) {
(void) strcpy(ErrMsg, "close_mib2: socket not open"); (void) strcpy(mib2->errmsg, "close_mib2: socket not open");
return(GET_MIB2_ERR_NOTOPEN); return(GET_MIB2_ERR_NOTOPEN);
} }
if (close(Sd)) { if (close(mib2->sd)) {
(void) sprintf(ErrMsg, "close_mib2: %s", strerror(errno)); (void) sprintf(mib2->errmsg, "close_mib2: %s", strerror(errno));
return(GET_MIB2_ERR_CLOSE); return(GET_MIB2_ERR_CLOSE);
} }
Sd = -1; mib2->sd = -1;
if (Dbl && Db) { if (mib2->db_len && mib2->db) {
Dbl = 0; mib2->db_len = 0;
free((void *)Db); free((void *)mib2->db);
Db = NULL; mib2->db = NULL;
} }
if (Smbl && Smb) { if (mib2->smb_len && mib2->smb) {
Smbl = 0; mib2->smb_len = 0;
free((void *)Smb); free((void *)mib2->smb);
Smb = NULL; mib2->smb = NULL;
} }
return(GET_MIB2_OK); return(GET_MIB2_OK);
} }
@ -110,7 +98,8 @@ close_mib2(char **errmsg)
*/ */
int int
get_mib2(struct opthdr **opt, get_mib2(solaris_mib2_t *mib2,
struct opthdr **opt,
char **data, char **data,
int *datalen, int *datalen,
char **errmsg) char **errmsg)
@ -125,24 +114,24 @@ get_mib2(struct opthdr **opt,
static struct T_optmgmt_req *r; /* message request pointer */ static struct T_optmgmt_req *r; /* message request pointer */
int rc; /* reply code */ int rc; /* reply code */
*errmsg = ErrMsg; *errmsg = mib2->errmsg;
/* /*
* If MIB2 access isn't open, open it and issue the preliminary stream * If MIB2 access isn't open, open it and issue the preliminary stream
* messages. * messages.
*/ */
if (Sd < 0) { if (mib2->sd < 0) {
/* /*
* Open access. Return on error. * Open access. Return on error.
*/ */
if ((err = open_mib2(errmsg))) { if ((err = open_mib2(mib2, errmsg))) {
return(err); return(err);
} }
/* /*
* Set up message request and option. * Set up message request and option.
*/ */
r = (struct T_optmgmt_req *)Smb; r = (struct T_optmgmt_req *)mib2->smb;
o = (struct opthdr *)&Smb[sizeof(struct T_optmgmt_req)]; o = (struct opthdr *)&mib2->smb[sizeof(struct T_optmgmt_req)];
r->PRIM_type = T_OPTMGMT_REQ; r->PRIM_type = T_OPTMGMT_REQ;
r->OPT_offset = sizeof(struct T_optmgmt_req); r->OPT_offset = sizeof(struct T_optmgmt_req);
r->OPT_length = sizeof(struct opthdr); r->OPT_length = sizeof(struct opthdr);
@ -159,30 +148,30 @@ get_mib2(struct opthdr **opt,
o->level = MIB2_IP; o->level = MIB2_IP;
o->name = o->len = 0; o->name = o->len = 0;
c.buf = Smb; c.buf = mib2->smb;
c.len = r->OPT_offset + r->OPT_length; c.len = r->OPT_offset + r->OPT_length;
/* /*
* Put the message. * Put the message.
*/ */
if (putmsg(Sd, &c, (struct strbuf *)NULL, 0) == -1) { if (putmsg(mib2->sd, &c, (struct strbuf *)NULL, 0) == -1) {
(void) sprintf(ErrMsg, (void) sprintf(mib2->errmsg,
"get_mib2: putmsg request: %s", strerror(errno)); "get_mib2: putmsg request: %s", strerror(errno));
return(GET_MIB2_ERR_PUTMSG); return(GET_MIB2_ERR_PUTMSG);
} }
/* /*
* Set up to process replies. * Set up to process replies.
*/ */
a = (struct T_optmgmt_ack *)Smb; a = (struct T_optmgmt_ack *)mib2->smb;
c.maxlen = Smbl; c.maxlen = mib2->smb_len;
e = (struct T_error_ack *)Smb; e = (struct T_error_ack *)mib2->smb;
o = (struct opthdr *)&Smb[sizeof(struct T_optmgmt_ack)]; o = (struct opthdr *)&mib2->smb[sizeof(struct T_optmgmt_ack)];
} }
/* /*
* Get the next (first) reply message. * Get the next (first) reply message.
*/ */
f = 0; f = 0;
if ((rc = getmsg(Sd, &c, NULL, &f)) < 0) { if ((rc = getmsg(mib2->sd, &c, NULL, &f)) < 0) {
(void) sprintf(ErrMsg, "get_mib2: getmsg(reply): %s", (void) sprintf(mib2->errmsg, "get_mib2: getmsg(reply): %s",
strerror(errno)); strerror(errno));
return(GET_MIB2_ERR_GETMSGR); return(GET_MIB2_ERR_GETMSGR);
} }
@ -195,7 +184,7 @@ get_mib2(struct opthdr **opt,
&& a->MGMT_flags == T_SUCCESS && a->MGMT_flags == T_SUCCESS
&& o->len == 0) && o->len == 0)
{ {
err = close_mib2(errmsg); err = close_mib2(mib2, errmsg);
if (err) { if (err) {
return(err); return(err);
} }
@ -207,7 +196,7 @@ get_mib2(struct opthdr **opt,
if (c.len >= sizeof(struct T_error_ack) if (c.len >= sizeof(struct T_error_ack)
&& e->PRIM_type == T_ERROR_ACK) && e->PRIM_type == T_ERROR_ACK)
{ {
(void) sprintf(ErrMsg, (void) sprintf(mib2->errmsg,
"get_mib2: T_ERROR_ACK: len=%d, TLI=%#x, UNIX=%#x", "get_mib2: T_ERROR_ACK: len=%d, TLI=%#x, UNIX=%#x",
c.len, (int)e->TLI_error, (int)e->UNIX_error); c.len, (int)e->TLI_error, (int)e->UNIX_error);
return(GET_MIB2_ERR_ACK); return(GET_MIB2_ERR_ACK);
@ -220,7 +209,7 @@ get_mib2(struct opthdr **opt,
|| a->PRIM_type != T_OPTMGMT_ACK || a->PRIM_type != T_OPTMGMT_ACK
|| a->MGMT_flags != T_SUCCESS) || a->MGMT_flags != T_SUCCESS)
{ {
(void) sprintf(ErrMsg, (void) sprintf(mib2->errmsg,
"get_mib2: T_OPTMGMT_ACK: " "get_mib2: T_OPTMGMT_ACK: "
"rc=%d len=%d type=%#x flags=%#x", "rc=%d len=%d type=%#x flags=%#x",
rc, c.len, (int)a->PRIM_type, (int)a->MGMT_flags); rc, c.len, (int)a->PRIM_type, (int)a->MGMT_flags);
@ -229,17 +218,18 @@ get_mib2(struct opthdr **opt,
/* /*
* Allocate (or enlarge) the data buffer. * Allocate (or enlarge) the data buffer.
*/ */
if (o->len >= Dbl) { if (o->len >= mib2->db_len) {
Dbl = o->len; mib2->db_len = o->len;
if (Db == NULL) { if (mib2->db == NULL) {
Db = (char *)malloc(Dbl); mib2->db = (char *)malloc(mib2->db_len);
} }
else { else {
Db = (char *)realloc(Db, Dbl); mib2->db = (char *)realloc(mib2->db, mib2->db_len);
} }
if (Db == NULL) { if (mib2->db == NULL) {
(void) sprintf(ErrMsg, (void) sprintf(mib2->errmsg,
"get_mib2: no space for %d byte data buffer", Dbl); "get_mib2: no space for %d byte data buffer",
mib2->db_len);
return(GET_MIB2_ERR_NOSPC); return(GET_MIB2_ERR_NOSPC);
} }
} }
@ -247,16 +237,16 @@ get_mib2(struct opthdr **opt,
* Get the data part of the message -- the MIB2 part. * Get the data part of the message -- the MIB2 part.
*/ */
d.maxlen = o->len; d.maxlen = o->len;
d.buf = Db; d.buf = mib2->db;
d.len = 0; d.len = 0;
f = 0; f = 0;
if ((rc = getmsg(Sd, NULL, &d, &f)) < 0) { if ((rc = getmsg(mib2->sd, NULL, &d, &f)) < 0) {
(void) sprintf(ErrMsg, "get_mib2: getmsg(data): %s", (void) sprintf(mib2->errmsg, "get_mib2: getmsg(data): %s",
strerror(errno)); strerror(errno));
return(GET_MIB2_ERR_GETMSGD); return(GET_MIB2_ERR_GETMSGD);
} }
if (rc) { if (rc) {
(void) sprintf(ErrMsg, (void) sprintf(mib2->errmsg,
"get_mib2: getmsg(data): rc=%d maxlen=%d len=%d: %s", "get_mib2: getmsg(data): rc=%d maxlen=%d len=%d: %s",
rc, d.maxlen, d.len, strerror(errno)); rc, d.maxlen, d.len, strerror(errno));
return(GET_MIB2_ERR_GETMSGD); return(GET_MIB2_ERR_GETMSGD);
@ -265,7 +255,7 @@ get_mib2(struct opthdr **opt,
* Compose a successful return. * Compose a successful return.
*/ */
*opt = o; *opt = o;
*data = Db; *data = mib2->db;
*datalen = d.len; *datalen = d.len;
return(GET_MIB2_OK); return(GET_MIB2_OK);
} }
@ -282,46 +272,46 @@ get_mib2(struct opthdr **opt,
*/ */
int int
open_mib2(char **errmsg) open_mib2(solaris_mib2_t *mib2, char **errmsg)
{ {
*errmsg = ErrMsg; *errmsg = mib2->errmsg;
/* /*
* It's an error if the stream device is already open. * It's an error if the stream device is already open.
*/ */
if (Sd >= 0) { if (mib2->sd >= 0) {
(void) strcpy(ErrMsg, "open_mib2: MIB2 access already open"); (void) strcpy(mib2->errmsg, "open_mib2: MIB2 access already open");
return(GET_MIB2_ERR_OPEN); return(GET_MIB2_ERR_OPEN);
} }
/* /*
* Open the ARP stream device, push TCP and UDP on it. * Open the ARP stream device, push TCP and UDP on it.
*/ */
if ((Sd = open(GET_MIB2_ARPDEV, O_RDWR, 0600)) < 0) { if ((mib2->sd = open(GET_MIB2_ARPDEV, O_RDWR, 0600)) < 0) {
(void) sprintf(ErrMsg, "open_mib2: %s: %s", GET_MIB2_ARPDEV, (void) sprintf(mib2->errmsg, "open_mib2: %s: %s", GET_MIB2_ARPDEV,
strerror(errno)); strerror(errno));
return(GET_MIB2_ERR_ARPOPEN); return(GET_MIB2_ERR_ARPOPEN);
} }
if (ioctl(Sd, I_PUSH, GET_MIB2_TCPSTREAM) == -1) { if (ioctl(mib2->sd, I_PUSH, GET_MIB2_TCPSTREAM) == -1) {
(void) sprintf(ErrMsg, "open_mib2: push %s: %s", (void) sprintf(mib2->errmsg, "open_mib2: push %s: %s",
GET_MIB2_TCPSTREAM, strerror(errno)); GET_MIB2_TCPSTREAM, strerror(errno));
return(GET_MIB2_ERR_TCPPUSH); return(GET_MIB2_ERR_TCPPUSH);
} }
if (ioctl(Sd, I_PUSH, GET_MIB2_UDPSTREAM) == -1) { if (ioctl(mib2->sd, I_PUSH, GET_MIB2_UDPSTREAM) == -1) {
(void) sprintf(ErrMsg, "open_mib2: push %s: %s", (void) sprintf(mib2->errmsg, "open_mib2: push %s: %s",
GET_MIB2_UDPSTREAM, strerror(errno)); GET_MIB2_UDPSTREAM, strerror(errno));
return(GET_MIB2_ERR_UDPPUSH); return(GET_MIB2_ERR_UDPPUSH);
} }
/* /*
* Allocate a stream message buffer. * Allocate a stream message buffer.
*/ */
Smbl = sizeof(struct opthdr) + sizeof(struct T_optmgmt_req); mib2->smb_len = sizeof(struct opthdr) + sizeof(struct T_optmgmt_req);
if (Smbl < (sizeof (struct opthdr) + sizeof(struct T_optmgmt_ack))) { if (mib2->smb_len < (sizeof (struct opthdr) + sizeof(struct T_optmgmt_ack))) {
Smbl = sizeof (struct opthdr) + sizeof(struct T_optmgmt_ack); mib2->smb_len = sizeof (struct opthdr) + sizeof(struct T_optmgmt_ack);
} }
if (Smbl < sizeof(struct T_error_ack)) { if (mib2->smb_len < sizeof(struct T_error_ack)) {
Smbl = sizeof(struct T_error_ack); mib2->smb_len = sizeof(struct T_error_ack);
} }
if ((Smb = (char *)malloc(Smbl)) == NULL) { if ((mib2->smb = (char *)malloc(mib2->smb_len)) == NULL) {
(void) strcpy(ErrMsg, (void) strcpy(mib2->errmsg,
"open_mib2: no space for stream message buffer"); "open_mib2: no space for stream message buffer");
return(GET_MIB2_ERR_NOSPC); return(GET_MIB2_ERR_NOSPC);
} }

View File

@ -32,7 +32,10 @@
* 4. This notice may not be removed or altered. * 4. This notice may not be removed or altered.
*/ */
/*
* Changes for sigar:
* - remove static stuff to make thread-safe
*/
#if !defined(GET_MIB2_H) #if !defined(GET_MIB2_H)
#define GET_MIB2_H #define GET_MIB2_H
@ -86,11 +89,21 @@
#define GET_MIB2_ERR_MAX 13 /* maximum error number + 1 */ #define GET_MIB2_ERR_MAX 13 /* maximum error number + 1 */
typedef struct {
char *db; /* data buffer */
int db_len; /* data buffer length */
char *smb; /* stream message buffer */
size_t smb_len; /* size of Smb[] */
int sd; /* stream device descriptor */
char errmsg[GET_MIB2_ERRMSGL]; /* error message buffer */
} solaris_mib2_t;
/* /*
* Function prototypes * Function prototypes
*/ */
int close_mib2( /* close acccess to MIB2 information */ int close_mib2( /* close acccess to MIB2 information */
solaris_mib2_t *mib2,
char **errmsg /* error message buffer return char **errmsg /* error message buffer return
* address (if return value * address (if return value
* > GET_MIB2_OK.) The error * > GET_MIB2_OK.) The error
@ -99,6 +112,7 @@ int close_mib2( /* close acccess to MIB2 information */
* been defined. */ * been defined. */
); );
int get_mib2( /* get MIB2 information */ int get_mib2( /* get MIB2 information */
solaris_mib2_t *mib2,
struct opthdr **opt, /* opthdr pointer return (see struct opthdr **opt, /* opthdr pointer return (see
* <sys/socket.h> */ * <sys/socket.h> */
char **data, /* data buffer return address */ char **data, /* data buffer return address */
@ -112,6 +126,7 @@ int get_mib2( /* get MIB2 information */
* been defined. */ * been defined. */
); );
int open_mib2( /* open acccess to MIB2 information */ int open_mib2( /* open acccess to MIB2 information */
solaris_mib2_t *mib2,
char **errmsg /* error message buffer return char **errmsg /* error message buffer return
* address (if return value * address (if return value
* > GET_MIB2_OK.) The error * > GET_MIB2_OK.) The error