本文整理汇总了C++中CURVNET_RESTORE函数的典型用法代码示例。如果您正苦于以下问题:C++ CURVNET_RESTORE函数的具体用法?C++ CURVNET_RESTORE怎么用?C++ CURVNET_RESTORE使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了CURVNET_RESTORE函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: tcp_timer_delack
void
tcp_timer_delack(void *xtp)
{
struct tcpcb *tp = xtp;
struct inpcb *inp;
CURVNET_SET(tp->t_vnet);
inp = tp->t_inpcb;
KASSERT(inp != NULL, ("%s: tp %p tp->t_inpcb == NULL", __func__, tp));
INP_WLOCK(inp);
if (callout_pending(&tp->t_timers->tt_delack) ||
!callout_active(&tp->t_timers->tt_delack)) {
INP_WUNLOCK(inp);
CURVNET_RESTORE();
return;
}
callout_deactivate(&tp->t_timers->tt_delack);
if ((inp->inp_flags & INP_DROPPED) != 0) {
INP_WUNLOCK(inp);
CURVNET_RESTORE();
return;
}
tp->t_flags |= TF_ACKNOW;
TCPSTAT_INC(tcps_delack);
(void) tp->t_fb->tfb_tcp_output(tp);
INP_WUNLOCK(inp);
CURVNET_RESTORE();
}
开发者ID:jaredmcneill,项目名称:freebsd,代码行数:28,代码来源:tcp_timer.c
示例2: tcp_timer_delack
void
tcp_timer_delack(void *xtp)
{
struct tcpcb *tp = xtp;
struct inpcb *inp;
CURVNET_SET(tp->t_vnet);
inp = tp->t_inpcb;
/*
* XXXRW: While this assert is in fact correct, bugs in the tcpcb
* tear-down mean we need it as a work-around for races between
* timers and tcp_discardcb().
*
* KASSERT(inp != NULL, ("tcp_timer_delack: inp == NULL"));
*/
if (inp == NULL) {
tcp_timer_race++;
CURVNET_RESTORE();
return;
}
INP_WLOCK(inp);
if ((inp->inp_flags & INP_DROPPED) || callout_pending(&tp->t_timers->tt_delack)
|| !callout_active(&tp->t_timers->tt_delack)) {
INP_WUNLOCK(inp);
CURVNET_RESTORE();
return;
}
callout_deactivate(&tp->t_timers->tt_delack);
tp->t_flags |= TF_ACKNOW;
TCPSTAT_INC(tcps_delack);
(void) tcp_output(tp);
INP_WUNLOCK(inp);
CURVNET_RESTORE();
}
开发者ID:carriercomm,项目名称:libuinet,代码行数:35,代码来源:tcp_timer.c
示例3: svc_vc_create
/*
* Usage:
* xprt = svc_vc_create(sock, send_buf_size, recv_buf_size);
*
* Creates, registers, and returns a (rpc) tcp based transporter.
* Once *xprt is initialized, it is registered as a transporter
* see (svc.h, xprt_register). This routine returns
* a NULL if a problem occurred.
*
* The filedescriptor passed in is expected to refer to a bound, but
* not yet connected socket.
*
* Since streams do buffered io similar to stdio, the caller can specify
* how big the send and receive buffers are via the second and third parms;
* 0 => use the system default.
*/
SVCXPRT *
svc_vc_create(SVCPOOL *pool, struct socket *so, size_t sendsize,
size_t recvsize)
{
SVCXPRT *xprt = NULL;
struct sockaddr* sa;
int error;
SOCK_LOCK(so);
if (so->so_state & (SS_ISCONNECTED|SS_ISDISCONNECTED)) {
SOCK_UNLOCK(so);
CURVNET_SET(so->so_vnet);
error = so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa);
CURVNET_RESTORE();
if (error)
return (NULL);
xprt = svc_vc_create_conn(pool, so, sa);
free(sa, M_SONAME);
return (xprt);
}
SOCK_UNLOCK(so);
xprt = svc_xprt_alloc();
sx_init(&xprt->xp_lock, "xprt->xp_lock");
xprt->xp_pool = pool;
xprt->xp_socket = so;
xprt->xp_p1 = NULL;
xprt->xp_p2 = NULL;
xprt->xp_ops = &svc_vc_rendezvous_ops;
CURVNET_SET(so->so_vnet);
error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa);
CURVNET_RESTORE();
if (error) {
goto cleanup_svc_vc_create;
}
memcpy(&xprt->xp_ltaddr, sa, sa->sa_len);
free(sa, M_SONAME);
xprt_register(xprt);
solisten(so, -1, curthread);
SOCKBUF_LOCK(&so->so_rcv);
xprt->xp_upcallset = 1;
soupcall_set(so, SO_RCV, svc_vc_soupcall, xprt);
SOCKBUF_UNLOCK(&so->so_rcv);
return (xprt);
cleanup_svc_vc_create:
if (xprt) {
sx_destroy(&xprt->xp_lock);
svc_xprt_free(xprt);
}
return (NULL);
}
开发者ID:hmatyschok,项目名称:MeshBSD,代码行数:73,代码来源:svc_vc.c
示例4: send_modevent
static int
send_modevent(module_t mod, int type, void *unused)
{
#ifdef __notyet__
VNET_ITERATOR_DECL(vnet_iter);
#endif
int error;
switch (type) {
case MOD_LOAD:
SEND_LOCK_INIT();
error = pf_proto_register(PF_INET6, &send_protosw);
if (error != 0) {
printf("%s:%d: MOD_LOAD pf_proto_register(): %d\n",
__func__, __LINE__, error);
SEND_LOCK_DESTROY();
break;
}
send_sendso_input_hook = send_input;
break;
case MOD_UNLOAD:
/* Do not allow unloading w/o locking. */
return (EBUSY);
#ifdef __notyet__
VNET_LIST_RLOCK_NOSLEEP();
SEND_LOCK();
VNET_FOREACH(vnet_iter) {
CURVNET_SET(vnet_iter);
if (V_send_so != NULL) {
CURVNET_RESTORE();
SEND_UNLOCK();
VNET_LIST_RUNLOCK_NOSLEEP();
return (EBUSY);
}
CURVNET_RESTORE();
}
SEND_UNLOCK();
VNET_LIST_RUNLOCK_NOSLEEP();
error = pf_proto_unregister(PF_INET6, IPPROTO_SEND, SOCK_RAW);
if (error == 0)
SEND_LOCK_DESTROY();
send_sendso_input_hook = NULL;
break;
#endif
default:
error = 0;
break;
}
return (error);
}
开发者ID:FreeBSDFoundation,项目名称:freebsd,代码行数:52,代码来源:send.c
示例5: if_clone_create
/*
* Lookup and create a clone network interface.
*/
int
if_clone_create(char *name, size_t len, caddr_t params)
{
struct if_clone *ifc;
/* Try to find an applicable cloner for this request */
IF_CLONERS_LOCK();
LIST_FOREACH(ifc, &V_if_cloners, ifc_list)
if (ifc->ifc_type == SIMPLE) {
if (ifc_simple_match(ifc, name))
break;
} else {
if (ifc->ifc_match(ifc, name))
break;
}
#ifdef VIMAGE
if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) {
CURVNET_SET_QUIET(vnet0);
LIST_FOREACH(ifc, &V_if_cloners, ifc_list)
if (ifc->ifc_type == SIMPLE) {
if (ifc_simple_match(ifc, name))
break;
} else {
if (ifc->ifc_match(ifc, name))
break;
}
CURVNET_RESTORE();
}
开发者ID:derekmarcotte,项目名称:freebsd,代码行数:31,代码来源:if_clone.c
示例6: soaio_process_sb
static void
soaio_process_sb(struct socket *so, struct sockbuf *sb)
{
struct kaiocb *job;
CURVNET_SET(so->so_vnet);
SOCKBUF_LOCK(sb);
while (!TAILQ_EMPTY(&sb->sb_aiojobq) && soaio_ready(so, sb)) {
job = TAILQ_FIRST(&sb->sb_aiojobq);
TAILQ_REMOVE(&sb->sb_aiojobq, job, list);
if (!aio_clear_cancel_function(job))
continue;
soaio_process_job(so, sb, job);
}
/*
* If there are still pending requests, the socket must not be
* ready so set SB_AIO to request a wakeup when the socket
* becomes ready.
*/
if (!TAILQ_EMPTY(&sb->sb_aiojobq))
sb->sb_flags |= SB_AIO;
sb->sb_flags &= ~SB_AIO_RUNNING;
SOCKBUF_UNLOCK(sb);
SOCK_LOCK(so);
sorele(so);
CURVNET_RESTORE();
}
开发者ID:2trill2spill,项目名称:freebsd,代码行数:30,代码来源:sys_socket.c
示例7: vnet_destroy
/*
* Destroy a virtual network stack.
*/
void
vnet_destroy(struct vnet *vnet)
{
SDT_PROBE2(vnet, functions, vnet_destroy, entry, __LINE__, vnet);
KASSERT(vnet->vnet_sockcnt == 0,
("%s: vnet still has sockets", __func__));
VNET_LIST_WLOCK();
LIST_REMOVE(vnet, vnet_le);
VNET_LIST_WUNLOCK();
CURVNET_SET_QUIET(vnet);
vnet_sysuninit();
CURVNET_RESTORE();
/*
* Release storage for the virtual network stack instance.
*/
free(vnet->vnet_data_mem, M_VNET_DATA);
vnet->vnet_data_mem = NULL;
vnet->vnet_data_base = 0;
vnet->vnet_magic_n = 0xdeadbeef;
free(vnet, M_VNET);
SDT_PROBE1(vnet, functions, vnet_destroy, return, __LINE__);
}
开发者ID:2asoft,项目名称:freebsd,代码行数:29,代码来源:vnet.c
示例8: ieee80211_notify_replay_failure
void
ieee80211_notify_replay_failure(struct ieee80211vap *vap,
const struct ieee80211_frame *wh, const struct ieee80211_key *k,
u_int64_t rsc, int tid)
{
struct ifnet *ifp = vap->iv_ifp;
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2,
"%s replay detected tid %d <rsc %ju, csc %ju, keyix %u rxkeyix %u>",
k->wk_cipher->ic_name, tid, (intmax_t) rsc,
(intmax_t) k->wk_keyrsc[tid],
k->wk_keyix, k->wk_rxkeyix);
if (ifp != NULL) { /* NB: for cipher test modules */
struct ieee80211_replay_event iev;
IEEE80211_ADDR_COPY(iev.iev_dst, wh->i_addr1);
IEEE80211_ADDR_COPY(iev.iev_src, wh->i_addr2);
iev.iev_cipher = k->wk_cipher->ic_cipher;
if (k->wk_rxkeyix != IEEE80211_KEYIX_NONE)
iev.iev_keyix = k->wk_rxkeyix;
else
iev.iev_keyix = k->wk_keyix;
iev.iev_keyrsc = k->wk_keyrsc[tid];
iev.iev_rsc = rsc;
CURVNET_SET(ifp->if_vnet);
rt_ieee80211msg(ifp, RTM_IEEE80211_REPLAY, &iev, sizeof(iev));
CURVNET_RESTORE();
}
}
开发者ID:Alkzndr,项目名称:freebsd,代码行数:30,代码来源:ieee80211_freebsd.c
示例9: soo_stat
int
soo_stat(struct file *fp, struct stat *ub, struct ucred *active_cred,
struct thread *td)
{
struct socket *so = fp->f_data;
#ifdef MAC
int error;
#endif
bzero((caddr_t)ub, sizeof (*ub));
ub->st_mode = S_IFSOCK;
#ifdef MAC
error = mac_socket_check_stat(active_cred, so);
if (error)
return (error);
#endif
/*
* If SBS_CANTRCVMORE is set, but there's still data left in the
* receive buffer, the socket is still readable.
*/
CURVNET_SET(so->so_vnet);
SOCKBUF_LOCK(&so->so_rcv);
if ((so->so_rcv.sb_state & SBS_CANTRCVMORE) == 0 ||
so->so_rcv.sb_cc != 0)
ub->st_mode |= S_IRUSR | S_IRGRP | S_IROTH;
ub->st_size = so->so_rcv.sb_cc - so->so_rcv.sb_ctl;
SOCKBUF_UNLOCK(&so->so_rcv);
CURVNET_RESTORE();
/* Unlocked read. */
if ((so->so_snd.sb_state & SBS_CANTSENDMORE) == 0)
ub->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
ub->st_uid = so->so_cred->cr_uid;
ub->st_gid = so->so_cred->cr_gid;
return (*so->so_proto->pr_usrreqs->pru_sense)(so, ub);
}
开发者ID:BillTheBest,项目名称:libuinet,代码行数:35,代码来源:sys_socket.c
示例10: in_rtqdrain
void
in_rtqdrain(void)
{
VNET_ITERATOR_DECL(vnet_iter);
struct radix_node_head *rnh;
struct rtqk_arg arg;
int fibnum;
VNET_LIST_RLOCK_NOSLEEP();
VNET_FOREACH(vnet_iter) {
CURVNET_SET(vnet_iter);
for ( fibnum = 0; fibnum < rt_numfibs; fibnum++) {
rnh = rt_tables_get_rnh(fibnum, AF_INET);
arg.found = arg.killed = 0;
arg.rnh = rnh;
arg.nextstop = 0;
arg.draining = 1;
arg.updating = 0;
RADIX_NODE_HEAD_LOCK(rnh);
rnh->rnh_walktree(rnh, in_rtqkill, &arg);
RADIX_NODE_HEAD_UNLOCK(rnh);
}
CURVNET_RESTORE();
}
VNET_LIST_RUNLOCK_NOSLEEP();
}
开发者ID:dcui,项目名称:FreeBSD-9.3_kernel,代码行数:27,代码来源:in_rmx.c
示例11: wtap_ioctl
int
wtap_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
int fflag, struct thread *td)
{
int error = 0;
CURVNET_SET(CRED_TO_VNET(curthread->td_ucred));
switch(cmd) {
case WTAPIOCTLCRT:
if(new_wtap(hal, *(int *)data))
error = EINVAL;
break;
case WTAPIOCTLDEL:
if(free_wtap(hal, *(int *)data))
error = EINVAL;
break;
default:
DWTAP_PRINTF("Unkown WTAP IOCTL\n");
error = EINVAL;
}
CURVNET_RESTORE();
return error;
}
开发者ID:Digital-Chaos,项目名称:freebsd,代码行数:25,代码来源:if_wtap_module.c
示例12: notify_macaddr
/*
* Helper function for events that pass just a single mac address.
*/
static void
notify_macaddr(struct ifnet *ifp, int op, const uint8_t mac[IEEE80211_ADDR_LEN])
{
struct ieee80211_join_event iev;
CURVNET_SET(ifp->if_vnet);
memset(&iev, 0, sizeof(iev));
IEEE80211_ADDR_COPY(iev.iev_addr, mac);
rt_ieee80211msg(ifp, op, &iev, sizeof(iev));
CURVNET_RESTORE();
}
开发者ID:Alkzndr,项目名称:freebsd,代码行数:14,代码来源:ieee80211_freebsd.c
示例13: svc_dg_create
SVCXPRT *
svc_dg_create(SVCPOOL *pool, struct socket *so, size_t sendsize,
size_t recvsize)
{
SVCXPRT *xprt;
struct __rpc_sockinfo si;
struct sockaddr* sa;
int error;
if (!__rpc_socket2sockinfo(so, &si)) {
printf(svc_dg_str, svc_dg_err1);
return (NULL);
}
/*
* Find the receive and the send size
*/
sendsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsize);
recvsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsize);
if ((sendsize == 0) || (recvsize == 0)) {
printf(svc_dg_str, svc_dg_err2);
return (NULL);
}
xprt = svc_xprt_alloc();
sx_init(&xprt->xp_lock, "xprt->xp_lock");
xprt->xp_pool = pool;
xprt->xp_socket = so;
xprt->xp_p1 = NULL;
xprt->xp_p2 = NULL;
xprt->xp_ops = &svc_dg_ops;
CURVNET_SET(so->so_vnet);
error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa);
CURVNET_RESTORE();
if (error)
goto freedata;
memcpy(&xprt->xp_ltaddr, sa, sa->sa_len);
free(sa, M_SONAME);
xprt_register(xprt);
SOCKBUF_LOCK(&so->so_rcv);
soupcall_set(so, SO_RCV, svc_dg_soupcall, xprt);
SOCKBUF_UNLOCK(&so->so_rcv);
return (xprt);
freedata:
(void) printf(svc_dg_str, __no_mem_str);
if (xprt) {
svc_xprt_free(xprt);
}
return (NULL);
}
开发者ID:AhmadTux,项目名称:freebsd,代码行数:54,代码来源:svc_dg.c
示例14: ieee80211_vap_destroy
void
ieee80211_vap_destroy(struct ieee80211vap *vap)
{
CURVNET_SET(vap->iv_ifp->if_vnet);
#if __FreeBSD_version >= 1000020
if_clone_destroyif(wlan_cloner, vap->iv_ifp);
#else
if_clone_destroyif(&wlan_cloner, vap->iv_ifp);
#endif
CURVNET_RESTORE();
}
开发者ID:Alkzndr,项目名称:freebsd,代码行数:11,代码来源:ieee80211_freebsd.c
示例15: ieee80211_notify_radio
void
ieee80211_notify_radio(struct ieee80211com *ic, int state)
{
struct ifnet *ifp = ic->ic_ifp;
struct ieee80211_radio_event iev;
memset(&iev, 0, sizeof(iev));
iev.iev_state = state;
CURVNET_SET(ifp->if_vnet);
rt_ieee80211msg(ifp, RTM_IEEE80211_RADIO, &iev, sizeof(iev));
CURVNET_RESTORE();
}
开发者ID:Alkzndr,项目名称:freebsd,代码行数:12,代码来源:ieee80211_freebsd.c
示例16: ieee80211_notify_scan_done
void
ieee80211_notify_scan_done(struct ieee80211vap *vap)
{
struct ifnet *ifp = vap->iv_ifp;
IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s\n", "notify scan done");
/* dispatch wireless event indicating scan completed */
CURVNET_SET(ifp->if_vnet);
rt_ieee80211msg(ifp, RTM_IEEE80211_SCAN, NULL, 0);
CURVNET_RESTORE();
}
开发者ID:Alkzndr,项目名称:freebsd,代码行数:12,代码来源:ieee80211_freebsd.c
示例17: netisr_process_workstream_proto
/*
* Process packets associated with a workstream and protocol. For reasons of
* fairness, we process up to one complete netisr queue at a time, moving the
* queue to a stack-local queue for processing, but do not loop refreshing
* from the global queue. The caller is responsible for deciding whether to
* loop, and for setting the NWS_RUNNING flag. The passed workstream will be
* locked on entry and relocked before return, but will be released while
* processing. The number of packets processed is returned.
*/
static u_int
netisr_process_workstream_proto(struct netisr_workstream *nwsp, u_int proto)
{
struct netisr_work local_npw, *npwp;
u_int handled;
struct mbuf *m;
NETISR_LOCK_ASSERT();
NWS_LOCK_ASSERT(nwsp);
KASSERT(nwsp->nws_flags & NWS_RUNNING,
("%s(%u): not running", __func__, proto));
KASSERT(proto >= 0 && proto < NETISR_MAXPROT,
("%s(%u): invalid proto\n", __func__, proto));
npwp = &nwsp->nws_work[proto];
if (npwp->nw_len == 0)
return (0);
/*
* Move the global work queue to a thread-local work queue.
*
* Notice that this means the effective maximum length of the queue
* is actually twice that of the maximum queue length specified in
* the protocol registration call.
*/
handled = npwp->nw_len;
local_npw = *npwp;
npwp->nw_head = NULL;
npwp->nw_tail = NULL;
npwp->nw_len = 0;
nwsp->nws_pendingbits &= ~(1 << proto);
NWS_UNLOCK(nwsp);
while ((m = local_npw.nw_head) != NULL) {
local_npw.nw_head = m->m_hdr.mh_nextpkt;
m->m_hdr.mh_nextpkt = NULL;
if (local_npw.nw_head == NULL)
local_npw.nw_tail = NULL;
local_npw.nw_len--;
VNET_ASSERT(m->M_dat.MH.MH_pkthdr.rcvif != NULL,
("%s:%d rcvif == NULL: m=%p", __func__, __LINE__, m));
CURVNET_SET(m->M_dat.MH.MH_pkthdr.rcvif->if_vnet);
netisr_proto[proto].np_handler(m);
CURVNET_RESTORE();
}
KASSERT(local_npw.nw_len == 0,
("%s(%u): len %u", __func__, proto, local_npw.nw_len));
if (netisr_proto[proto].np_drainedcpu)
netisr_proto[proto].np_drainedcpu(nwsp->nws_cpu);
NWS_LOCK(nwsp);
npwp->nw_handled += handled;
return (handled);
}
开发者ID:kevsmith,项目名称:osv,代码行数:62,代码来源:netisr.c
示例18: tcp_slowtimo
/*
* Tcp protocol timeout routine called every 500 ms.
* Updates timestamps used for TCP
* causes finite state machine actions if timers expire.
*/
void
tcp_slowtimo(void)
{
VNET_ITERATOR_DECL(vnet_iter);
VNET_LIST_RLOCK_NOSLEEP();
VNET_FOREACH(vnet_iter) {
CURVNET_SET(vnet_iter);
(void) tcp_tw_2msl_scan(0);
CURVNET_RESTORE();
}
VNET_LIST_RUNLOCK_NOSLEEP();
}
开发者ID:jaredmcneill,项目名称:freebsd,代码行数:18,代码来源:tcp_timer.c
示例19: in6_mtutimo
static void
in6_mtutimo(void *rock)
{
CURVNET_SET_QUIET((struct vnet *) rock);
struct timeval atv;
struct mtuex_arg arg;
rt_foreach_fib_walk(AF_INET6, in6_mtutimo_setwa, in6_mtuexpire, &arg);
atv.tv_sec = MTUTIMO_DEFAULT;
atv.tv_usec = 0;
callout_reset(&V_rtq_mtutimer, tvtohz(&atv), in6_mtutimo, rock);
CURVNET_RESTORE();
}
开发者ID:hmatyschok,项目名称:MeshBSD,代码行数:14,代码来源:in6_rmx.c
示例20: vtbe_proc_rx
static void
vtbe_proc_rx(struct vtbe_softc *sc, struct vqueue_info *vq)
{
struct iovec iov[DESC_COUNT];
struct ifnet *ifp;
struct uio uio;
struct mbuf *m;
int iolen;
int i;
int n;
ifp = sc->ifp;
n = vq_getchain(sc->beri_mem_offset, vq, iov,
DESC_COUNT, NULL);
KASSERT(n >= 1 && n <= DESC_COUNT,
("wrong n %d", n));
iolen = 0;
for (i = 1; i < n; i++) {
iolen += iov[i].iov_len;
}
uio.uio_resid = iolen;
uio.uio_iov = &iov[1];
uio.uio_segflg = UIO_SYSSPACE;
uio.uio_iovcnt = (n - 1);
uio.uio_rw = UIO_WRITE;
if ((m = m_uiotombuf(&uio, M_NOWAIT, 0, ETHER_ALIGN,
M_PKTHDR)) == NULL) {
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto done;
}
m->m_pkthdr.rcvif = ifp;
if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
CURVNET_SET(ifp->if_vnet);
VTBE_UNLOCK(sc);
(*ifp->if_input)(ifp, m);
VTBE_LOCK(sc);
CURVNET_RESTORE();
done:
vq_relchain(vq, iov, n, iolen + sc->hdrsize);
}
开发者ID:jashank,项目名称:freebsd,代码行数:49,代码来源:if_vtbe.c
注:本文中的CURVNET_RESTORE函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论