?? ss_strm.c
字號:
/********************************************************************20**
Name: System Services -- STREAMS
Type: C source file
Desc: Implementation of STREAMS messaging functions.
File: ss_strm.c
Sid: ss_strm.c 1.3 - 10/14/98 14:21:37
Prg: kp
*********************************************************************21*/
/* header include files (.h) */
#include "envopt.h" /* environment options */
#include "envdep.h" /* environment dependent */
#include "envind.h" /* environment independent */
#include "gen.h" /* general layer */
#include "ssi.h" /* system services */
#include "ss_err.h" /* errors */
#include "ss_dep.h" /* implementation-specific */
#include "ss_queue.h" /* queues */
#include "ss_strm.h" /* STREAMS */
#include "ss_msg.h" /* messaging */
#include "ss_mem.h" /* memory management interface */
#include "ss_gen.h" /* general */
/* header/extern include files (.x) */
#include "gen.x" /* general layer */
#include "ssi.x" /* system services */
#include "ss_dep.x" /* implementation-specific */
#include "ss_queue.x" /* queues */
#include "ss_task.x" /* tasking */
#include "ss_timer.x" /* timers */
#include "ss_strm.x" /* STREAMS */
#include "ss_msg.x" /* messaging */
#include "ss_mem.x" /* memory management interface */
#include "ss_drvr.x" /* driver tasks */
#include "ss_gen.x" /* general */
/* private variable declarations */
PRIVATE struct
{
Region mdRegion; /* region for message and data blocks */
Region datRegion; /* region for data buffers */
} strmCfg;
/*
* Interface functions (System Services--non-STREAMS interface)
*/
/*
*
* Fun: ssStrmCfg
*
* Desc: Configures the STREAMS system.
*
* Ret: ROK - ok
*
* Notes:
*
* File: ss_strm.c
*
*/
#ifdef ANSI
PUBLIC S16 ssStrmCfg
(
Region mdRegId, /* region for message and data blocks */
Region datRegId /* region for data buffers */
)
#else
PUBLIC S16 ssStrmCfg(mdRegId, datRegId)
Region mdRegId; /* region for message and data blocks */
Region datRegId; /* region for data buffers */
#endif
{
TRC1(ssStrmCfg);
strmCfg.mdRegion = mdRegId;
strmCfg.datRegion = datRegId;
RETVALUE(ROK);
}
/*
* STREAMS interface functions
*
* All these assume that ssStrmCfg() has been called first, with
* valid parameters.
*/
/*
*
* Fun: ssAdjMsg
*
* Desc: Trim abs(len) bytes from a message. If len is less than
* 0, trim from the tail, otherwise from the head. Operates
* only on blocks of the same type. Does not remove emptied
* message blocks.
*
*
* Ret: 1 - ok
* 0 - failure
*
* Notes:
*
* File: ss_strm.c
*
*/
#ifdef ANSI
PUBLIC S32 ssAdjMsg
(
SsMblk *mp, /* message */
S32 len /* bytes to remove */
)
#else
PUBLIC S32 ssAdjMsg(mp, len)
SsMblk *mp; /* message */
S32 len; /* bytes to remove */
#endif
{
S32 n; /* counter */
S32 size; /* size of mblks of same type as head/tail */
U8 type; /* message type */
SsMblk *bp; /* mblk for iteration */
SsMblk *first; /* first mblk to be adjusted */
TRC1(ssAdjMsg);
#if (ERRCLASS & ERRCLS_INT_PAR)
if (mp == NULLP)
{
SSLOGERROR(ERRCLS_INT_PAR, ESS428, ERRZERO, "Null pointer");
RETVALUE(0);
}
#endif
if (len == 0) /* nothing to do */
{
RETVALUE(1);
}
if (len > 0) /* trim from the head */
{
/* figure out the size of all blocks of the same type as the head */
bp = mp;
size = 0;
type = bp->b_datap->db_type;
while (bp && bp->b_datap->db_type == type)
{
n = bp->b_wptr - bp->b_rptr;
if (n > 0)
{
size += n;
}
bp = bp->b_cont;
}
/* if we can't trim len bytes, fail */
if (len > size)
{
RETVALUE(0);
}
/* do the trimming */
bp = mp;
for (; ;)
{
n = bp->b_wptr - bp->b_rptr;
if (n >= len)
{
bp->b_rptr += len;
break;
} else if (n > 0)
{
bp->b_rptr += len;
len -= n;
}
bp = bp->b_cont;
}
} else /* trim from the tail */
{
/* figure out the size of all blocks of the same type as the tail */
bp = mp;
first = bp;
size = 0;
type = bp->b_datap->db_type;
while (bp)
{
if (bp->b_datap->db_type == type)
{
n = bp->b_wptr - bp->b_rptr;
if (n > 0)
{
size += n;
}
} else
{
type = bp->b_datap->db_type;
first = bp;
size = 0;
}
bp = bp->b_cont;
}
/* if we can't trim len bytes, fail */
size += len;
if (size < 0)
{
RETVALUE(0);
}
/* do the trimming */
while (first)
{
n = first->b_wptr - first->b_rptr;
if (size <= 0)
{
first->b_rptr = first->b_wptr;
} else if (n > 0)
{
if (n > size)
{
first->b_wptr = first->b_rptr + size;
}
size -= n;
}
first = first->b_cont;
}
}
RETVALUE(1);
} /* ssAdjMsg */
/*
*
* Fun: ssAllocB
*
* Desc: Returns a pointer to a message block of type M_DATA
* in which the data buffer is of at least the specified
* size.
*
*
* Ret: non-NULL - success
* NULL - failure
*
* Notes: The parameter pri is unused.
*
* File: ss_strm.c
*
*/
#ifdef ANSI
PUBLIC SsMblk *ssAllocB
(
S32 size, /* required size */
U32 pri /* message priority */
)
#else
PUBLIC SsMblk *ssAllocB(size, pri)
S32 size; /* required size */
U32 pri; /* message priority */
#endif
{
SsMblk *bp; /* mblk for iteration */
Data *dat; /* pointer to data buffer */
Size m; /* temporary */
Size n; /* temporary */
S16 r; /* return value */
TRC1(ssAllocB);
UNUSED(pri);
/* allocate a single block for the mblock and the dblock */
m = (sizeof(SsMblk) + sizeof(SsDblk));
r = SAlloc(strmCfg.mdRegion, &m, 0, (Data **)&bp);
if (r != ROK)
{
#if (ERRCLASS & ERRCLS_ADD_RES)
SSLOGERROR(ERRCLS_ADD_RES, ESS429, (ErrVal) r, "SAlloc() failed");
#endif
RETVALUE(NULLP);
}
/* allocate space for the data block */
if (size > 0)
{
n = size;
r = SAlloc(strmCfg.datRegion, &n, 0, &dat);
if (r != ROK)
{
#if (ERRCLASS & ERRCLS_ADD_RES)
SSLOGERROR(ERRCLS_ADD_RES, ESS430, (ErrVal) r, "SAlloc() failed");
#endif
SFree(strmCfg.mdRegion, (Data *)bp, m);
RETVALUE(NULLP);
}
}
/* we _can_ allocate a message with an empty data block */
else
{
dat = NULLP;
}
/* generic set-up-message function */
SS_STRM_INITB(bp, (SsDblk *)(((U8 *)bp) + sizeof(SsMblk)), dat, size, NULLP);
RETVALUE(bp);
} /* ssAllocB */
/*
*
* Fun: ssCopyB
*
* Desc: Copies the contents of the specified message block
* into a newly-allocated message block of at least
* the same size. Calls ssAllocB().
*
* Ret: non-NULL - ok
* NULL - failure
*
* Notes:
*
* File: ss_strm.c
*
*/
#ifdef ANSI
PUBLIC SsMblk *ssCopyB
(
SsMblk *mp /* message block */
)
#else
PUBLIC SsMblk *ssCopyB(mp)
SsMblk *mp; /* message block */
#endif
{
SsMblk *bp; /* mblk for iteration */
U8 *ptr; /* pointer to data */
U32 size; /* size of data content */
TRC1(ssCopyB);
#if (ERRCLASS & ERRCLS_INT_PAR)
if (mp == NULLP)
{
SSLOGERROR(ERRCLS_INT_PAR, ESS431, ERRZERO, "Null pointer");
RETVALUE(NULLP);
}
#endif
/* allocate another message */
bp = ssAllocB((mp->b_datap->db_lim - mp->b_datap->db_base), 0);
if (bp == NULLP)
{
#if (ERRCLASS & ERRCLS_ADD_RES)
SSLOGERROR(ERRCLS_ADD_RES, ESS432, ERRZERO, "ssAllocB() failed");
#endif
RETVALUE(NULLP);
}
/* copy the contents, if any */
size = (mp->b_wptr - mp->b_rptr);
if (size > 0)
{
ptr = mp->b_rptr;
while (ptr != mp->b_wptr)
{
*bp->b_wptr++ = *ptr++;
}
}
RETVALUE(bp);
} /* ssCopyB */
/*
*
* Fun: ssCopyMsg
*
* Desc: Uses ssCopyB to copy the message blocks contained in
* the specified message to newly allocated blocks and
* links those blocks into a new message.
*
* Ret: non-NULL - ok
* NULL - failure
*
* Notes:
*
* File: ss_strm.c
*
*/
#ifdef ANSI
PUBLIC SsMblk *ssCopyMsg
(
SsMblk *mp /* message block */
)
#else
PUBLIC SsMblk *ssCopyMsg(mp)
SsMblk *mp; /* message block */
#endif
{
SsMblk *first; /* first mblk in message */
SsMblk *bp; /* mblk for iteration */
TRC1(ssCopyMsg);
#if (ERRCLASS & ERRCLS_INT_PAR)
if (mp == NULLP)
{
SSLOGERROR(ERRCLS_INT_PAR, ESS433, ERRZERO, "Null pointer");
RETVALUE(NULLP);
}
#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -