TO_REMOVE+=/usr/share/man/cat1/g++41.1.gz
TO_REMOVE+=/usr/share/man/cat1/gcc41.1.gz
TO_REMOVE+=/usr/share/man/cat1/gcov41.1.gz
+TO_REMOVE+=/usr/include/sys/caps.h
+TO_REMOVE+=/usr/share/man/cat2/caps_sys_abort.2.gz
+TO_REMOVE+=/usr/share/man/man2/caps_sys_abort.2.gz
+TO_REMOVE+=/usr/share/man/cat2/caps_sys_client.2.gz
+TO_REMOVE+=/usr/share/man/man2/caps_sys_client.2.gz
+TO_REMOVE+=/usr/share/man/cat2/caps_sys_close.2.gz
+TO_REMOVE+=/usr/share/man/man2/caps_sys_close.2.gz
+TO_REMOVE+=/usr/share/man/cat2/caps_sys_get.2.gz
+TO_REMOVE+=/usr/share/man/man2/caps_sys_get.2.gz
+TO_REMOVE+=/usr/share/man/cat2/caps_sys_getgen.2.gz
+TO_REMOVE+=/usr/share/man/man2/caps_sys_getgen.2.gz
+TO_REMOVE+=/usr/share/man/cat2/caps_sys_put.2.gz
+TO_REMOVE+=/usr/share/man/man2/caps_sys_put.2.gz
+TO_REMOVE+=/usr/share/man/cat2/caps_sys_reply.2.gz
+TO_REMOVE+=/usr/share/man/man2/caps_sys_reply.2.gz
+TO_REMOVE+=/usr/share/man/cat2/caps_sys_service.2.gz
+TO_REMOVE+=/usr/share/man/man2/caps_sys_service.2.gz
+TO_REMOVE+=/usr/share/man/cat2/caps_sys_setgen.2.gz
+TO_REMOVE+=/usr/share/man/man2/caps_sys_setgen.2.gz
+TO_REMOVE+=/usr/share/man/cat2/caps_sys_wait.2.gz
+TO_REMOVE+=/usr/share/man/man2/caps_sys_wait.2.gz
+TO_REMOVE+=/var/caps
.if ${MACHINE_ARCH} == "x86_64"
TO_REMOVE+=/usr/libdata/stallion/2681.sys
..
..
/set mode=0755
- caps
- root
- ..
- users
- ..
- ..
db
..
empty mode=0555 flags=schg
.ds doc-str-Lb-libbsdxml eXpat XML parser library (libbsdxml, \-lbsdxml)
.ds doc-str-Lb-libcalendar Calendar Arithmetic Library (libcalendar, \-lcalendar)
.ds doc-str-Lb-libcam Common Access Method User Library (libcam, \-lcam)
-.ds doc-str-Lb-libcaps CAPS IPC Library (libcaps, \-lcaps)
.ds doc-str-Lb-libcipher FreeSec Crypt Library (libcipher, \-lcipher)
.ds doc-str-Lb-libdevattr Device attribute and event library (libdevattr \-ldevattr)
.ds doc-str-Lb-libdevinfo Device and Resource Information Utility Library (libdevinfo, \-ldevinfo)
aio_cancel.2 aio_error.2 aio_read.2 aio_return.2 \
aio_suspend.2 aio_waitcomplete.2 aio_write.2 \
bind.2 brk.2 \
- caps_sys_abort.2 caps_sys_client.2 caps_sys_close.2 caps_sys_get.2 \
- caps_sys_getgen.2 caps_sys_put.2 caps_sys_reply.2 caps_sys_service.2 \
- caps_sys_setgen.2 \
sys_checkpoint.2 chdir.2 chflags.2 \
chmod.2 chown.2 chroot.2 clock_gettime.2 close.2 closefrom.2 \
connect.2 dup.2 execve.2 extattr.2 extexit.2 \
MLINKS+=access.2 faccessat.2
MLINKS+=brk.2 sbrk.2
-MLINKS+=caps_sys_get.2 caps_sys_wait.2
MLINKS+=chdir.2 fchdir.2
MLINKS+=chflags.2 fchflags.2 chflags.2 lchflags.2
MLINKS+=chmod.2 fchmod.2 chmod.2 lchmod.2 chmod.2 fchmodat.2
+++ /dev/null
-.\"
-.\" Copyright (c) 2006 The DragonFly Project. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\"
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in
-.\" the documentation and/or other materials provided with the
-.\" distribution.
-.\" 3. Neither the name of The DragonFly Project nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific, prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
-.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $DragonFly: src/lib/libc/sys/caps_sys_abort.2,v 1.1 2006/02/28 22:40:49 swildner Exp $
-.\"
-.Dd February 28, 2006
-.Dt CAPS_SYS_ABORT 2
-.Os
-.Sh NAME
-.Nm caps_sys_abort
-.Nd abort a CAPS IPC message
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In sys/caps.h
-.Ft int
-.Fn caps_sys_abort "int portid" "off_t msgid" "int flags"
-.Sh DESCRIPTION
-Abort a previously sent message.
-The
-.Fa portid
-argument is a port identifier returned by a previous call to
-.Fn caps_sys_service
-or
-.Fn caps_sys_client .
-The message to be aborted is identified by the 64 bit
-.Fa msgid
-that was returned by a previous call to
-.Fn caps_sys_put .
-.Pp
-You must still wait for the message to be returned after sending the
-abort request.
-.\".Sh RETURN VALUES
-.\"This function returns an abort code indicating failure or success of
-.\"the call:
-.\".Bl -tag -width ".Dv CAPS_ABORT_BEFORESERVER"
-.\".It Dv CAPS_ABORT_RETURNED
-.\"The message was already returned.
-.\"No action is taken.
-.\".It Dv CAPS_ABORT_BEFORESERVER
-.\"The message was caught before the server got it.
-.\".It Dv CAPS_ABORT_ATSERVER
-.\"The message was already retrieved by the server.
-.\".El
-.Sh SEE ALSO
-.Xr caps_sys_client 2 ,
-.Xr caps_sys_put 2 ,
-.Xr caps_sys_service 2
-.Sh HISTORY
-The
-.Fn caps_sys_abort
-function call first appeared in
-.Dx 1.0 .
-.Sh AUTHORS
-.An -nosplit
-CAPS IPC was written by
-.An Matthew Dillon .
-This man page was written by
-.An Sascha Wildner .
-.Sh BUGS
-This function is currently not implemented and
-.Dv CAPS_ABORT_NOTIMPL
-is returned.
+++ /dev/null
-.\"
-.\" Copyright (c) 2006 The DragonFly Project. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\"
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in
-.\" the documentation and/or other materials provided with the
-.\" distribution.
-.\" 3. Neither the name of The DragonFly Project nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific, prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
-.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $DragonFly: src/lib/libc/sys/caps_sys_client.2,v 1.2 2006/03/02 19:27:35 swildner Exp $
-.\"
-.Dd February 28, 2006
-.Dt CAPS_SYS_CLIENT 2
-.Os
-.Sh NAME
-.Nm caps_sys_client
-.Nd create a CAPS IPC client
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In sys/caps.h
-.Ft int
-.Fo caps_sys_client
-.Fa "const char *name"
-.Fa "uid_t uid"
-.Fa "gid_t gid"
-.Fa "int upcid"
-.Fa "int flags"
-.Fc
-.Sh DESCRIPTION
-Create an IPC client connected to the service specified by the
-.Fa name
-argument.
-Either
-.Fa uid
-or
-.Fa gid
-can be -1 (thereby indicating a wildcard),
-but not both.
-Programs connecting to a
-.Em generic
-service typically first try
-.Fn getuid
-and -1, then try -1 and
-.Fn getgid ,
-then try 0 and 0.
-The
-.Fa upcid
-argument can either be an upcall or a kqueue identifier.
-.Sh RETURN VALUES
-On success, this function returns a port identifier.
-On failure, -1 is returned and
-.Va errno
-is set to indicate the error.
-.Sh ERRORS
-This function will fail if:
-.Bl -tag -width ".Bq Er EOPNOTSUPP"
-.It Bq Er EOPNOTSUPP
-The CAPS system has not been enabled with
-.Va kern.caps_enabled .
-.It Bq Er EINVAL
-An invalid argument was specified.
-.El
-.Sh SEE ALSO
-.Xr caps_sys_service 2
-.Sh HISTORY
-The
-.Fn caps_sys_client
-function call first appeared in
-.Dx 1.0 .
-.Sh AUTHORS
-.An -nosplit
-CAPS IPC was written by
-.An Matthew Dillon .
-This man page was written by
-.An Sascha Wildner .
-.Sh BUGS
-Support for the
-.Fa upcid
-argument is currently not implemented.
+++ /dev/null
-.\"
-.\" Copyright (c) 2006 The DragonFly Project. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\"
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in
-.\" the documentation and/or other materials provided with the
-.\" distribution.
-.\" 3. Neither the name of The DragonFly Project nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific, prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
-.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $DragonFly: src/lib/libc/sys/caps_sys_close.2,v 1.1 2006/02/28 22:40:49 swildner Exp $
-.\"
-.Dd February 28, 2006
-.Dt CAPS_SYS_CLOSE 2
-.Os
-.Sh NAME
-.Nm caps_sys_close
-.Nd terminate a CAPS IPC link
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In sys/caps.h
-.Ft int
-.Fn caps_sys_close "int portid"
-.Sh DESCRIPTION
-Terminate a CAPS IPC link.
-The
-.Fa portid
-argument is a port identifier returned by a previous call to
-.Fn caps_sys_service
-or
-.Fn caps_sys_client .
-Any unreplied messages will be automatically replied to by the kernel.
-.Sh RETURN VALUES
-.Rv -std caps_sys_close
-.Sh ERRORS
-This function will fail if:
-.Bl -tag -width ".Bq Er EINVAL"
-.It Bq Er EINVAL
-The
-.Fa portid
-could not be found.
-.El
-.Sh SEE ALSO
-.Xr caps_sys_client 2 ,
-.Xr caps_sys_service 2
-.Sh HISTORY
-The
-.Fn caps_sys_close
-function call first appeared in
-.Dx 1.0 .
-.Sh AUTHORS
-.An -nosplit
-CAPS IPC was written by
-.An Matthew Dillon .
-This man page was written by
-.An Sascha Wildner .
+++ /dev/null
-.\"
-.\" Copyright (c) 2006 The DragonFly Project. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\"
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in
-.\" the documentation and/or other materials provided with the
-.\" distribution.
-.\" 3. Neither the name of The DragonFly Project nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific, prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
-.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $DragonFly: src/lib/libc/sys/caps_sys_get.2,v 1.2 2006/03/02 19:27:35 swildner Exp $
-.\"
-.Dd February 28, 2006
-.Dt CAPS_SYS_GET 2
-.Os
-.Sh NAME
-.Nm caps_sys_get ,
-.Nm caps_sys_wait
-.Nd retrieve a message from a CAPS IPC port
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In sys/caps.h
-.Ft int
-.Fo caps_sys_get
-.Fa "int portid"
-.Fa "void *msg"
-.Fa "int maxsize"
-.Fa "struct caps_msgid *msgid"
-.Fa "struct caps_cred *ccr"
-.Fc
-.Ft int
-.Fo caps_sys_wait
-.Fa "int portid"
-.Fa "void *msg"
-.Fa "int maxsize"
-.Fa "struct caps_msgid *msgid"
-.Fa "struct caps_cred *ccr"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn caps_sys_get
-function retrieves the next ready message from a port specified by
-.Fa portid .
-The identifier and creds of the message are stored in
-.Fa msgid
-and
-.Fa ccr
-(which may be NULL).
-.Pp
-The message is only stored in the
-.Fa msg
-buffer if its length is less or equal than the size specified by
-.Fa maxsize .
-If the message is too large its identifier and creds are still
-returned but the message is not dequeued.
-In this case, the caller is expected to call
-.Fn caps_sys_get
-again with a larger buffer or to call
-.Fn caps_sys_reply
-on the
-.Fa msgid
-without retrieving it (if it does not want to handle the message).
-.Pp
-The returned
-.Fa msg
-can either be a new message from a client, a reply from the service,
-or (on the service side only)
-an acknowledgement that a reply made earlier has been processed by
-the client.
-This state information is stored in
-.Va msgid->c_state
-and can be:
-.Bl -tag -width ".Dv CAPMS_REQUEST_RETRY"
-.It Dv CAPMS_REQUEST
-The server side received a new request.
-.It Dv CAPMS_REQUEST_RETRY
-Reserved for future use.
-.It Dv CAPMS_REPLY
-The client side received a reply.
-.It Dv CAPMS_REPLY_RETRY
-Reserved for future use.
-.It Dv CAPMS_DISPOSE
-The server side reply has been disposed of by the client.
-.El
-.Pp
-If you are a CAPS client the only message type you will get is
-.Dv CAPMS_REPLY .
-If you are a CAPS server you can get
-.Dv CAPMS_REQUEST
-or
-.Dv CAPMS_DISPOSE
-message types.
-.Pp
-The
-.Fn caps_sys_get
-function does not block.
-If a blocking function is needed
-.Fn caps_sys_wait
-can be used which blocks until it is interrupted or a message is
-received.
-.Sh RETURN VALUES
-If successful, the
-.Fn caps_sys_get
-and
-.Fn caps_sys_wait
-functions return the length of the message received.
-Note that zero message lengths are perfectly acceptable so 0 can be
-legitimately returned.
-On failure, -1 is returned and
-.Va errno
-is set to indicate the error.
-.Sh ERRORS
-This function will fail if:
-.Bl -tag -width ".Bq Er EWOULDBLOCK"
-.It Bq Er EINVAL
-An invalid argument was specified.
-.It Bq Er ENOTCONN
-The process originally creating the port forked and the child
-process attempts to access the port.
-The child process is expected to create its own port.
-This error is also returned if the remote end closed its connection
-and is no longer available.
-.It Bq Er EWOULDBLOCK
-No messages are ready (this applies only to
-.Fn caps_sys_get ) .
-.It Bq Er EINTR
-The system call was interrupted (this applies only to
-.Fn caps_sys_wait ) .
-.El
-.Sh SEE ALSO
-.Xr caps_sys_client 2 ,
-.Xr caps_sys_put 2 ,
-.Xr caps_sys_reply 2 ,
-.Xr caps_sys_service 2
-.Sh HISTORY
-The
-.Fn caps_sys_get
-and
-.Fn caps_sys_wait
-function calls first appeared in
-.Dx 1.0 .
-.Sh AUTHORS
-.An -nosplit
-CAPS IPC was written by
-.An Matthew Dillon .
-This man page was written by
-.An Sascha Wildner .
+++ /dev/null
-.\"
-.\" Copyright (c) 2006 The DragonFly Project. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\"
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in
-.\" the documentation and/or other materials provided with the
-.\" distribution.
-.\" 3. Neither the name of The DragonFly Project nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific, prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
-.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $DragonFly: src/lib/libc/sys/caps_sys_getgen.2,v 1.1 2006/02/28 22:40:49 swildner Exp $
-.\"
-.Dd February 28, 2006
-.Dt CAPS_SYS_GETGEN 2
-.Os
-.Sh NAME
-.Nm caps_sys_getgen
-.Nd get the generation number for a CAPS IPC link
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In sys/caps.h
-.Ft caps_gen_t
-.Fn caps_sys_getgen "int portid"
-.Sh DESCRIPTION
-The
-.Fn caps_sys_getgen
-function returns the 64 bit generation number for a CAPS link
-specified by the
-.Fa portid
-identifier.
-This number is typically used to allow a client to detect when a
-service has been restarted.
-.Sh RETURN VALUES
-On success, the 64 bit generation number is returned.
-If an error occurs, -1 is returned and
-.Va errno
-is set.
-.Sh ERRORS
-This function will fail if:
-.Bl -tag -width ".Bq Er ENOTCONN"
-.It Bq Er EINVAL
-The
-.Fa portid
-could not be found.
-.It Bq Er ENOTCONN
-The process originally creating the port forked and the child
-process attempts to access the port.
-The child process is expected to create its own port.
-.El
-.Sh SEE ALSO
-.Xr caps_sys_setgen 2
-.Sh HISTORY
-The
-.Fn caps_sys_getgen
-function call first appeared in
-.Dx 1.0 .
-.Sh AUTHORS
-.An -nosplit
-CAPS IPC was written by
-.An Matthew Dillon .
-This man page was written by
-.An Sascha Wildner .
+++ /dev/null
-.\"
-.\" Copyright (c) 2006 The DragonFly Project. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\"
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in
-.\" the documentation and/or other materials provided with the
-.\" distribution.
-.\" 3. Neither the name of The DragonFly Project nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific, prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
-.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $DragonFly: src/lib/libc/sys/caps_sys_put.2,v 1.1 2006/02/28 22:40:49 swildner Exp $
-.\"
-.Dd February 28, 2006
-.Dt CAPS_SYS_PUT 2
-.Os
-.Sh NAME
-.Nm caps_sys_put
-.Nd send an opaque message to a CAPS IPC port
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In sys/caps.h
-.Ft off_t
-.Fn caps_sys_put "int portid" "const void *msg" "int msgsize"
-.Sh DESCRIPTION
-Send an opaque message
-.Fa msg
-of the specified size
-.Fa msgsiz
-to the port identified by
-.Fa portid .
-The memory associated with the message must be left intact until the
-message is returned.
-The kernel does not make a copy of the message and its size may not
-exceed 128KB.
-.Pp
-This function is only used on the client side.
-.Sh RETURN VALUES
-On success, this function returns a 64 bit message identifier.
-If an error occurs, -1 is returned and
-.Va errno
-is set.
-.Sh ERRORS
-This function will fail if:
-.Bl -tag -width ".Bq Er ENOTCONN"
-.It Bq Er EINVAL
-An invalid argument was specified.
-.It Bq Er ENOTCONN
-The process originally creating the port forked and the child
-process attempts to access the port.
-The child process is expected to create its own port.
-This error is also returned if the remote end closed its connection
-and is no longer available.
-.It Bq Er ENOBUFS
-The maximum number of in-transmit messages has been reached.
-No more messages can be sent until some of them are replied to.
-.El
-.Sh SEE ALSO
-.Xr caps_sys_client 2 ,
-.Xr caps_sys_get 2 ,
-.Xr caps_sys_service 2
-.Sh HISTORY
-The
-.Fn caps_sys_put
-function call first appeared in
-.Dx 1.0 .
-.Sh AUTHORS
-.An -nosplit
-CAPS IPC was written by
-.An Matthew Dillon .
-This man page was written by
-.An Sascha Wildner .
+++ /dev/null
-.\"
-.\" Copyright (c) 2006 The DragonFly Project. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\"
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in
-.\" the documentation and/or other materials provided with the
-.\" distribution.
-.\" 3. Neither the name of The DragonFly Project nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific, prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
-.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $DragonFly: src/lib/libc/sys/caps_sys_reply.2,v 1.1 2006/02/28 22:40:49 swildner Exp $
-.\"
-.Dd February 28, 2006
-.Dt CAPS_SYS_REPLY 2
-.Os
-.Sh NAME
-.Nm caps_sys_reply
-.Nd reply to a CAPS IPC message
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In sys/caps.h
-.Ft int
-.Fn caps_sys_reply "int portid" "const void *msg" "int msgsize" "off_t msgid"
-.Sh DESCRIPTION
-Reply to the received CAPS message identified by
-.Fa msgid
-on the port specified by
-.Fa portid .
-The reply may supply opaque data in
-.Fa msg .
-The memory associated with the message must be left intact until
-an acknowledgement is returned at a later time.
-The kernel does not make a copy of the message and its size may not
-exceed 128KB.
-.Pp
-This function is only used on the server side.
-The server may reply to a message without retrieving its data.
-.Sh RETURN VALUES
-.Rv -std caps_sys_reply
-.Sh ERRORS
-This function will fail if:
-.Bl -tag -width ".Bq Er ENOTCONN"
-.It Bq Er EINVAL
-An invalid argument was specified.
-.It Bq Er ENOTCONN
-The process originally creating the port forked and the child
-process attempts to access the port.
-The child process is expected to create its own port.
-This error is also returned if the remote end closed its connection
-and is no longer available.
-Note that a child process may not reply to a message received by its
-parent.
-.El
-.Sh SEE ALSO
-.Xr caps_sys_client 2 ,
-.Xr caps_sys_get 2 ,
-.Xr caps_sys_put 2 ,
-.Xr caps_sys_service 2
-.Sh HISTORY
-The
-.Fn caps_sys_reply
-function call first appeared in
-.Dx 1.0 .
-.Sh AUTHORS
-.An -nosplit
-CAPS IPC was written by
-.An Matthew Dillon .
-This man page was written by
-.An Sascha Wildner .
+++ /dev/null
-.\"
-.\" Copyright (c) 2006 The DragonFly Project. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\"
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in
-.\" the documentation and/or other materials provided with the
-.\" distribution.
-.\" 3. Neither the name of The DragonFly Project nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific, prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
-.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $DragonFly: src/lib/libc/sys/caps_sys_service.2,v 1.2 2006/03/02 19:27:35 swildner Exp $
-.\"
-.Dd February 28, 2006
-.Dt CAPS_SYS_SERVICE 2
-.Os
-.Sh NAME
-.Nm caps_sys_service
-.Nd create a CAPS IPC service
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In sys/caps.h
-.Ft int
-.Fo caps_sys_service
-.Fa "const char *name"
-.Fa "uid_t uid"
-.Fa "gid_t gid"
-.Fa "int upcid"
-.Fa "int flags"
-.Fc
-.Sh DESCRIPTION
-Create an IPC service using the specified
-.Fa name ,
-.Fa uid ,
-.Fa gid ,
-and
-.Fa flags .
-Either
-.Fa uid
-or
-.Fa gid
-can be -1 (thereby indicating a wildcard),
-but not both.
-The
-.Fa upcid
-argument can either be an upcall or a kqueue identifier.
-.Sh RETURN VALUES
-On success, this function returns a port identifier.
-On failure, -1 is returned and
-.Va errno
-is set to indicate the error.
-.Sh ERRORS
-This function will fail if:
-.Bl -tag -width ".Bq Er EOPNOTSUPP"
-.It Bq Er EOPNOTSUPP
-The CAPS system has not been enabled with
-.Va kern.caps_enabled .
-.It Bq Er EINVAL
-An invalid argument was specified.
-.El
-.Sh SEE ALSO
-.Xr caps_sys_client 2
-.Sh HISTORY
-The
-.Fn caps_sys_service
-function call first appeared in
-.Dx 1.0 .
-.Sh AUTHORS
-.An -nosplit
-CAPS IPC was written by
-.An Matthew Dillon .
-This man page was written by
-.An Sascha Wildner .
-.Sh BUGS
-Support for the
-.Fa upcid
-argument is currently not implemented.
+++ /dev/null
-.\"
-.\" Copyright (c) 2006 The DragonFly Project. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\"
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in
-.\" the documentation and/or other materials provided with the
-.\" distribution.
-.\" 3. Neither the name of The DragonFly Project nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific, prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
-.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $DragonFly: src/lib/libc/sys/caps_sys_setgen.2,v 1.1 2006/02/28 22:40:49 swildner Exp $
-.\"
-.Dd February 28, 2006
-.Dt CAPS_SYS_SETGEN 2
-.Os
-.Sh NAME
-.Nm caps_sys_setgen
-.Nd set the generation number for a CAPS IPC link
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In sys/caps.h
-.Ft int
-.Fn caps_sys_setgen "int portid" "caps_gen_t gen"
-.Sh DESCRIPTION
-Set the 64 bit generation number
-.Fa gen
-for a CAPS link specified by the
-.Fa portid
-identifier.
-A service typically changes the generation number to indicate that it
-has been restarted.
-.Sh RETURN VALUES
-.Rv -std caps_sys_setgen
-.Sh ERRORS
-This function will fail if:
-.Bl -tag -width ".Bq Er ENOTCONN"
-.It Bq Er EINVAL
-The
-.Fa portid
-could not be found.
-.It Bq Er ENOTCONN
-The process originally creating the port forked and the child
-process attempts to access the port.
-The child process is expected to create its own port.
-.El
-.Sh SEE ALSO
-.Xr caps_sys_getgen 2
-.Sh HISTORY
-The
-.Fn caps_sys_setgen
-function call first appeared in
-.Dx 1.0 .
-.Sh AUTHORS
-.An -nosplit
-CAPS IPC was written by
-.An Matthew Dillon .
-This man page was written by
-.An Sascha Wildner .
+++ /dev/null
-# $DragonFly: src/lib/libcaps/Makefile,v 1.8 2008/05/22 20:01:55 nth Exp $
-#
-LIB=caps
-SHLIB_MAJOR= 2
-AINC= -I${.CURDIR}/${MACHINE_ARCH} -I${.OBJDIR}
-CFLAGS+= -I${.CURDIR}/.. -I${.CURDIR}/${MACHINE_ARCH}
-CFLAGS+= -DSMP -D_UTHREAD
-CFLAGS+= -DCAPS_DEBUG
-INSTALL_PIC_ARCHIVE= yes
-.PATH: ${.CURDIR}/${MACHINE_ARCH} ${.CURDIR}/../../sys/kern
-
-#MISRCS= uthread.c init.c sysport.c slaballoc.c globaldata.c
-
-MISRCS= caps_msgbuf.c caps_struct.c caps_pwent.c
-
-SRCS+= ${.OBJDIR}/asdefs.h
-CLEANFILES+=asdefs asdefs.o ${.CURDIR}/asdefs.h
-
-${.OBJDIR}/asdefs.h: asdefs
- ${.OBJDIR}/${.ALLSRC} > ${.TARGET}
-
-.include "${MACHINE_ARCH}/Makefile.inc"
-
-##################################################################
-# For now this is a clone of what src/lib/libcr/Makefile.inc does.
-# When this is liblwkt becomes part of libcr the rest of this file
-# can be removed.
-##################################################################
-
-# If there are no machine dependent sources, append all the
-# machine-independent sources:
-.if empty{MDSRCS}
-SRCS+= ${MISRCS}
-.else
-# Append machine-dependent sources, then append machine-independent sources
-# for which there is no machine-dependent variant.
-SRCS+= ${MDSRCS}
-.for _src in ${MISRCS}
-.if ${MDSRCS:R:M${_src:R}} == ""
-SRCS+= ${_src}
-.endif
-.endfor
-.endif
-
-.include <bsd.lib.mk>
+++ /dev/null
-/*
- * ASDEFS.C
- *
- * Generate assembly defs.
- *
- * $DragonFly: src/lib/libcaps/asdefs.c,v 1.2 2003/12/07 04:21:52 dillon Exp $
- */
-
-#include <sys/cdefs.h> /* for __dead2 needed by thread.h */
-#include "libcaps/thread.h"
-#include <sys/thread.h>
-#include "libcaps/globaldata.h"
-#include <stddef.h> /* for offsetof(type, field) */
-#include <stdio.h>
-
-#define OFFSET(name, offset) printf("#define %s %d\n", #name, offset);
-
-int
-main(int ac, char **av)
-{
- OFFSET(TD_SP, offsetof(struct thread, td_sp));
- OFFSET(TD_FLAGS, offsetof(struct thread, td_flags));
- OFFSET(TD_MPCOUNT, offsetof(struct thread, td_mpcount));
- OFFSET(TD_PRI, offsetof(struct thread, td_pri));
-
- OFFSET(UPC_MAGIC, offsetof(struct upcall, upc_magic));
- OFFSET(UPC_CRITOFF, offsetof(struct upcall, upc_critoff));
- OFFSET(UPC_PENDING, offsetof(struct upcall, upc_pending));
- OFFSET(UPC_UTHREAD, offsetof(struct upcall, upc_uthread));
-
- OFFSET(TDF_RUNNING, TDF_RUNNING);
- OFFSET(TDPRI_CRIT, TDPRI_CRIT);
-
- OFFSET(gd_curthread, offsetof(struct globaldata, gd_upcall.upc_uthread));
- OFFSET(gd_cpuid, offsetof(struct globaldata, gd_cpuid));
-
- return(0);
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/lib/libcaps/caps_msgbuf.c,v 1.1 2004/03/07 23:36:44 dillon Exp $
- */
-
-#include "defs.h"
-
-void
-caps_init_msgbuf(caps_msgbuf_t msg, void *data, int size)
-{
- msg->base = data;
- msg->index = 0;
- msg->bufsize = size;
- msg->error = 0;
-}
-
-void
-caps_msgbuf_error(caps_msgbuf_t msg, int eno, int undo)
-{
- if (eno)
- msg->error = eno;
- if (msg->index < undo)
- msg->index = 0;
- else
- msg->index -= undo;
-}
-
-/*
- * Extract the next class specification. A class specification is an upper
- * case letter followed by quoted data or non-quoted data. Non-quoted data
- * may only contain the characters 0-9 and LOWER CASE a-z, '.', or '_'.
- * The returned (ptr,len) tuple includes the quotes in quoted data.
- */
-u_int8_t
-caps_msgbuf_getclass(caps_msgbuf_t msg, u_int8_t **pptr, int *plen)
-{
- u_int8_t c;
- u_int8_t cc;
- int i;
-
- while (msg->index < msg->bufsize) {
- c = msg->base[msg->index++];
- if (c >= 'A' && c <= 'Z') {
- i = msg->index;
- *pptr = msg->base + i;
- if (i < msg->bufsize && msg->base[i] == '\"') {
- for (++i; i < msg->bufsize; ++i) {
- cc = msg->base[i];
- if ((cc >= 'a' && cc <= 'z') ||
- (cc >= 'A' && cc <= 'Z') ||
- (cc >= '0' && cc <= '9') ||
- cc == '_' || cc == '.' || cc == '/' || cc == '+' ||
- cc == '-' || cc == '%'
- ) {
- continue;
- }
- if (cc == '"') /* quote end string, else error */
- ++i;
- else
- msg->error = EINVAL;
- break;
- }
- } else {
- for (; i < msg->bufsize; ++i) {
- cc = msg->base[i];
- if (cc >= 'a' && cc <= 'z')
- continue;
- if (cc >= '0' && cc <= '9')
- continue;
- if (cc == '.' || cc == '_')
- continue;
- break;
- }
- }
- *plen = i - msg->index;
- msg->index = i;
- return(c);
- }
- if (c == ',' || c == '{' || c == '}')
- return(c);
- if (c != '\t' && c != ' ' && c != '\r' && c != '\n') {
- msg->error = EINVAL;
- break;
- }
- /* loop on whitespce */
- }
- return(0);
-}
-
-/*
- * Support routines for encoding/decoding
- */
-void
-caps_msgbuf_printf(caps_msgbuf_t msg, const char *ctl, ...)
-{
- va_list va;
- int i;
-
- va_start(va, ctl);
- i = msg->index;
- if (i <= msg->bufsize)
- i += vsnprintf(msg->base + i, msg->bufsize - i, ctl, va);
- else
- i += vsnprintf(NULL, 0, ctl, va);
- msg->index = i;
- va_end(va);
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/lib/libcaps/caps_pwent.c,v 1.1 2004/03/07 23:36:44 dillon Exp $
- */
-
-#include <sys/types.h>
-#include <pwd.h>
-#include <stddef.h>
-#include <stdarg.h>
-#include "caps_struct.h"
-
-/*
- * Password Entry encoding and decoding
- */
-#define CAPS_PW_NAME 1
-#define CAPS_PW_PASSWD 2
-#define CAPS_PW_UID 3
-#define CAPS_PW_GID 4
-#define CAPS_PW_CHANGE 5
-#define CAPS_PW_CLASS 6
-#define CAPS_PW_GECOS 7
-#define CAPS_PW_DIR 8
-#define CAPS_PW_SHELL 9
-#define CAPS_PW_EXPIRE 10
-
-#define STYPE struct passwd
-
-const struct caps_label caps_passwd_label[] = {
- { offsetof(STYPE, pw_name), CAPS_IN_STRPTR_T, CAPS_PW_NAME },
- { offsetof(STYPE, pw_passwd), CAPS_IN_STRPTR_T, CAPS_PW_PASSWD },
- { offsetof(STYPE, pw_uid), CAPS_IN_UID_T, CAPS_PW_UID },
- { offsetof(STYPE, pw_gid), CAPS_IN_GID_T, CAPS_PW_GID },
- { offsetof(STYPE, pw_change), CAPS_IN_TIME_T, CAPS_PW_CHANGE },
- { offsetof(STYPE, pw_class), CAPS_IN_STRPTR_T, CAPS_PW_CLASS },
- { offsetof(STYPE, pw_gecos), CAPS_IN_STRPTR_T, CAPS_PW_GECOS },
- { offsetof(STYPE, pw_dir), CAPS_IN_STRPTR_T, CAPS_PW_DIR },
- { offsetof(STYPE, pw_shell), CAPS_IN_STRPTR_T, CAPS_PW_SHELL },
- { offsetof(STYPE, pw_expire), CAPS_IN_TIME_T, CAPS_PW_EXPIRE },
- { -1 }
-};
-
-#undef STYPE
-
-const struct caps_struct caps_passwd_struct = {
- "passwd", caps_passwd_label
-};
-
+++ /dev/null
-/*
- * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/lib/libcaps/caps_struct.c,v 1.1 2004/03/07 23:36:44 dillon Exp $
- */
-
-#include "defs.h"
-
-static
-int32_t
-parsehex32(const u_int8_t *ptr, int len)
-{
- int neg = 0;
- int32_t v = 0;
- u_int8_t c;
-
- if (len && ptr[0] == '-') {
- neg = 1;
- --len;
- ++ptr;
- }
- while (len) {
- v = v << 4;
- c = *ptr;
- if (c >= '0' && c <= '9')
- v |= c - '0';
- if (c >= 'a' && c <= 'f')
- v |= c - ('a' - 10);
- --len;
- ++ptr;
- }
- if (neg)
- v = -v;
- return(v);
-}
-
-static
-int64_t
-parsehex64(const u_int8_t *ptr, int len)
-{
- int neg = 0;
- int64_t v;
-
- if (len && ptr[0] == '-') {
- neg = 1;
- --len;
- ++ptr;
- }
-
- if (len > 4) {
- v = parsehex32(ptr + len - 4, 4) |
- ((int64_t)parsehex32(ptr, len - 4) << 32);
- } else {
- v = (int64_t)parsehex32(ptr, len);
- }
- if (neg)
- v = -v;
- return(v);
-}
-
-static caps_label_t
-caps_find_label(caps_struct_t cs, caps_fid_t fid, const struct caps_label **pcache)
-{
- caps_label_t label;
-
- if ((label = *pcache) != NULL) {
- if (label->fid == fid)
- return(label);
- ++label;
- if (label->fid == fid && label->offset >= 0) {
- *pcache = label;
- return(label);
- }
- --label;
- if (label != cs->labels) {
- --label;
- if (label->fid == fid && label->offset >= 0) {
- *pcache = label;
- return(label);
- }
- }
- }
- for (label = cs->labels; label->offset >= 0; ++label) {
- if (label->fid == fid) {
- *pcache = label;
- return(label);
- }
- }
- return(NULL);
-}
-
-/*
- * Generic structural encoder. The number of bytes that would be stored in
- * buf if it were infinitely-sized is returned.
- */
-int
-caps_encode(void *buf, int bytes, void *data, caps_struct_t cs)
-{
- struct caps_msgbuf msgbuf;
-
- caps_init_msgbuf(&msgbuf, buf, bytes);
- caps_msg_encode_structure(&msgbuf, data, cs);
- return(msgbuf.index);
-}
-
-/*
- * Encode a structure into a message using the supplied label data. The
- * message's index is updated to reflect the actual number of bytes that
- * would be consumed, even if the message buffer would overflow (but we don't
- * overflow the buffer, obviously).
- */
-void
-caps_msg_encode_structure(caps_msgbuf_t msg, void *data, caps_struct_t cs)
-{
- caps_label_t label;
- void *ptr;
-
- caps_msgbuf_printf(msg, "S%s{", cs->name);
- for (label = cs->labels; label->offset >= 0; ++label) {
- if (label != cs->labels)
- caps_msgbuf_putc(msg, ',');
- caps_msgbuf_printf(msg, "F%x", label->fid);
- ptr = (char *)data + label->offset;
- if (label->nary > 1)
- caps_msg_encode_array(msg, ptr, label);
- else if (label->csinfo)
- caps_msg_encode_structure(msg, ptr, label->csinfo);
- else
- caps_msg_encode_data(msg, ptr, label->type, label->size);
- }
- caps_msgbuf_putc(msg, '}');
-}
-
-void
-caps_msg_encode_array(caps_msgbuf_t msg, void *data, caps_label_t label)
-{
- int i;
- void *ptr;
-
- caps_msgbuf_printf(msg, "A%x{", label->nary);
- for (i = 0; i < label->nary; ++i) {
- ptr = (char *)data + i *
- ((label->type & CAPS_OPF_PTR) ? sizeof(void *) : label->size);
- if (label->csinfo)
- caps_msg_encode_structure(msg, ptr, label->csinfo);
- else
- caps_msg_encode_data(msg, ptr, label->type, label->size);
- }
- caps_msgbuf_putc(msg, '}');
-}
-
-void
-caps_msg_encode_data(caps_msgbuf_t msg, void *data, int type, int size)
-{
- int i;
- u_int8_t c;
-
- switch(type) {
- case CAPS_OP_INT_T:
- switch(size) {
- case 1:
- if (*(int8_t *)data < 0)
- caps_msgbuf_printf(msg, "D-%x", -*(int8_t *)data);
- else
- caps_msgbuf_printf(msg, "D%x", *(u_int8_t *)data);
- break;
- case 2:
- if (*(int16_t *)data < 0)
- caps_msgbuf_printf(msg, "D%x", -*(int16_t *)data);
- else
- caps_msgbuf_printf(msg, "D%x", *(u_int16_t *)data);
- break;
- case 4:
- if (*(int32_t *)data < 0)
- caps_msgbuf_printf(msg, "D%x", -*(int32_t *)data);
- else
- caps_msgbuf_printf(msg, "D%x", *(u_int32_t *)data);
- break;
- case 8:
- if (*(int64_t *)data < 0)
- caps_msgbuf_printf(msg, "D%llx", -*(int64_t *)data);
- else
- caps_msgbuf_printf(msg, "D%llx", *(u_int64_t *)data);
- break;
- default:
- caps_msgbuf_putc(msg, 'D');
- caps_msgbuf_putc(msg, '?');
- break;
- }
- break;
- case CAPS_OP_UINT_T:
- switch(size) {
- case 1:
- caps_msgbuf_printf(msg, "D%x", *(u_int8_t *)data);
- break;
- case 2:
- caps_msgbuf_printf(msg, "D%x", *(u_int16_t *)data);
- break;
- case 4:
- caps_msgbuf_printf(msg, "D%x", *(u_int32_t *)data);
- break;
- case 8:
- caps_msgbuf_printf(msg, "D%llx", *(u_int64_t *)data);
- break;
- default:
- caps_msgbuf_putc(msg, 'D');
- caps_msgbuf_putc(msg, '?');
- break;
- }
- break;
- case CAPS_OP_STRPTR_T:
- data = *(void **)data;
- if (data == NULL) {
- caps_msgbuf_printf(msg, "D"); /* represents NULL */
- break;
- }
- if (size == 0)
- size = 0x7FFFFFFF;
- /* fall through, size is the 'limit' */
- case CAPS_OP_STRBUF_T:
- caps_msgbuf_putc(msg, 'D');
- caps_msgbuf_putc(msg, '"'); /* string designator */
- for (i = 0; i < size && (c = ((u_int8_t *)data)[i]) != 0; ++i) {
- if ((c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z') ||
- (c >= '0' && c <= '9') ||
- c == '_' || c == '.' || c == '/' || c == '+' || c == '-'
- ) {
- caps_msgbuf_putc(msg, c);
- } else {
- caps_msgbuf_printf(msg, "%%%02x", (int)c);
- }
- }
- caps_msgbuf_putc(msg, '"');
- break;
- case CAPS_OP_OPAQUE_T:
- caps_msgbuf_putc(msg, 'D');
- caps_msgbuf_putc(msg, '"');
- for (i = 0; i < size; ++i) {
- c = ((u_int8_t *)data)[i];
- if ((c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z') ||
- (c >= '0' && c <= '9') ||
- c == '_' || c == '.' || c == '/' || c == '+' || c == '-'
- ) {
- caps_msgbuf_putc(msg, c);
- } else {
- caps_msgbuf_printf(msg, "%%%02x", (int)c);
- }
- }
- caps_msgbuf_putc(msg, '"');
- break;
- default:
- caps_msgbuf_putc(msg, 'D');
- caps_msgbuf_putc(msg, '?');
- break;
- }
-}
-
-/*
- * Generic structural decoder. The number of bytes that were decoded from
- * the buffer are returned, the structure is populated, and the error code
- * is set unconditionally as a side effect.
- */
-int
-caps_decode(const void *buf, int bytes, void *data, caps_struct_t cs, int *error)
-{
- struct caps_msgbuf msgbuf;
- u_int8_t c;
- u_int8_t *ptr;
- int len;
-
- caps_init_msgbuf(&msgbuf, (void *)buf, bytes);
- while ((c = caps_msgbuf_getclass(&msgbuf, &ptr, &len)) != 0) {
- if (c == 'S' && len == strlen(cs->name) &&
- strncmp(ptr, cs->name, len) == 0
- ) {
- caps_msg_decode_structure(&msgbuf, data, cs);
- *error = msgbuf.error;
- return(msgbuf.index);
- }
- /*
- * Skip substructures.
- */
- if (c == '{') {
- caps_msgbuf_error(&msgbuf, 0, 1);
- caps_msg_decode_structure(&msgbuf, NULL, NULL);
- }
- }
- if (msgbuf.error == 0)
- *error = ENOENT;
- *error = msgbuf.error;
- return(msgbuf.index);
-}
-
-/*
- * Decode a message buffer into a structure, return the number of bytes
- * chomped and set *error to 0 on success, or an error code on failure.
- * The 'Sname' has already been snarfed. We are responsible for snarfing
- * the '{'.
- *
- * Note that the structural specification, cs, may be NULL, indicating and
- * unknown structure which causes us to skip the structure.
- */
-void
-caps_msg_decode_structure(caps_msgbuf_t msg, void *data, caps_struct_t cs)
-{
- caps_label_t label;
- caps_label_t cache;
- u_int8_t *ptr;
- int len;
- char c;
-
- cache = NULL;
-
- /*
- * A structure must contain an open brace
- */
- if (caps_msgbuf_getc(msg) != '{') {
- caps_msgbuf_error(msg, EINVAL, 1);
- return;
- }
-
- /*
- * Parse data elements within the structure
- */
- do {
- /*
- * Parse class info for the next element. Note that the label
- * specification may be NULL.
- */
- label = NULL;
- while ((c = caps_msgbuf_getclass(msg, &ptr, &len)) != 0) {
- switch(c) {
- case 'F':
- label = caps_find_label(cs, parsehex32(ptr, len), &cache);
- continue;
- case 'A':
- caps_msg_decode_array(msg,
- (char *)data + label->offset,
- parsehex32(ptr, len),
- label);
- continue;
- case 'S':
- if (label && label->csinfo &&
- strlen(label->csinfo->name) == len &&
- strncmp(label->csinfo->name, ptr, len) == 0
- ) {
- caps_msg_decode_structure(msg,
- (char *)data + label->offset,
- label->csinfo);
- } else {
- caps_msg_decode_structure(msg, NULL, NULL);
- }
- continue;
- case 'D':
- if (label) {
- caps_msg_decode_data(ptr, len,
- (char *)data + label->offset,
- label->type,
- label->size);
- }
- continue;
- case '{':
- /*
- * This case occurs when we previously hit an unknown class
- * which has a sub-structure associated with it. Parseskip
- * the sub-structure.
- */
- caps_msgbuf_error(msg, 0, 1);
- caps_msg_decode_structure(msg, NULL, NULL);
- continue;
- case '}':
- case ',':
- break;
- default:
- /* unknown classes are ignored */
- continue;
- }
- break;
- }
- } while (c == ',');
-
- /*
- * A structure must end with a close brace
- */
- if (c != '}')
- caps_msgbuf_error(msg, EINVAL, 1);
-}
-
-void
-caps_msg_decode_array(caps_msgbuf_t msg, void *data, int nary, caps_label_t label)
-{
- int i;
- char c;
- int len;
- u_int8_t *ptr;
-
- c = 0;
-
- /*
- * An array must contain an open brace
- */
- if (caps_msgbuf_getc(msg) != '{') {
- caps_msgbuf_error(msg, EINVAL, 1);
- return;
- }
- for (i = 0; i < nary && (label == NULL || i < label->nary); ++i) {
- while ((c = caps_msgbuf_getclass(msg, &ptr, &len)) != 0) {
- switch(c) {
- case 'F':
- /* a field id for an array element is not expected */
- continue;
- case 'A':
- /* nested arrays are not yet supported */
- continue;
- case 'S':
- if (label && label->csinfo &&
- strlen(label->csinfo->name) == len &&
- strncmp(label->csinfo->name, ptr, len) == 0
- ) {
- caps_msg_decode_structure(msg, data, label->csinfo);
- } else {
- caps_msg_decode_structure(msg, NULL, NULL);
- }
- continue;
- case 'D':
- if (label) {
- caps_msg_decode_data(ptr, len, data,
- label->type, label->size);
- }
- continue;
- case '{':
- /*
- * This case occurs when we previously hit an unknown class
- * which has a sub-structure associated with it. Parseskip
- * the sub-structure.
- */
- caps_msgbuf_error(msg, 0, 1);
- caps_msg_decode_structure(msg, NULL, NULL);
- continue;
- case '}':
- case ',':
- break;
- default:
- /* unknown classes are ignored */
- continue;
- }
- break;
- }
-
- if (label) {
- data = (char *)data +
- ((label->type & CAPS_OPF_PTR) ? sizeof(void *) : label->size);
- }
-
- /*
- * I really expected a comma here
- */
- if (c != ',') {
- caps_msgbuf_error(msg, EINVAL, 0);
- break;
- }
- }
-
- /*
- * Our array was too small, exhaust any remaining elements
- */
- for (; i < nary; ++i) {
- while ((c = caps_msgbuf_getclass(msg, &ptr, &len)) != 0) {
- switch(c) {
- case 'S':
- caps_msg_decode_structure(msg, NULL, NULL);
- continue;
- case 'D':
- /* data is embedded, no additional decoding needed to skip */
- continue;
- case '{':
- caps_msgbuf_error(msg, 0, 1);
- caps_msg_decode_structure(msg, NULL, NULL);
- continue;
- case '}':
- case ',':
- break;
- default:
- /* unknown classes are ignored */
- continue;
- }
- break;
- }
- if (c != ',') {
- caps_msgbuf_error(msg, EINVAL, 0);
- break;
- }
- }
-
- /*
- * Finish up. Note degenerate case (c not loaded) if nary is 0
- */
- if (nary == 0)
- c = caps_msgbuf_getc(msg);
- if (c != '}')
- caps_msgbuf_error(msg, EINVAL, 1);
-}
-
-void
-caps_msg_decode_data(char *ptr, int len, void *data, int type, int size)
-{
- int i;
- int j;
-
- switch(type) {
- case CAPS_OP_INT_T:
- case CAPS_OP_UINT_T:
- switch(size) {
- case 1:
- *(int8_t *)data = parsehex32(ptr, len);
- break;
- case 2:
- *(int16_t *)data = parsehex32(ptr, len);
- break;
- case 4:
- *(int32_t *)data = parsehex32(ptr, len);
- break;
- case 8:
- *(int64_t *)data = parsehex64(ptr, len);
- break;
- default:
- /* unknown data type */
- break;
- }
- break;
- case CAPS_OP_STRPTR_T:
- /*
- * Assume NULL if not a quoted string (the actual encoding for NULL
- * is a completely empty 'D' specification).
- */
- if (len < 2 || ptr[0] != '"' || ptr[len-1] != '"') {
- *(void **)data = NULL;
- break;
- }
- for (i = j = 0; i < len; ++j) {
- if (ptr[i] == '%') {
- i += 3;
- } else {
- ++i;
- }
- }
- if (size == 0 || size > j)
- size = j + 1;
- *(void **)data = malloc(size);
- data = *(void **)data;
- assert(data != NULL);
- /* fall through */
- case CAPS_OP_STRBUF_T:
- case CAPS_OP_OPAQUE_T:
- /*
- * Skip quotes
- */
- if (len < 2 || ptr[0] != '"' || ptr[len-1] != '"') {
- break;
- }
- ++ptr;
- len -= 2;
-
- /*
- * Parse the contents of the string
- */
- for (i = j = 0; i < len && j < size; ++j) {
- if (ptr[i] == '%') {
- if (i + 2 < len) {
- ((char *)data)[j] = parsehex32(ptr + 1, 2);
- i += 3;
- } else {
- /* XXX error */
- i = len;
- }
- } else {
- ((char *)data)[j] = ptr[i];
- ++i;
- }
- }
- if (type == CAPS_OP_OPAQUE_T) {
- if (j < size)
- bzero((char *)data + j, size - j);
- } else {
- if (j < size)
- ((char *)data)[j] = 0;
- else if (size)
- ((char *)data)[size - 1] = 0; /* XXX error */
- }
- break;
- default:
- break;
- }
-}
-
-/*
- * Free string pointers dynamically allocated by caps_msg_decode_structure().
- */
-void
-caps_struct_free_pointers(void *data, caps_struct_t cs)
-{
- caps_label_t label;
- void *ptr;
-
- for (label = cs->labels; label->offset >= 0; ++label) {
- ptr = (char *)data + label->offset;
- if (label->nary > 1) {
- caps_array_free_pointers(ptr, label);
- } else if (label->csinfo) {
- caps_struct_free_pointers(ptr, label->csinfo);
- } else if (label->type & CAPS_OPF_PTR) {
- if (*(void **)ptr) {
- free(*(void **)ptr);
- *(void **)ptr = NULL;
- }
- }
- }
-}
-
-void
-caps_array_free_pointers(void *data, caps_label_t label)
-{
- int i;
-
- for (i = 0; i < label->nary; ++i) {
- if (label->csinfo) {
- caps_struct_free_pointers(data, label->csinfo);
- } else if (label->type & CAPS_OPF_PTR) {
- if (*(void **)data) {
- free(*(void **)data);
- *(void **)data = NULL;
- }
- }
- data = (char *)data +
- ((label->type & CAPS_OPF_PTR) ? sizeof(void *) : label->size);
- }
-}
+++ /dev/null
-/*
- * CAPS_STRUCT.H
- *
- * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/lib/libcaps/caps_struct.h,v 1.1 2004/03/07 23:36:44 dillon Exp $
- */
-#include <sys/endian.h>
-
-struct caps_label;
-struct caps_struct;
-struct caps_msgbuf;
-
-typedef const struct caps_label *caps_label_t;
-typedef const struct caps_struct *caps_struct_t;
-typedef struct caps_msgbuf *caps_msgbuf_t;
-
-typedef u_int32_t caps_fid_t;
-
-struct caps_label {
- int offset;
- int type;
- int size; /* element size for array[1] */
- caps_fid_t fid;
- int nary; /* can be 0 or 1 to indicate 1 element */
- caps_struct_t csinfo; /* if embedded structure */
-};
-
-struct caps_struct {
- char *name;
- const caps_label_t labels;
-};
-
-struct caps_msgbuf {
- u_int8_t *base;
- int index;
- int bufsize;
- int error;
-};
-
-#define CAPS_OPF_PTR 0x0100
-
-#define CAPS_OP_INT_T 1
-#define CAPS_OP_UINT_T 2
-#define CAPS_OP_STRBUF_T 3
-#define CAPS_OP_STRPTR_T (3|CAPS_OPF_PTR)
-#define CAPS_OP_OPAQUE_T 4
-
-/*
- * Note: signed/unsignedness may not reflect the actual type. Instead it
- * reflects our casting policy if the client and server are using different
- * integer sizes for any given field.
- */
-#define CAPS_IN_INT_T CAPS_OP_INT_T, sizeof(int)
-#define CAPS_IN_INT8_T CAPS_OP_INT_T, sizeof(int8_t)
-#define CAPS_IN_INT16_T CAPS_OP_INT_T, sizeof(int16_t)
-#define CAPS_IN_INT32_T CAPS_OP_INT_T, sizeof(int32_t)
-#define CAPS_IN_LONG_T CAPS_OP_INT_T, sizeof(long)
-#define CAPS_IN_INT64_T CAPS_OP_INT_T, sizeof(int64_t)
-
-#define CAPS_IN_UINT_T CAPS_OP_INT_T, sizeof(u_int)
-#define CAPS_IN_UINT8_T CAPS_OP_INT_T, sizeof(u_int8_t)
-#define CAPS_IN_UINT16_T CAPS_OP_INT_T, sizeof(u_int16_t)
-#define CAPS_IN_UINT32_T CAPS_OP_INT_T, sizeof(u_int32_t)
-#define CAPS_IN_ULONG_T CAPS_OP_INT_T, sizeof(u_long)
-#define CAPS_IN_UINT64_T CAPS_OP_INT_T, sizeof(u_int64_t)
-
-#define CAPS_IN_STRPTR_T CAPS_OP_STRPTR_T, 0
-#define CAPS_IN_STRBUF_T(n) CAPS_OP_STRBUF_T, (n)
-#define CAPS_IN_UID_T CAPS_OP_INT_T, sizeof(uid_t)
-#define CAPS_IN_GID_T CAPS_OP_INT_T, sizeof(gid_t)
-#define CAPS_IN_TIME_T CAPS_OP_UINT_T, sizeof(time_t)
-#define CAPS_IN_OFF_T CAPS_OP_INT_T, sizeof(off_t)
-#define CAPS_IN_SIZE_T CAPS_OP_UINT_T, sizeof(size_t)
-#define CAPS_IN_SSIZE_T CAPS_OP_INT_T, sizeof(ssize_t)
-
-static __inline
-u_int8_t
-caps_msgbuf_getc(caps_msgbuf_t msg)
-{
- u_int8_t c = 0;
-
- if (msg->index < msg->bufsize)
- c = msg->base[msg->index];
- ++msg->index;
- return(c); /* always bumped */
-}
-
-static __inline
-void
-caps_msgbuf_putc(caps_msgbuf_t msg, u_int8_t c)
-{
- if (msg->index < msg->bufsize) {
- msg->base[msg->index] = c;
- }
- ++msg->index; /* always bumped */
-}
-
-extern const struct caps_struct caps_passwd_struct;
-
-int caps_encode(void *buf, int bytes, void *data, caps_struct_t cs);
-int caps_decode(const void *buf, int bytes, void *data, caps_struct_t cs, int *error);
-void caps_struct_free_pointers(void *data, caps_struct_t cs);
-void caps_array_free_pointers(void *data, caps_label_t label);
-
-void caps_init_msgbuf(caps_msgbuf_t msg, void *data, int size);
-void caps_msgbuf_error(caps_msgbuf_t msg, int eno, int undo);
-u_int8_t caps_msgbuf_getclass(caps_msgbuf_t msg, u_int8_t **pptr, int *plen);
-void caps_msgbuf_printf(caps_msgbuf_t msg, const char *ctl, ...);
-
-void caps_msg_encode_structure(caps_msgbuf_t msg, void *data, caps_struct_t cs);
-void caps_msg_encode_array(caps_msgbuf_t msg, void *data, caps_label_t label);
-void caps_msg_encode_data(caps_msgbuf_t msg, void *data, int type, int size);
-void caps_msg_decode_structure(caps_msgbuf_t msg, void *data, caps_struct_t cs);
-void caps_msg_decode_array(caps_msgbuf_t msg, void *data, int nary, caps_label_t label);
-void caps_msg_decode_data(char *ptr, int len, void *data, int type, int size);
-
+++ /dev/null
-/*
- * DEFS.H
- *
- * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/lib/libcaps/defs.h,v 1.5 2004/07/04 22:44:26 eirikn Exp $
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/stdint.h>
-#include <sys/upcall.h>
-#include <sys/malloc.h>
-#include "thread.h"
-#include <sys/thread.h>
-#include <sys/msgport.h>
-#include <sys/errno.h>
-#include "globaldata.h"
-#include "sysport.h"
-#include <machine/cpufunc.h>
-#include <sys/thread2.h>
-#include <sys/msgport2.h>
-#include <sys/caps.h>
-
-#include <sys/time.h>
-#include <sys/event.h>
-#if 0
-#include <sys/socket.h>
-#include <sys/un.h>
-#endif
-
-#include <fcntl.h>
-#include <stdio.h> /* temporary debugging */
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdarg.h>
-#include <string.h>
-#include <unistd.h> /* temporary debugging */
-#include <signal.h>
-#include <assert.h>
-
-#include "caps_struct.h"
-
-#ifdef CAPS_DEBUG
-#define DBPRINTF(x) printf x
-#else
-#define DBPRINTF(x)
-#endif
-
-extern struct thread main_td;
+++ /dev/null
-/*
- * GLOBALDATA.C
- *
- * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/lib/libcaps/globaldata.c,v 1.7 2004/07/29 08:55:02 dillon Exp $
- */
-
-#include "defs.h"
-
-struct globaldata gdary[MAXVCPU];
-u_int mp_lock;
-int ncpus = 1;
-cpumask_t stopped_cpus;
-cpumask_t smp_active_mask;
-char *panicstr;
-
-/*
- * Master globaldata init
- */
-void
-globaldata_init(thread_t td)
-{
- mi_gdinit1(&gdary[0], 0);
- mi_gdinit2(&gdary[0]);
-
- /*
- * If a 'main' thread is passed make it the current thread and mark it
- * as currently running, but not on the run queue.
- */
- if (td) {
- gdary[0].gd_curthread = td;
- lwkt_init_thread(td, NULL, 0, TDF_RUNNING|TDF_SYSTHREAD, mycpu);
- }
-}
-
-/*
- * per-cpu globaldata init. Calls lwkt_gdinit() and md_gdinit*(). Returns
- * with the target cpu left in a critical section.
- */
-void
-mi_gdinit1(globaldata_t gd, int cpuid)
-{
- bzero(gd, sizeof(*gd));
- TAILQ_INIT(&gd->gd_tdfreeq);
- gd->gd_cpuid = cpuid;
- gd->gd_cpumask = (cpumask_t)1 << cpuid;
- gd->gd_self = gd;
- gd->gd_upcall.upc_magic = UPCALL_MAGIC;
- gd->gd_upcall.upc_critoff = offsetof(struct thread, td_pri);
- gd->gd_ipiq = malloc(sizeof(lwkt_ipiq) * MAXVCPU);
- bzero(gd->gd_ipiq, sizeof(lwkt_ipiq) * MAXVCPU);
- md_gdinit1(gd);
-}
-
-void
-mi_gdinit2(globaldata_t gd)
-{
- gd->gd_upcid = upc_register(&gd->gd_upcall, upc_callused_wrapper,
- (void *)lwkt_process_ipiq, gd);
- if (gd->gd_upcid < 0)
- panic("upc_register: failed on cpu %d\n", gd->gd_cpuid);
- md_gdinit2(gd);
- lwkt_gdinit(gd);
-}
-
-globaldata_t
-globaldata_find(int cpu)
-{
- KKASSERT(cpu >= 0 && cpu < ncpus);
- return(&gdary[cpu]);
-}
-
-void *
-libcaps_alloc_stack(int stksize)
-{
- return(malloc(stksize));
-}
-
-void
-libcaps_free_stack(void *stk, int stksize)
-{
- free(stk);
-}
-
-/*
- * Process any pending upcalls now. Remember there is a dispatch interlock
- * if upc_pending is non-zero, so we have to set it to zero. If we are in
- * a critical section this function is a NOP.
- */
-void
-splz(void)
-{
- globaldata_t gd = mycpu;
-
- if (gd->gd_upcall.upc_pending) {
- gd->gd_upcall.upc_pending = 0;
- upc_control(UPC_CONTROL_DISPATCH, -1, (void *)1);
- }
-}
-
-int
-need_lwkt_resched(void)
-{
- return(0);
-}
-
-void
-cpu_send_ipiq(int dcpu)
-{
- upc_control(UPC_CONTROL_DISPATCH, gdary[dcpu].gd_upcid, (void *)TDPRI_CRIT);
-}
-
-void
-cpu_halt(void)
-{
- upc_control(UPC_CONTROL_WAIT, -1, (void *)TDPRI_CRIT);
-}
-
-__dead2 void
-panic(const char *ctl, ...)
-{
- va_list va;
-
- va_start(va, ctl);
- vfprintf(stderr, ctl, va);
- va_end(va);
- abort();
-}
-
-/*
- * Create a new virtual cpu. The cpuid is returned and may be used
- * in later lwkt_create() calls.
- */
-static int
-caps_vcpu_start(void *vgd)
-{
- mi_gdinit2(vgd); /* sets %gs */
- cpu_rfork_start();
-}
-
-int
-caps_fork_vcpu(void)
-{
- int cpuid;
- globaldata_t gd;
- char stack[8192];
-
- if ((cpuid = ncpus) >= MAXVCPU)
- return(-1);
- ++ncpus;
- gd = &gdary[cpuid];
- mi_gdinit1(gd, cpuid);
- rfork_thread(RFMEM|RFPROC|RFSIGSHARE, stack + sizeof(stack),
- caps_vcpu_start, gd);
- while (gd->gd_pid == 0)
- ;
- /* XXX wait for upcall setup */
- return(cpuid);
-}
-
+++ /dev/null
-/*
- * GLOBALDATA.H
- */
-/*
- * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/lib/libcaps/globaldata.h,v 1.9 2004/09/21 18:40:30 joerg Exp $
- */
-
-#ifndef _LIBCAPS_GLOBALDATA_H_
-#define _LIBCAPS_GLOBALDATA_H_
-
-#ifndef _LIBCAPS_THREAD_H_
-#include "thread.h"
-#endif
-#ifndef _SYS_THREAD_H_
-#include <sys/thread.h>
-#endif
-#ifndef _SYS_UPCALL_H_
-#include <sys/upcall.h>
-#endif
-#ifndef _LIBCAPS_SLABALLOC_H_
-#include "slaballoc.h"
-#endif
-#ifndef _ASSERT_H_
-#include <assert.h>
-#endif
-#ifndef _SYS_QUEUE_H_
-#include <sys/queue.h>
-#endif
-#ifndef _MACHINE_LOCK_H_
-#include <machine/lock.h>
-#endif
-
-struct globaldata;
-typedef struct globaldata *globaldata_t;
-
-#include "md_globaldata.h"
-
-extern int smp_active;
-extern int ncpus;
-extern int hz;
-extern u_int32_t stopped_cpus;
-extern char *panicstr;
-
-struct globaldata {
- struct globaldata *gd_self; /* self pointer */
- struct upcall gd_upcall; /* upcall for this cpu */
- int gd_upcid; /* upcall id */
- int gd_pid; /* user pid for rfork'd cpu */
- int gd_tdfreecount;
- TAILQ_HEAD(,thread) gd_tdallq; /* all threads */
- TAILQ_HEAD(,thread) gd_tdfreeq; /* new thread cache */
- TAILQ_HEAD(,thread) gd_tdrunq[32]; /* runnable threads */
- __uint32_t gd_runqmask; /* which queues? */
- __uint32_t gd_cpuid;
- cpumask_t gd_cpumask; /* mask = 1<<cpuid */
- cpumask_t gd_other_cpus;
- int gd_intr_nesting_level;
- struct thread gd_idlethread;
- SLGlobalData gd_slab; /* slab allocator */
- int gd_num_threads; /* Number of threads */
- int gd_sys_threads; /* Number of threads */
- struct lwkt_ipiq *gd_ipiq;
- lwkt_tokref_t gd_tokreqbase; /* requests from other cpus */
- struct lwkt_ipiq gd_cpusyncq; /* ipiq for cpu synchro */
-};
-
-#define gd_reqflags gd_upcall.upc_pending
-#define gd_curthread gd_upcall.upc_uthread
-
-#define RQB_IPIQ 0
-#define RQB_INTPEND 1
-#define RQB_AST_OWEUPC 2
-#define RQB_AST_SIGNAL 3
-#define RQB_AST_USER_RESCHED 4
-#define RQB_AST_LWKT_RESCHED 5
-#define RQB_AST_UPCALL 6
-
-#define RQF_IPIQ (1 << RQB_IPIQ)
-#define RQF_INTPEND (1 << RQB_INTPEND)
-#define RQF_AST_OWEUPC (1 << RQB_AST_OWEUPC)
-#define RQF_AST_SIGNAL (1 << RQB_AST_SIGNAL)
-#define RQF_AST_USER_RESCHED (1 << RQB_AST_USER_RESCHED)
-#define RQF_AST_LWKT_RESCHED (1 << RQB_AST_LWKT_RESCHED)
-#define RQF_AST_UPCALL (1 << RQB_AST_UPCALL)
-#define RQF_AST_MASK (RQF_AST_OWEUPC|RQF_AST_SIGNAL|\
- RQF_AST_USER_RESCHED|RQF_AST_LWKT_RESCHED|\
- RQF_AST_UPCALL)
-#define RQF_IDLECHECK_MASK (RQF_IPIQ|RQF_INTPEND)
-
-#define KASSERT(exp, printargs) \
- do { if (!(exp)) { panic printargs; } } while(0)
-#define KKASSERT(exp) assert(exp)
-
-#define MAXVCPU 32
-
-#define curthread (mycpu->gd_curthread)
-
-extern cpumask_t smp_active_mask;
-
-extern struct globaldata *globaldata_find(int cpu);
-
-void globaldata_init(struct thread *td);
-void splz(void);
-int need_lwkt_resched(void);
-void cpu_halt(void);
-void cpu_send_ipiq(int dcpu);
-void mi_gdinit1(globaldata_t gd, int cpuid);
-void mi_gdinit2(globaldata_t gd);
-__dead2 void panic(const char *, ...);
-
-#endif
+++ /dev/null
-# $DragonFly: src/lib/libcaps/i386/Makefile.inc,v 1.2 2006/01/28 18:07:45 dillon Exp $
-#
-#MDSRCS= td_switch.c md_globaldata.c \
-# td_switch_asm.S upcall.S mplock.S
-MDSRCS=
+++ /dev/null
-/*
- * ASMACROS.H
- *
- * $DragonFly: src/lib/libcaps/i386/asmacros.h,v 1.1 2003/12/04 22:06:22 dillon Exp $
- */
-#include <machine/asmacros.h>
-
-#define PCPU(name) %gs:gd_ ## name
-
+++ /dev/null
-/*
- * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/lib/libcaps/i386/md_globaldata.c,v 1.2 2003/12/07 04:21:54 dillon Exp $
- */
-#include "../defs.h"
-#include <machine/segments.h>
-#include <machine/sysarch.h>
-
-int __mycpu__dummy; /* for the MP lock functions */
-
-void
-md_gdinit1(globaldata_t gd)
-{
- union descriptor desc;
- int error;
-
- bzero(&desc, sizeof(desc));
- desc.sd.sd_lolimit = sizeof(struct globaldata);
- desc.sd.sd_lobase = (uintptr_t)gd & 0xFFFFFF;
- desc.sd.sd_hibase = (uintptr_t)gd >> 24;
- desc.sd.sd_type = SDT_MEMRW;
- desc.sd.sd_dpl = SEL_UPL;
- desc.sd.sd_p = 1;
- desc.sd.sd_hilimit = 0;
- desc.sd.sd_xx = 0;
- desc.sd.sd_def32 = 1;
- desc.sd.sd_gran = 0;
-
- error = i386_set_ldt(gd->gd_cpuid, &desc, 1);
- if (error < 0)
- panic("i386_set_ldt cpu %d failed\n", gd->gd_cpuid);
-}
-
-void
-md_gdinit2(globaldata_t gd)
-{
- _set_mycpu(LSEL(gd->gd_cpuid, SEL_UPL));
-}
-
+++ /dev/null
-/*
- * MD_GLOBALDATA.H
- *
- * $DragonFly: src/lib/libcaps/i386/md_globaldata.h,v 1.3 2007/04/13 12:12:27 corecode Exp $
- */
-
-#ifndef _MD_GLOBALDATA_H_
-#define _MD_GLOBALDATA_H_
-
-extern int __mycpu__dummy;
-
-static __inline
-globaldata_t
-_get_mycpu(void)
-{
- globaldata_t gd;
-
- __asm ("movl %%gs:0,%0" : "=r" (gd) : "m"(__mycpu__dummy));
- return(gd);
-}
-
-static __inline
-void
-_set_mycpu(int selector)
-{
- __asm __volatile("mov %0,%%gs" :: "g"(selector));
-}
-
-#define mycpu _get_mycpu()
-
-void md_gdinit1(globaldata_t gd);
-void md_gdinit2(globaldata_t gd);
-void cpu_user_switch(void);
-void cpu_rfork_start(void) __dead2;
-
-#endif
-
+++ /dev/null
-/*
- * $FreeBSD: src/sys/i386/i386/mplock.s,v 1.29.2.2 2000/05/16 06:58:06 dillon Exp $
- * $DragonFly: src/lib/libcaps/i386/mplock.S,v 1.2 2003/12/07 04:21:54 dillon Exp $
- *
- * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * DragonFly MPLOCK operation
- *
- * Each thread as an MP lock count, td_mpcount, and there is a shared
- * global called mp_lock. mp_lock is the physical MP lock and contains either
- * -1 or the cpuid of the cpu owning the lock. The count is *NOT* integrated
- * into mp_lock but instead resides in each thread td_mpcount.
- *
- * When obtaining or releasing the MP lock the td_mpcount is PREDISPOSED
- * to the desired count *PRIOR* to operating on the mp_lock itself. MP
- * lock operations can occur outside a critical section with interrupts
- * enabled with the provisio (which the routines below handle) that an
- * interrupt may come along and preempt us, racing our cmpxchgl instruction
- * to perform the operation we have requested by pre-dispoing td_mpcount.
- *
- * Additionally, the LWKT threading system manages the MP lock and
- * lwkt_switch(), in particular, may be called after pre-dispoing td_mpcount
- * to handle 'blocking' on the MP lock.
- *
- *
- * Recoded from the FreeBSD original:
- * ----------------------------------------------------------------------------
- * "THE BEER-WARE LICENSE" (Revision 42):
- * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
- * ----------------------------------------------------------------------------
- */
-
-#include "asmacros.h"
-#include "asdefs.h"
-
- .data
- ALIGN_DATA
-#ifdef SMP
- .globl mp_lock
-mp_lock:
- .long -1 /* initialized to not held */
-#endif
-
- .text
- SUPERALIGN_TEXT
-
- /*
- * Note on cmpxchgl... exchanges ecx with mem if mem matches eax.
- * Z=1 (jz) on success. A lock prefix is required for MP.
- */
-NON_GPROF_ENTRY(cpu_get_initial_mplock)
- movl PCPU(curthread),%ecx
- movl $1,TD_MPCOUNT(%ecx) /* curthread has mpcount of 1 */
- movl $0,mp_lock /* owned by cpu 0 */
- ret
-
- /*
- * cpu_try_mplock() returns non-zero on success, 0 on failure. It
- * only adjusts mp_lock, it does not touch td_mpcount. Callers
- * should always increment td_mpcount *before* trying to acquire
- * the actual lock, predisposing td_mpcount to the desired state of
- * the lock.
- *
- * NOTE! Only call cpu_try_mplock() inside a critical section. If
- * you don't an interrupt can come along and get and release
- * the lock before our cmpxchgl instruction, causing us to fail
- * but resulting in the lock being held by our cpu.
- */
-NON_GPROF_ENTRY(cpu_try_mplock)
- movl PCPU(cpuid),%ecx
- movl $-1,%eax
- lock cmpxchgl %ecx,mp_lock /* ecx<->mem if eax matches */
- jnz 1f
-#ifdef PARANOID_INVLTLB
- movl %cr3,%eax; movl %eax,%cr3 /* YYY check and remove */
-#endif
- movl $1,%eax
- ret
-1:
- subl %eax,%eax
- ret
-
- /*
- * get_mplock() Obtains the MP lock and may switch away if it cannot
- * get it. This routine may be called WITHOUT a critical section
- * and with cpu interrupts enabled.
- *
- * To handle races in a sane fashion we predispose TD_MPCOUNT,
- * which prevents us from losing the lock in a race if we already
- * have it or happen to get it. It also means that we might get
- * the lock in an interrupt race before we have a chance to execute
- * our cmpxchgl instruction, so we have to handle that case.
- * Fortunately simply calling lwkt_switch() handles the situation
- * for us and also 'blocks' us until the MP lock can be obtained.
- */
-NON_GPROF_ENTRY(get_mplock)
- movl PCPU(cpuid),%ecx
- movl PCPU(curthread),%edx
- incl TD_MPCOUNT(%edx) /* predispose */
- cmpl %ecx,mp_lock
- jne 1f
- ret /* success! */
-
- /*
- * We don't already own the mp_lock, use cmpxchgl to try to get
- * it.
- */
-1:
- movl $-1,%eax
- lock cmpxchgl %ecx,mp_lock
- jnz 2f
-#ifdef PARANOID_INVLTLB
- movl %cr3,%eax; movl %eax,%cr3 /* YYY check and remove */
-#endif
- ret /* success */
-
- /*
- * Failure, but we could end up owning mp_lock anyway due to
- * an interrupt race. lwkt_switch() will clean up the mess
- * and 'block' until the mp_lock is obtained.
- */
-2:
- call lwkt_switch
-#ifdef INVARIANTS
- movl PCPU(cpuid),%eax /* failure */
- cmpl %eax,mp_lock
- jne 4f
-#endif
- ret
-#ifdef INVARIANTS
-4:
- cmpl $0,panicstr /* don't double panic */
- je badmp_get2
- ret
-#endif
-
- /*
- * try_mplock() attempts to obtain the MP lock. 1 is returned on
- * success, 0 on failure. We do not have to be in a critical section
- * and interrupts are almost certainly enabled.
- *
- * We must pre-dispose TD_MPCOUNT in order to deal with races in
- * a reasonable way.
- *
- */
-NON_GPROF_ENTRY(try_mplock)
- movl PCPU(cpuid),%ecx
- movl PCPU(curthread),%edx
- incl TD_MPCOUNT(%edx) /* pre-dispose for race */
- cmpl %ecx,mp_lock
- je 1f /* trivial success */
- movl $-1,%eax
- lock cmpxchgl %ecx,mp_lock
- jnz 2f
- /*
- * Success
- */
-#ifdef PARANOID_INVLTLB
- movl %cr3,%eax; movl %eax,%cr3 /* YYY check and remove */
-#endif
-1:
- movl $1,%eax /* success (cmpxchgl good!) */
- ret
-
- /*
- * The cmpxchgl failed but we might have raced. Undo the mess by
- * predispoing TD_MPCOUNT and then checking. If TD_MPCOUNT is
- * still non-zero we don't care what state the lock is in (since
- * we obviously didn't own it above), just return failure even if
- * we won the lock in an interrupt race. If TD_MPCOUNT is zero
- * make sure we don't own the lock in case we did win it in a race.
- */
-2:
- decl TD_MPCOUNT(%edx)
- cmpl $0,TD_MPCOUNT(%edx)
- jne 3f
- movl PCPU(cpuid),%eax
- movl $-1,%ecx
- lock cmpxchgl %ecx,mp_lock
-3:
- subl %eax,%eax
- ret
-
- /*
- * rel_mplock() releases a previously obtained MP lock.
- *
- * In order to release the MP lock we pre-dispose TD_MPCOUNT for
- * the release and basically repeat the release portion of try_mplock
- * above.
- */
-NON_GPROF_ENTRY(rel_mplock)
- movl PCPU(curthread),%edx
- movl TD_MPCOUNT(%edx),%eax
-#ifdef INVARIANTS
- cmpl $0,%eax
- je badmp_rel
-#endif
- subl $1,%eax
- movl %eax,TD_MPCOUNT(%edx)
- cmpl $0,%eax
- jne 3f
- movl PCPU(cpuid),%eax
- movl $-1,%ecx
- lock cmpxchgl %ecx,mp_lock
-3:
- ret
-
-#ifdef INVARIANTS
-
-badmp_get:
- pushl $bmpsw1
- call panic
-badmp_get2:
- pushl $bmpsw1a
- call panic
-badmp_rel:
- pushl $bmpsw2
- call panic
-
- .data
-
-bmpsw1:
- .asciz "try/get_mplock(): already have lock! %d %p"
-
-bmpsw1a:
- .asciz "try/get_mplock(): failed on count or switch %d %p"
-
-bmpsw2:
- .asciz "rel_mplock(): mpcount already 0 @ %p %p %p %p %p %p %p %p!"
-
-#endif
-
+++ /dev/null
-/*
- * $DragonFly: src/lib/libcaps/i386/sendsys.h,v 1.1 2003/12/04 22:06:22 dillon Exp $
- */
-#ifndef _SENDSYS_H_
-#define _SENDSYS_H_
-
-static __inline
-int
-sendsys(struct lwkt_port *port, void *msg, int msgsize)
-{
- int error;
- __asm __volatile("int $0x81" : "=a"(error), "=c"(msg), "=d"(msgsize) : "0"(port), "1"(msg), "2"(msgsize) : "memory");
- return(error);
-}
-
-#endif /* _SENDSYS_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/lib/libcaps/i386/td_switch.c,v 1.2 2004/07/29 08:55:02 dillon Exp $
- */
-#include <sys/cdefs.h> /* for __dead2 needed by thread.h */
-#include "libcaps/thread.h"
-#include <sys/thread.h>
-#include "libcaps/globaldata.h" /* for curthread */
-
-void cpu_lwkt_switch(struct thread *);
-void cpu_kthread_start(struct thread *);
-void cpu_exit_switch(struct thread *);
-
-void
-cpu_init_thread(struct thread *td)
-{
- td->td_sp = td->td_kstack + td->td_kstack_size - sizeof(void *);
- td->td_switch = cpu_lwkt_switch;
-}
-
-void
-cpu_set_thread_handler(thread_t td, void (*rfunc)(void), void (*func)(void *), void *arg)
-{
- td->td_sp -= sizeof(void *);
- *(void **)td->td_sp = arg; /* argument to function */
- td->td_sp -= sizeof(void *);
- *(void **)td->td_sp = rfunc; /* exit function on return */
- td->td_sp -= sizeof(void *);
- *(void **)td->td_sp = func; /* started by cpu_kthread_start */
- td->td_sp -= sizeof(void *);
- *(void **)td->td_sp = cpu_kthread_start; /* bootstrap */
- td->td_switch = cpu_lwkt_switch;
-}
-
-void
-cpu_thread_exit(void)
-{
- curthread->td_switch = cpu_exit_switch;
- lwkt_switch();
- panic("cpu_exit");
-}
+++ /dev/null
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- * LWKT threads Copyright (c) 2003 Matthew Dillon
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/i386/i386/swtch.s,v 1.89.2.10 2003/01/23 03:36:24 ps Exp $
- * $DragonFly: src/lib/libcaps/i386/td_switch_asm.S,v 1.2 2003/12/07 04:21:54 dillon Exp $
- */
-
-#include "asmacros.h"
-#include "asdefs.h"
-
- .text
-
-/*
- * cpu_exit_switch()
- *
- * The switch function is changed to this when a thread is going away
- * for good. We have to ensure that the MMU state is not cached, and
- * we don't bother saving the existing thread state before switching.
- *
- * At this point we are in a critical section and this cpu owns the
- * thread's token, which serves as an interlock until the switchout is
- * complete.
- */
-NON_GPROF_ENTRY(cpu_exit_switch)
- /*
- * Get us out of the vmspace
- */
- movl PCPU(curthread),%ebx
- /*
- * Switch to the next thread. RET into the restore function, which
- * expects the new thread in EAX and the old in EBX.
- *
- * There is a one-instruction window where curthread is the new
- * thread but %esp still points to the old thread's stack, but
- * we are protected by a critical section so it is ok.
- */
- movl 4(%esp),%eax
- movl %eax,PCPU(curthread)
- movl TD_SP(%eax),%esp
- ret
-
-/*
- * cpu_kthread_start() (current thread is %eax on entry) (one-time execution)
- *
- * Run only on first function
- */
-NON_GPROF_ENTRY(cpu_kthread_start)
- andl $~TDF_RUNNING,TD_FLAGS(%ebx)
- orl $TDF_RUNNING,TD_FLAGS(%eax)
- subl $TDPRI_CRIT,TD_PRI(%eax)
- /* call splz here? */
- movl $0,%eax
- movl %eax,%ebx
- movl %eax,%ecx
- movl %eax,%edx
- movl %eax,%esi
- movl %eax,%edi
- movl %eax,%ebp
- ret
-
-/*
- * cpu_rfork_start(). The current thread is the idlethread. We restore the
- * idle thread which generally causes us to jump to cpu_kthraed_start.
- */
-NON_GPROF_ENTRY(cpu_rfork_start)
- movl PCPU(curthread),%eax
- movl %eax,%ebx
- movl TD_SP(%eax),%esp
- ret
-
-/*
- * cpu_lwkt_switch()
- *
- * Standard LWKT switching function. Only non-scratch registers are
- * saved and we don't bother with the MMU state or anything else.
- *
- * This function is always called while in a critical section.
- *
- * There is a one-instruction window where curthread is the new
- * thread but %esp still points to the old thread's stack, but
- * we are protected by a critical section so it is ok.
- *
- * YYY BGL, SPL
- */
-NON_GPROF_ENTRY(cpu_lwkt_switch)
- movl 4(%esp),%eax
- pushl %ebp
- pushl %ebx
- pushl %esi
- pushl %edi
- pushfl
- movl PCPU(curthread),%ebx
- pushl $cpu_lwkt_restore
- movl %esp,TD_SP(%ebx)
- movl %eax,PCPU(curthread)
- movl TD_SP(%eax),%esp
-
- /*
- * eax contains new thread, ebx contains old thread.
- */
- ret
-
-/*
- * cpu_lwkt_restore() (current thread in %eax on entry)
- * (old thread %ebx on entry)
- *
- * Standard LWKT restore function. This function is always called
- * while in a critical section.
- *
- * Warning: due to preemption the restore function can be used to
- * 'return' to the original thread. Interrupt disablement must be
- * protected through the switch so we cannot run splz here.
- *
- * YYY we theoretically do not need to load IdlePTD into cr3, but if
- * so we need a way to detect when the PTD we are using is being
- * deleted due to a process exiting.
- */
-NON_GPROF_ENTRY(cpu_lwkt_restore)
- andl $~TDF_RUNNING,TD_FLAGS(%ebx)
- orl $TDF_RUNNING,TD_FLAGS(%eax)
- popfl
- popl %edi
- popl %esi
- popl %ebx
- popl %ebp
- ret
-
-/*
- * cpu_user_switch()
- *
- * Standard USER switching function. FP and non-scratch registers
- * are saved.
- *
- * This function is always called while in a critical section.
- *
- * There is a one-instruction window where curthread is the new
- * thread but %esp still points to the old thread's stack, but
- * we are protected by a critical section so it is ok.
- *
- * YYY BGL, SPL
- */
-NON_GPROF_ENTRY(cpu_user_switch)
- movl 4(%esp),%eax
- pushl %ebp
- pushl %ebx
- pushl %esi
- pushl %edi
- pushfl
- subl $108,%esp
- fnsave 0(%esp)
- movl PCPU(curthread),%ebx
- pushl $cpu_user_restore
- movl %esp,TD_SP(%ebx)
- movl %eax,PCPU(curthread)
- movl TD_SP(%eax),%esp
-
- /*
- * eax contains new thread, ebx contains old thread.
- */
- ret
-
-/*
- * cpu_user_restore() (current thread in %eax on entry)
- *
- * Standard LWKT restore function. This function is always called
- * while in a critical section.
- *
- * Warning: due to preemption the restore function can be used to
- * 'return' to the original thread. Interrupt disablement must be
- * protected through the switch so we cannot run splz here.
- *
- * YYY we theoretically do not need to load IdlePTD into cr3, but if
- * so we need a way to detect when the PTD we are using is being
- * deleted due to a process exiting.
- */
-NON_GPROF_ENTRY(cpu_user_restore)
- andl $~TDF_RUNNING,TD_FLAGS(%ebx)
- orl $TDF_RUNNING,TD_FLAGS(%eax)
- frstor 0(%esp)
- addl $108,%esp
- popfl
- popl %edi
- popl %esi
- popl %ebx
- popl %ebp
- ret
-
- .end
+++ /dev/null
- /*
- * $DragonFly: src/lib/libcaps/i386/upcall.S,v 1.2 2003/12/07 04:21:54 dillon Exp $
- */
-
-#include "asmacros.h"
-#include "asdefs.h"
-
- .text
- .globl upc_callused_wrapper
-
- /*
- * On entry: %eax contains function
- * %ecx contains data
- * Stack: [eax,ecx,eflags,oldip]
- */
-NON_GPROF_ENTRY(upc_callused_wrapper)
- pushl %edx /* save %edx (upcall pointer) */
- pushl %ecx /* func(data) */
- call *%eax
- addl $4,%esp
- popl %edx /* upcall pointer */
- movl UPC_UTHREAD(%edx),%eax
- incl UPC_PENDING(%edx) /* set pending bit (prevents upcalls) */
- subl $TDPRI_CRIT,TD_PRI(%eax) /* cleanup critical section count */
- pushl %esp /* sp pointing to os supplied frame */
- pushl $-1 /* upcid */
- pushl $2 /* FETCH next */
- call upc_control
- popl %eax
- popl %ecx
- popl %edx
- popfl
- ret
-
+++ /dev/null
-/*
- * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/lib/libcaps/init.c,v 1.2 2003/12/07 04:21:52 dillon Exp $
- */
-
-#include "defs.h"
-
-struct thread main_td;
-
-static void uthread_exit(void);
-
-void
-uthread_init(void)
-{
- slab_init();
- globaldata_init(&main_td);
- sysport_init();
- crit_exit();
- get_mplock();
- atexit(uthread_exit);
-}
-
-void
-uthread_exit(void)
-{
- int i;
-
- for (i = 0; i < ncpus; ++i) {
- globaldata_t gd = globaldata_find(i);
- if (gd != mycpu && gd->gd_pid)
- kill(gd->gd_pid, 9);
- }
-}
-
+++ /dev/null
-/*
- * SLABALLOC.C - Userland SLAB memory allocator
- *
- * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/lib/libcaps/slaballoc.c,v 1.4 2004/07/04 22:44:26 eirikn Exp $
- *
- * This module implements a thread-safe slab allocator for userland.
- *
- * A slab allocator reserves a ZONE for each chunk size, then lays the
- * chunks out in an array within the zone. Allocation and deallocation
- * is nearly instantanious, and fragmentation/overhead losses are limited
- * to a fixed worst-case amount.
- *
- * The downside of this slab implementation is in the chunk size
- * multiplied by the number of zones. ~80 zones * 128K = 10MB of VM per cpu.
- * To mitigate this we attempt to select a reasonable zone size based on
- * available system memory. e.g. 32K instead of 128K. Also since the
- * slab allocator is operating out of virtual memory in userland the actual
- * physical memory use is not as bad as it might otherwise be.
- *
- * The upside is that overhead is bounded... waste goes down as use goes up.
- *
- * Slab management is done on a per-cpu basis and no locking or mutexes
- * are required, only a critical section. When one cpu frees memory
- * belonging to another cpu's slab manager an asynchronous IPI message
- * will be queued to execute the operation. In addition, both the
- * high level slab allocator and the low level zone allocator optimize
- * M_ZERO requests, and the slab allocator does not have to pre initialize
- * the linked list of chunks.
- *
- * XXX Balancing is needed between cpus. Balance will be handled through
- * asynchronous IPIs primarily by reassigning the z_Cpu ownership of chunks.
- *
- * Alloc Size Chunking Number of zones
- * 0-127 8 16
- * 128-255 16 8
- * 256-511 32 8
- * 512-1023 64 8
- * 1024-2047 128 8
- * 2048-4095 256 8
- * 4096-8191 512 8
- * 8192-16383 1024 8
- * 16384-32767 2048 8
- * (if PAGE_SIZE is 4K the maximum zone allocation is 16383)
- *
- * Allocations >= ZoneLimit go directly to kmem.
- *
- * API REQUIREMENTS AND SIDE EFFECTS
- *
- * To operate as a drop-in replacement to the FreeBSD-4.x malloc() we
- * have remained compatible with the following API requirements:
- *
- * + small power-of-2 sized allocations are power-of-2 aligned (kern_tty)
- * + all power-of-2 sized allocations are power-of-2 aligned (twe)
- * + malloc(0) is allowed and returns non-NULL (ahc driver)
- * + ability to allocate arbitrarily large chunks of memory
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/stdint.h>
-#include <sys/malloc.h>
-#include "thread.h"
-#include <sys/thread.h>
-#include <sys/msgport.h>
-#include <sys/errno.h>
-#include "globaldata.h"
-#include <sys/sysctl.h>
-#include <machine/cpufunc.h>
-#include <sys/thread2.h>
-#include <sys/msgport2.h>
-
-#define arysize(ary) (sizeof(ary)/sizeof((ary)[0]))
-#define slab_min(a,b) (((a)<(b)) ? (a) : (b))
-
-/*
- * Fixed globals (not per-cpu)
- */
-static int ZoneSize;
-static int ZoneLimit;
-static int ZonePageCount;
-static int ZonePageLimit;
-static int ZoneMask;
-static struct malloc_type *kmemstatistics;
-static int32_t weirdary[16];
-
-/*
- * Misc constants. Note that allocations that are exact multiples of
- * PAGE_SIZE, or exceed the zone limit, fall through to the kmem module.
- * IN_SAME_PAGE_MASK is used to sanity-check the per-page free lists.
- */
-#define MIN_CHUNK_SIZE 8 /* in bytes */
-#define MIN_CHUNK_MASK (MIN_CHUNK_SIZE - 1)
-#define ZONE_RELS_THRESH 2 /* threshold number of zones */
-#define IN_SAME_PAGE_MASK (~(intptr_t)PAGE_MASK | MIN_CHUNK_MASK)
-
-#define SLOVERSZ_HSIZE 8192
-#define SLOVERSZ_HMASK (SLOVERSZ_HSIZE - 1)
-
-#define SLOVERSZ_HASH(ptr) ((((uintptr_t)ptr >> PAGE_SHIFT) ^ \
- ((uintptr_t)ptr >> (PAGE_SHIFT * 2))) & \
- SLOVERSZ_HMASK)
-
-SLOversized *SLOvHash[SLOVERSZ_HSIZE];
-
-/*
- * The WEIRD_ADDR is used as known text to copy into free objects to
- * try to create deterministic failure cases if the data is accessed after
- * free.
- */
-#define WEIRD_ADDR 0xdeadc0de
-#define MAX_COPY sizeof(weirdary)
-#define ZERO_LENGTH_PTR ((void *)-8)
-
-/*
- * Misc global malloc buckets
- */
-MALLOC_DEFINE(M_OVERSIZED, "overszinfo", "Oversized Info Blocks");
-
-static __inline
-SLOversized **
-get_oversized(void *ptr)
-{
- SLOversized **slovpp;
- SLOversized *slov;
-
- for (slovpp = &SLOvHash[SLOVERSZ_HASH(ptr)];
- (slov = *slovpp) != NULL;
- slovpp = &slov->ov_Next
- ) {
- if (slov->ov_Ptr == ptr)
- return(slovpp);
- }
- return(NULL);
-}
-
-/*
- * Initialize the slab memory allocator. We have to choose a zone size based
- * on available physical memory. We choose a zone side which is approximately
- * 1/1024th of our memory, so if we have 128MB of ram we have a zone size of
- * 128K. The zone size is limited to the bounds set in slaballoc.h
- * (typically 32K min, 128K max).
- */
-void
-slab_init(void)
-{
- int i;
- int error;
- int pagecnt;
- int pagecnt_size = sizeof(pagecnt);
-
- error = sysctlbyname("vm.stats.vm.v_page_count",
- &pagecnt, &pagecnt_size, NULL, 0);
- if (error == 0) {
- vm_poff_t limsize;
- int usesize;
-
- limsize = pagecnt * (vm_poff_t)PAGE_SIZE;
- usesize = (int)(limsize / 1024); /* convert to KB */
-
- ZoneSize = ZALLOC_MIN_ZONE_SIZE;
- while (ZoneSize < ZALLOC_MAX_ZONE_SIZE && (ZoneSize << 1) < usesize)
- ZoneSize <<= 1;
- } else {
- ZoneSize = ZALLOC_MIN_ZONE_SIZE;
- }
- ZoneLimit = ZoneSize / 4;
- if (ZoneLimit > ZALLOC_ZONE_LIMIT)
- ZoneLimit = ZALLOC_ZONE_LIMIT;
- ZoneMask = ZoneSize - 1;
- ZonePageLimit = PAGE_SIZE * 4;
- ZonePageCount = ZoneSize / PAGE_SIZE;
-
- for (i = 0; i < arysize(weirdary); ++i)
- weirdary[i] = WEIRD_ADDR;
- slab_malloc_init(M_OVERSIZED);
-}
-
-/*
- * Initialize a malloc type tracking structure.
- */
-void
-slab_malloc_init(void *data)
-{
- struct malloc_type *type = data;
- vm_poff_t limsize;
-
- /*
- * Skip if already initialized
- */
- if (type->ks_limit != 0)
- return;
-
- type->ks_magic = M_MAGIC;
- limsize = (vm_poff_t)-1; /* unlimited */
- type->ks_limit = limsize / 10;
- type->ks_next = kmemstatistics;
- kmemstatistics = type;
-}
-
-void
-slab_malloc_uninit(void *data)
-{
- struct malloc_type *type = data;
- struct malloc_type *t;
-#ifdef INVARIANTS
- int i;
- long ttl;
-#endif
-
- if (type->ks_magic != M_MAGIC)
- panic("malloc type lacks magic");
-
- if (type->ks_limit == 0)
- panic("malloc_uninit on uninitialized type");
-
-#ifdef INVARIANTS
- /*
- * memuse is only correct in aggregation. Due to memory being allocated
- * on one cpu and freed on another individual array entries may be
- * negative or positive (canceling each other out).
- */
- for (i = ttl = 0; i < ncpus; ++i)
- ttl += type->ks_memuse[i];
- if (ttl) {
- printf("malloc_uninit: %ld bytes of '%s' still allocated on cpu %d\n",
- ttl, type->ks_shortdesc, i);
- }
-#endif
- if (type == kmemstatistics) {
- kmemstatistics = type->ks_next;
- } else {
- for (t = kmemstatistics; t->ks_next != NULL; t = t->ks_next) {
- if (t->ks_next == type) {
- t->ks_next = type->ks_next;
- break;
- }
- }
- }
- type->ks_next = NULL;
- type->ks_limit = 0;
-}
-
-/*
- * Calculate the zone index for the allocation request size and set the
- * allocation request size to that particular zone's chunk size.
- */
-static __inline int
-zoneindex(unsigned long *bytes)
-{
- unsigned int n = (unsigned int)*bytes; /* unsigned for shift opt */
- if (n < 128) {
- *bytes = n = (n + 7) & ~7;
- return(n / 8 - 1); /* 8 byte chunks, 16 zones */
- }
- if (n < 256) {
- *bytes = n = (n + 15) & ~15;
- return(n / 16 + 7);
- }
- if (n < 8192) {
- if (n < 512) {
- *bytes = n = (n + 31) & ~31;
- return(n / 32 + 15);
- }
- if (n < 1024) {
- *bytes = n = (n + 63) & ~63;
- return(n / 64 + 23);
- }
- if (n < 2048) {
- *bytes = n = (n + 127) & ~127;
- return(n / 128 + 31);
- }
- if (n < 4096) {
- *bytes = n = (n + 255) & ~255;
- return(n / 256 + 39);
- }
- *bytes = n = (n + 511) & ~511;
- return(n / 512 + 47);
- }
-#if ZALLOC_ZONE_LIMIT > 8192
- if (n < 16384) {
- *bytes = n = (n + 1023) & ~1023;
- return(n / 1024 + 55);
- }
-#endif
-#if ZALLOC_ZONE_LIMIT > 16384
- if (n < 32768) {
- *bytes = n = (n + 2047) & ~2047;
- return(n / 2048 + 63);
- }
-#endif
- panic("Unexpected byte count %d", n);
- return(0);
-}
-
-/*
- * slab_malloc()
- *
- * Allocate memory via the slab allocator. If the request is too large,
- * or if it page-aligned beyond a certain size, we fall back to the
- * KMEM subsystem. A SLAB tracking descriptor must be specified, use
- * &SlabMisc if you don't care.
- *
- * M_NOWAIT - return NULL instead of blocking.
- * M_ZERO - zero the returned memory.
- */
-void *
-slab_malloc(unsigned long size, struct malloc_type *type, int flags)
-{
- SLZone *z;
- SLChunk *chunk;
- SLGlobalData *slgd;
- struct globaldata *gd;
- int zi;
-
- gd = mycpu;
- slgd = &gd->gd_slab;
-
- /*
- * XXX silly to have this in the critical path.
- */
- if (type->ks_limit == 0) {
- crit_enter();
- if (type->ks_limit == 0)
- slab_malloc_init(type);
- crit_exit();
- }
- ++type->ks_calls;
-
- /*
- * Handle the case where the limit is reached. Panic if can't return
- * NULL. XXX the original malloc code looped, but this tended to
- * simply deadlock the computer.
- */
- while (type->ks_loosememuse >= type->ks_limit) {
- int i;
- long ttl;
-
- for (i = ttl = 0; i < ncpus; ++i)
- ttl += type->ks_memuse[i];
- type->ks_loosememuse = ttl;
- if (ttl >= type->ks_limit) {
- if (flags & (M_NOWAIT|M_NULLOK))
- return(NULL);
- panic("%s: malloc limit exceeded", type->ks_shortdesc);
- }
- }
-
- /*
- * Handle the degenerate size == 0 case. Yes, this does happen.
- * Return a special pointer. This is to maintain compatibility with
- * the original malloc implementation. Certain devices, such as the
- * adaptec driver, not only allocate 0 bytes, they check for NULL and
- * also realloc() later on. Joy.
- */
- if (size == 0)
- return(ZERO_LENGTH_PTR);
-
- /*
- * Handle hysteresis from prior frees here in malloc(). We cannot
- * safely manipulate the kernel_map in free() due to free() possibly
- * being called via an IPI message or from sensitive interrupt code.
- */
- while (slgd->NFreeZones > ZONE_RELS_THRESH && (flags & M_NOWAIT) == 0) {
- crit_enter();
- if (slgd->NFreeZones > ZONE_RELS_THRESH) { /* crit sect race */
- z = slgd->FreeZones;
- slgd->FreeZones = z->z_Next;
- --slgd->NFreeZones;
- munmap(z, ZoneSize);
- }
- crit_exit();
- }
- /*
- * XXX handle oversized frees that were queued from free().
- */
- while (slgd->FreeOvZones && (flags & M_NOWAIT) == 0) {
- crit_enter();
- if ((z = slgd->FreeOvZones) != NULL) {
- KKASSERT(z->z_Magic == ZALLOC_OVSZ_MAGIC);
- slgd->FreeOvZones = z->z_Next;
- munmap(z, z->z_ChunkSize);
- }
- crit_exit();
- }
-
- /*
- * Handle large allocations directly. There should not be very many of
- * these so performance is not a big issue.
- *
- * Guarentee page alignment for allocations in multiples of PAGE_SIZE
- */
- if (size >= ZoneLimit || (size & PAGE_MASK) == 0) {
- SLOversized **slovpp;
- SLOversized *slov;
-
- slov = slab_malloc(sizeof(SLOversized), M_OVERSIZED, M_ZERO);
- if (slov == NULL)
- return(NULL);
-
- size = round_page(size);
- chunk = mmap(NULL, size, PROT_READ|PROT_WRITE,
- MAP_ANON|MAP_PRIVATE, -1, 0);
- if (chunk == MAP_FAILED) {
- slab_free(slov, M_OVERSIZED);
- return(NULL);
- }
- flags &= ~M_ZERO; /* result already zero'd if M_ZERO was set */
- flags |= M_PASSIVE_ZERO;
-
- slov->ov_Ptr = chunk;
- slov->ov_Bytes = size;
- slovpp = &SLOvHash[SLOVERSZ_HASH(chunk)];
- slov->ov_Next = *slovpp;
- *slovpp = slov;
- crit_enter();
- goto done;
- }
-
- /*
- * Attempt to allocate out of an existing zone. First try the free list,
- * then allocate out of unallocated space. If we find a good zone move
- * it to the head of the list so later allocations find it quickly
- * (we might have thousands of zones in the list).
- *
- * Note: zoneindex() will panic of size is too large.
- */
- zi = zoneindex(&size);
- KKASSERT(zi < NZONES);
- crit_enter();
- if ((z = slgd->ZoneAry[zi]) != NULL) {
- KKASSERT(z->z_NFree > 0);
-
- /*
- * Remove us from the ZoneAry[] when we become empty
- */
- if (--z->z_NFree == 0) {
- slgd->ZoneAry[zi] = z->z_Next;
- z->z_Next = NULL;
- }
-
- /*
- * Locate a chunk in a free page. This attempts to localize
- * reallocations into earlier pages without us having to sort
- * the chunk list. A chunk may still overlap a page boundary.
- */
- while (z->z_FirstFreePg < ZonePageCount) {
- if ((chunk = z->z_PageAry[z->z_FirstFreePg]) != NULL) {
-#ifdef DIAGNOSTIC
- /*
- * Diagnostic: c_Next is not total garbage.
- */
- KKASSERT(chunk->c_Next == NULL ||
- ((intptr_t)chunk->c_Next & IN_SAME_PAGE_MASK) ==
- ((intptr_t)chunk & IN_SAME_PAGE_MASK));
-#endif
-#ifdef INVARIANTS
- if ((uintptr_t)chunk < VM_MIN_KERNEL_ADDRESS)
- panic("chunk %p FFPG %d/%d", chunk, z->z_FirstFreePg, ZonePageCount);
- if (chunk->c_Next && (uintptr_t)chunk->c_Next < VM_MIN_KERNEL_ADDRESS)
- panic("chunkNEXT %p %p FFPG %d/%d", chunk, chunk->c_Next, z->z_FirstFreePg, ZonePageCount);
-#endif
- z->z_PageAry[z->z_FirstFreePg] = chunk->c_Next;
- goto done;
- }
- ++z->z_FirstFreePg;
- }
-
- /*
- * No chunks are available but NFree said we had some memory, so
- * it must be available in the never-before-used-memory area
- * governed by UIndex. The consequences are very serious if our zone
- * got corrupted so we use an explicit panic rather then a KASSERT.
- */
- if (z->z_UIndex + 1 != z->z_NMax)
- z->z_UIndex = z->z_UIndex + 1;
- else
- z->z_UIndex = 0;
- if (z->z_UIndex == z->z_UEndIndex)
- panic("slaballoc: corrupted zone");
- chunk = (SLChunk *)(z->z_BasePtr + z->z_UIndex * size);
- if ((z->z_Flags & SLZF_UNOTZEROD) == 0) {
- flags &= ~M_ZERO;
- flags |= M_PASSIVE_ZERO;
- }
- goto done;
- }
-
- /*
- * If all zones are exhausted we need to allocate a new zone for this
- * index. Use M_ZERO to take advantage of pre-zerod pages. Also see
- * UAlloc use above in regards to M_ZERO. Note that when we are reusing
- * a zone from the FreeZones list UAlloc'd data will not be zero'd, and
- * we do not pre-zero it because we do not want to mess up the L1 cache.
- *
- * At least one subsystem, the tty code (see CROUND) expects power-of-2
- * allocations to be power-of-2 aligned. We maintain compatibility by
- * adjusting the base offset below.
- */
- {
- int off;
-
- if ((z = slgd->FreeZones) != NULL) {
- slgd->FreeZones = z->z_Next;
- --slgd->NFreeZones;
- bzero(z, sizeof(SLZone));
- z->z_Flags |= SLZF_UNOTZEROD;
- } else {
- z = mmap(NULL, ZoneSize, PROT_READ|PROT_WRITE,
- MAP_ANON|MAP_PRIVATE, -1, 0);
- if (z == MAP_FAILED)
- goto fail;
- }
-
- /*
- * Guarentee power-of-2 alignment for power-of-2-sized chunks.
- * Otherwise just 8-byte align the data.
- */
- if ((size | (size - 1)) + 1 == (size << 1))
- off = (sizeof(SLZone) + size - 1) & ~(size - 1);
- else
- off = (sizeof(SLZone) + MIN_CHUNK_MASK) & ~MIN_CHUNK_MASK;
- z->z_Magic = ZALLOC_SLAB_MAGIC;
- z->z_ZoneIndex = zi;
- z->z_NMax = (ZoneSize - off) / size;
- z->z_NFree = z->z_NMax - 1;
- z->z_BasePtr = (char *)z + off;
- z->z_UIndex = z->z_UEndIndex = slgd->JunkIndex % z->z_NMax;
- z->z_ChunkSize = size;
- z->z_FirstFreePg = ZonePageCount;
- z->z_Cpu = gd->gd_cpuid;
- z->z_CpuGd = gd;
- chunk = (SLChunk *)(z->z_BasePtr + z->z_UIndex * size);
- z->z_Next = slgd->ZoneAry[zi];
- slgd->ZoneAry[zi] = z;
- if ((z->z_Flags & SLZF_UNOTZEROD) == 0) {
- flags &= ~M_ZERO; /* already zero'd */
- flags |= M_PASSIVE_ZERO;
- }
-
- /*
- * Slide the base index for initial allocations out of the next
- * zone we create so we do not over-weight the lower part of the
- * cpu memory caches.
- */
- slgd->JunkIndex = (slgd->JunkIndex + ZALLOC_SLAB_SLIDE)
- & (ZALLOC_MAX_ZONE_SIZE - 1);
- }
-done:
- ++type->ks_inuse[gd->gd_cpuid];
- type->ks_memuse[gd->gd_cpuid] += size;
- type->ks_loosememuse += size;
- crit_exit();
- if (flags & M_ZERO)
- bzero(chunk, size);
-#ifdef INVARIANTS
- else if ((flags & (M_ZERO|M_PASSIVE_ZERO)) == 0)
- chunk->c_Next = (void *)-1; /* avoid accidental double-free check */
-#endif
- return(chunk);
-fail:
- crit_exit();
- return(NULL);
-}
-
-void *
-slab_realloc(void *ptr, unsigned long size, struct malloc_type *type, int flags)
-{
- SLZone *z;
- SLOversized **slovpp;
- SLOversized *slov;
- void *nptr;
- unsigned long osize;
-
- if (ptr == NULL || ptr == ZERO_LENGTH_PTR)
- return(slab_malloc(size, type, flags));
- if (size == 0) {
- slab_free(ptr, type);
- return(NULL);
- }
-
- /*
- * Handle oversized allocations.
- */
- if ((slovpp = get_oversized(ptr)) != NULL) {
- slov = *slovpp;
- osize = slov->ov_Bytes;
- if (osize == round_page(size))
- return(ptr);
- if ((nptr = slab_malloc(size, type, flags)) == NULL)
- return(NULL);
- bcopy(ptr, nptr, slab_min(size, osize));
- slab_free(ptr, type);
- return(nptr);
- }
-
- /*
- * Get the original allocation's zone. If the new request winds up
- * using the same chunk size we do not have to do anything.
- */
- z = (SLZone *)((uintptr_t)ptr & ~(uintptr_t)ZoneMask);
- KKASSERT(z->z_Magic == ZALLOC_SLAB_MAGIC);
-
- zoneindex(&size);
- if (z->z_ChunkSize == size)
- return(ptr);
-
- /*
- * Allocate memory for the new request size. Note that zoneindex has
- * already adjusted the request size to the appropriate chunk size, which
- * should optimize our bcopy(). Then copy and return the new pointer.
- */
- if ((nptr = slab_malloc(size, type, flags)) == NULL)
- return(NULL);
- bcopy(ptr, nptr, slab_min(size, z->z_ChunkSize));
- slab_free(ptr, type);
- return(nptr);
-}
-
-#ifdef SMP
-/*
- * slab_free() (SLAB ALLOCATOR)
- *
- * Free the specified chunk of memory.
- */
-static
-void
-slab_free_remote(void *ptr)
-{
- slab_free(ptr, *(struct malloc_type **)ptr);
-}
-
-#endif
-
-void
-slab_free(void *ptr, struct malloc_type *type)
-{
- SLZone *z;
- SLOversized **slovpp;
- SLOversized *slov;
- SLChunk *chunk;
- SLGlobalData *slgd;
- struct globaldata *gd;
- int pgno;
-
- gd = mycpu;
- slgd = &gd->gd_slab;
-
- /*
- * Handle special 0-byte allocations
- */
- if (ptr == ZERO_LENGTH_PTR)
- return;
-
- /*
- * Handle oversized allocations. XXX we really should require that a
- * size be passed to slab_free() instead of this nonsense.
- *
- * This code is never called via an ipi.
- */
- if ((slovpp = get_oversized(ptr)) != NULL) {
- slov = *slovpp;
- *slovpp = slov->ov_Next;
-
-#ifdef INVARIANTS
- KKASSERT(sizeof(weirdary) <= slov->ov_Bytes);
- bcopy(weirdary, ptr, sizeof(weirdary));
-#endif
- /*
- * note: we always adjust our cpu's slot, not the originating
- * cpu (kup->ku_cpuid). The statistics are in aggregate.
- *
- * note: XXX we have still inherited the interrupts-can't-block
- * assumption. An interrupt thread does not bump
- * gd_intr_nesting_level so check TDF_INTTHREAD. This is
- * primarily until we can fix softupdate's assumptions about
- * slab_free().
- */
- crit_enter();
- --type->ks_inuse[gd->gd_cpuid];
- type->ks_memuse[gd->gd_cpuid] -= slov->ov_Bytes;
- if (mycpu->gd_intr_nesting_level || (gd->gd_curthread->td_flags & TDF_INTTHREAD)) {
- z = (SLZone *)ptr;
- z->z_Magic = ZALLOC_OVSZ_MAGIC;
- z->z_Next = slgd->FreeOvZones;
- z->z_ChunkSize = slov->ov_Bytes;
- slgd->FreeOvZones = z;
- crit_exit();
- } else {
- crit_exit();
- munmap(ptr, slov->ov_Bytes);
- }
- slab_free(slov, M_OVERSIZED);
- return;
- }
-
- /*
- * Zone case. Figure out the zone based on the fact that it is
- * ZoneSize aligned.
- */
- z = (SLZone *)((uintptr_t)ptr & ~(uintptr_t)ZoneMask);
- KKASSERT(z->z_Magic == ZALLOC_SLAB_MAGIC);
-
- /*
- * If we do not own the zone then forward the request to the
- * cpu that does. The freeing code does not need the byte count
- * unless DIAGNOSTIC is set.
- */
- if (z->z_CpuGd != gd) {
- *(struct malloc_type **)ptr = type;
-#ifdef SMP
- lwkt_send_ipiq(z->z_CpuGd, slab_free_remote, ptr);
-#else
- panic("Corrupt SLZone");
-#endif
- return;
- }
-
- if (type->ks_magic != M_MAGIC)
- panic("slab_free: malloc type lacks magic");
-
- crit_enter();
- pgno = ((char *)ptr - (char *)z) >> PAGE_SHIFT;
- chunk = ptr;
-
-#ifdef INVARIANTS
- /*
- * Attempt to detect a double-free. To reduce overhead we only check
- * if there appears to be link pointer at the base of the data.
- */
- if (((intptr_t)chunk->c_Next - (intptr_t)z) >> PAGE_SHIFT == pgno) {
- SLChunk *scan;
- for (scan = z->z_PageAry[pgno]; scan; scan = scan->c_Next) {
- if (scan == chunk)
- panic("Double free at %p", chunk);
- }
- }
-#endif
-
- /*
- * Put weird data into the memory to detect modifications after freeing,
- * illegal pointer use after freeing (we should fault on the odd address),
- * and so forth. XXX needs more work, see the old malloc code.
- */
-#ifdef INVARIANTS
- if (z->z_ChunkSize < sizeof(weirdary))
- bcopy(weirdary, chunk, z->z_ChunkSize);
- else
- bcopy(weirdary, chunk, sizeof(weirdary));
-#endif
-
- /*
- * Add this free non-zero'd chunk to a linked list for reuse, adjust
- * z_FirstFreePg.
- */
-#ifdef INVARIANTS
- if ((uintptr_t)chunk < VM_MIN_KERNEL_ADDRESS)
- panic("BADFREE %p\n", chunk);
-#endif
- chunk->c_Next = z->z_PageAry[pgno];
- z->z_PageAry[pgno] = chunk;
-#ifdef INVARIANTS
- if (chunk->c_Next && (uintptr_t)chunk->c_Next < VM_MIN_KERNEL_ADDRESS)
- panic("BADFREE2");
-#endif
- if (z->z_FirstFreePg > pgno)
- z->z_FirstFreePg = pgno;
-
- /*
- * Bump the number of free chunks. If it becomes non-zero the zone
- * must be added back onto the appropriate list.
- */
- if (z->z_NFree++ == 0) {
- z->z_Next = slgd->ZoneAry[z->z_ZoneIndex];
- slgd->ZoneAry[z->z_ZoneIndex] = z;
- }
-
- --type->ks_inuse[z->z_Cpu];
- type->ks_memuse[z->z_Cpu] -= z->z_ChunkSize;
-
- /*
- * If the zone becomes totally free, and there are other zones we
- * can allocate from, move this zone to the FreeZones list. Since
- * this code can be called from an IPI callback, do *NOT* try to mess
- * with kernel_map here. Hysteresis will be performed at malloc() time.
- */
- if (z->z_NFree == z->z_NMax &&
- (z->z_Next || slgd->ZoneAry[z->z_ZoneIndex] != z)
- ) {
- SLZone **pz;
-
- for (pz = &slgd->ZoneAry[z->z_ZoneIndex]; z != *pz; pz = &(*pz)->z_Next)
- ;
- *pz = z->z_Next;
- z->z_Magic = -1;
- z->z_Next = slgd->FreeZones;
- slgd->FreeZones = z;
- ++slgd->NFreeZones;
- }
- crit_exit();
-}
-
+++ /dev/null
-/*
- * SLABALLOC.H - Userland SLAB memory allocator
- *
- * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/lib/libcaps/slaballoc.h,v 1.3 2004/03/06 19:48:22 dillon Exp $
- */
-
-#ifndef _LIBCAPS_SLABALLOC_H_
-#define _LIBCAPS_SLABALLOC_H_
-
-#ifndef _SYS_STDINT_H_
-#include <sys/stdint.h>
-#endif
-#ifndef _SYS_MALLOC_H_
-#include <sys/malloc.h>
-#endif
-
-/*
- * Note that any allocations which are exact multiples of PAGE_SIZE, or
- * which are >= ZALLOC_ZONE_LIMIT, will fall through to the kmem subsystem.
- */
-#define ZALLOC_ZONE_LIMIT (16 * 1024) /* max slab-managed alloc */
-#define ZALLOC_MIN_ZONE_SIZE (32 * 1024) /* minimum zone size */
-#define ZALLOC_MAX_ZONE_SIZE (128 * 1024) /* maximum zone size */
-#define ZALLOC_SLAB_MAGIC 0x736c6162 /* magic sanity */
-#define ZALLOC_OVSZ_MAGIC 0x736c6163 /* magic sanity */
-#define ZALLOC_SLAB_SLIDE 20
-
-
-#if ZALLOC_ZONE_LIMIT == 16384
-#define NZONES 72
-#elif ZALLOC_ZONE_LIMIT == 32768
-#define NZONES 80
-#else
-#error "I couldn't figure out NZONES"
-#endif
-
-/*
- * Chunk structure for free elements
- */
-typedef struct SLChunk {
- struct SLChunk *c_Next;
-} SLChunk;
-
-/*
- * The IN-BAND zone header is placed at the beginning of each zone.
- */
-typedef struct SLZone {
- __int32_t z_Magic; /* magic number for sanity check */
- int z_Cpu; /* which cpu owns this zone? */
- struct globaldata *z_CpuGd;
- int z_NFree; /* total free chunks / ualloc space in zone */
- struct SLZone *z_Next; /* ZoneAry[] link if z_NFree non-zero */
- int z_NMax; /* maximum free chunks */
- char *z_BasePtr; /* pointer to start of chunk array */
- int z_UIndex; /* current initial allocation index */
- int z_UEndIndex; /* last (first) allocation index */
- int z_ChunkSize; /* chunk size for validation */
- int z_FirstFreePg; /* chunk list on a page-by-page basis */
- int z_ZoneIndex;
- int z_Flags;
- SLChunk *z_PageAry[ZALLOC_MAX_ZONE_SIZE / PAGE_SIZE];
-} SLZone;
-
-#define SLZF_UNOTZEROD 0x0001
-
-typedef struct SLGlobalData {
- SLZone *ZoneAry[NZONES]; /* linked list of zones NFree > 0 */
- SLZone *FreeZones; /* whole zones that have become free */
- SLZone *FreeOvZones; /* oversized zones */
- int NFreeZones; /* free zone count */
- int JunkIndex;
- struct malloc_type ZoneInfo; /* stats on meta-zones allocated */
-} SLGlobalData;
-
-typedef struct SLOversized {
- struct SLOversized *ov_Next;
- void *ov_Ptr;
- __uintptr_t ov_Bytes;
-} SLOversized;
-
-void slab_init(void);
-void slab_malloc_init(void *data);
-void *slab_malloc(unsigned long size, struct malloc_type *type, int flags);
-void slab_free(void *ptr, struct malloc_type *info);
-
-#endif
-
+++ /dev/null
-/*
- * Copyright (c) 2003 Galen Sampson <galen_sampson@yahoo.com>
- * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/lib/libcaps/sysport.c,v 1.4 2004/07/29 08:55:02 dillon Exp $
- */
-#include "defs.h"
-
-#include "sendsys.h"
-#include <sys/syscall.h>
-#include <sys/sysproto.h>
-#include <sys/sysunion.h>
-
-/* XXX Temporary */
-#include <unistd.h>
-
-#ifdef DEBUG
-#include <stdio.h>
-#endif
-
-static int sysport_putport(lwkt_port_t port, lwkt_msg_t msg);
-static void sysport_loop(void *dummy);
-
-struct thread sys_td;
-lwkt_port_t sysport;
-
-void
-sysport_init(void)
-{
- lwkt_init_thread(&sys_td, libcaps_alloc_stack(LWKT_THREAD_STACK),
- LWKT_THREAD_STACK, TDF_SYSTHREAD, mycpu);
- sysport = &sys_td.td_msgport;
- sysport->mp_putport = sysport_putport;
- sysport->mp_flags = MSGPORTF_WAITING; /* XXX temporary */
- cpu_set_thread_handler(&sys_td, lwkt_exit, sysport_loop, NULL);
-}
-
-/************************************************************************
- * PORT FUNCTIONS *
- ************************************************************************/
-
-/*
- * XXX We might need to separte this function in the way *lwkt_putport*
- * is separated in the case of multiple cpus. Secifically we will need
- * a lwkt_sysputport_remote().
- */
-static
-int
-sysport_putport(lwkt_port_t port, lwkt_msg_t msg)
-{
- int error = 0;
- thread_t td = port->mp_td;
-
- /**
- * XXX sendsys() will only allow asynchronous messages from uid 0. This
- * is a kernel issue. See note below.
- */
- if(msg->ms_flags & MSGF_ASYNC)
- {
- /**
- * The message is not done.
- */
- msg->ms_flags &= ~MSGF_DONE;
- error = sendsys(NULL, msg, msg->ms_msgsize);
- if(error == EASYNC)
- {
- TAILQ_INSERT_TAIL(&port->mp_msgq, msg, ms_node);
- msg->ms_flags |= MSGF_QUEUED;
- /**
- * Shouldn't need this check, we are always waiting
- */
- if(port->mp_flags & MSGPORTF_WAITING)
- {
- lwkt_schedule(td);
- }
- }
-#ifdef DEBUG
- printf("async return error %d\n", error);
-#endif
- }
-
- /**
- * XXX this is a temporary hack until the kernel changes to implement
- * the desired asynchronous goals.
- *
- * The current asynchronous messaging systemcall interface that sendsys
- * uses has some potential security issues and is limited to use by the
- * superuser only. Synchronous messages are allowed by anyone. Sendsys
- * returns EPERM in the case where you are not the superuser but tried to
- * send an asynchonous message.
- *
- * If you are not the super user then the system call will be made again,
- * but without MSGF_ASYNC set.
- */
- if(error != EASYNC && error == EPERM)
- {
- msg->ms_flags &= ~MSGF_ASYNC;
-#ifdef DEBUG
- printf("Warning, only super user can send asynchonous system messages\n");
-#endif
- }
-
- /**
- * The message is synchronous. Send it sychronously.
- */
- if((msg->ms_flags & MSGF_ASYNC) == 0)
- {
- error = sendsys(NULL, msg, msg->ms_msgsize);
- msg->ms_flags |= MSGF_DONE;
- }
-
- return(error);
-}
-
-void *
-lwkt_syswaitport(lwkt_msg_t msg)
-{
- lwkt_msg_t rmsg;
-
- /**
- * Block awaiting a return from the kernel.
- */
- for(rmsg = (lwkt_msg_t)sendsys(NULL, NULL, -1); rmsg != msg; )
- {
- usleep(1000000 / 10);
- rmsg = (lwkt_msg_t)sendsys(NULL, NULL, -1);
-#ifdef DEBUG
- printf(" rmsg %p\n", rmsg);
-#endif
- }
-
- return msg;
-}
-
-/************************************************************************
- * THREAD FUNCTIONS *
- ************************************************************************/
-/*
- * XXX Temporary function that provides a mechanism to return an asynchronous
- * message completed by the kernel to be returned to the port it originated
- * from.
- */
-static
-void
-sysport_loop(void *dummy)
-{
- lwkt_msg_t msg;
-
- for(;;)
- {
- msg = lwkt_waitport(&curthread->td_msgport, NULL);
-
- msg = lwkt_syswaitport(msg);
-
- /**
- * The message was asynchronous
- */
- if(msg->ms_flags & MSGF_ASYNC)
- {
- lwkt_replymsg(msg, msg->ms_error);
- }
- else
- {
- msg->ms_flags |= MSGF_DONE;
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/lib/libcaps/sysport.h,v 1.1 2003/12/04 22:06:19 dillon Exp $
- */
-
-#ifndef _SYSPORT_H_
-#define _SYSPORT_H_
-
-struct lwkt_port;
-
-extern struct lwkt_port *sysport;
-
-void sysport_init(void);
-
-#endif /* _SYSPORT_H_ */
+++ /dev/null
-/*
- * THREAD.H
- *
- * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/lib/libcaps/thread.h,v 1.4 2004/10/18 17:54:35 eirikn Exp $
- */
-
-#ifndef _LIBCAPS_THREAD_H_
-#define _LIBCAPS_THREAD_H_
-
-#define LWKT_THREAD_STACK 65536
-
-struct thread;
-
-struct md_thread {
-
-};
-
-extern void *libcaps_alloc_stack(int);
-extern void libcaps_free_stack(void *, int);
-extern int tsleep(struct thread *, int, const char *, int);
-extern void lwkt_start_threading(struct thread *);
-extern void cpu_init_thread(struct thread *);
-extern void cpu_set_thread_handler(struct thread *, void (*)(void), void (*)(void *), void *);
-extern void kthread_exit(void) __dead2;
-extern void cpu_thread_exit(void) __dead2;
-
-/*
- * User overloads of lwkt_*
- * Unfortunately C doesn't support function overloading.
- * XXX we need some strong weak magic here....
- */
-struct globaldata;
-void lwkt_user_gdinit(struct globaldata *);
-
-extern int hz;
-
-#endif
-
+++ /dev/null
-/*
- * Copyright (c) 2003 Galen Sampson <galen_sampson@yahoo.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/lib/libcaps/uthread.c,v 1.5 2004/07/29 08:55:02 dillon Exp $
- */
-
-/*
- * Each cpu in a system has its own self-contained light weight kernel
- * thread scheduler, which means that generally speaking we only need
- * to use a critical section to avoid problems. Foreign thread
- * scheduling is queued via (async) IPIs.
- */
-
-#include "defs.h"
-
-void cpu_lwkt_switch(thread_t);
-
-/*
- * system message port for the system call interface
- */
-lwkt_port_t sysport;
-
-static void
-lwkt_idleloop(void *dummy)
-{
- globaldata_t gd = mycpu;
-
- DBPRINTF(("idlestart cpu %d pri %d (should be < 32) mpcount %d (should be 0)\n",
- gd->gd_cpuid, curthread->td_pri, curthread->td_mpcount));
-
- gd->gd_pid = getpid();
-
- for (;;) {
- /*
- * If only our 'main' thread is left, schedule it.
- */
- if (gd->gd_num_threads == gd->gd_sys_threads) {
- int i;
- globaldata_t tgd;
-
- for (i = 0; i < ncpus; ++i) {
- tgd = globaldata_find(i);
- if (tgd->gd_num_threads != tgd->gd_sys_threads)
- break;
- }
- if (i == ncpus && (main_td.td_flags & TDF_RUNQ) == 0)
- lwkt_schedule(&main_td);
- }
-
- /*
- * Wait for an interrupt, aka wait for a signal or an upcall to
- * occur, then switch away.
- */
- crit_enter();
- if (gd->gd_runqmask || (curthread->td_flags & TDF_IDLE_NOHLT)) {
- curthread->td_flags &= ~TDF_IDLE_NOHLT;
- } else {
- printf("cpu %d halting\n", gd->gd_cpuid);
- cpu_halt();
- printf("cpu %d resuming\n", gd->gd_cpuid);
- }
- crit_exit();
- lwkt_switch();
- }
-}
-
-/*
- * Userland override of lwkt_init_thread. The only difference is
- * the manipulation of gd->gd_num_threads.
- */
-static void
-lwkt_init_thread_remote(void *arg)
-{
- thread_t td = arg;
- globaldata_t gd = td->td_gd;
-
- printf("init_thread_remote td %p on cpu %d\n", td, gd->gd_cpuid);
-
- TAILQ_INSERT_TAIL(&gd->gd_tdallq, td, td_allq);
- ++gd->gd_num_threads;
- if (td->td_flags & TDF_SYSTHREAD)
- ++gd->gd_sys_threads;
-}
-
-void
-lwkt_init_thread(thread_t td, void *stack, int stksize, int flags,
- struct globaldata *gd)
-{
- bzero(td, sizeof(struct thread));
- td->td_kstack = stack;
- td->td_kstack_size = stksize;
- td->td_flags |= flags;
- td->td_gd = gd;
- td->td_pri = TDPRI_KERN_DAEMON + TDPRI_CRIT;
- lwkt_initport(&td->td_msgport, td);
- cpu_init_thread(td);
- if (td == &gd->gd_idlethread) {
- TAILQ_INSERT_TAIL(&gd->gd_tdallq, td, td_allq);
- /* idle thread is not counted in gd_num_threads */
- } else if (gd == mycpu) {
- crit_enter();
- TAILQ_INSERT_TAIL(&gd->gd_tdallq, td, td_allq);
- ++gd->gd_num_threads;
- if (td->td_flags & TDF_SYSTHREAD)
- ++gd->gd_sys_threads;
- crit_exit();
- } else {
- lwkt_send_ipiq(gd, lwkt_init_thread_remote, td);
- }
-}
-
-/*
- * Userland override of lwkt_exit. The only difference is
- * the manipulation of gd->gd_num_threads;
- */
-void
-lwkt_exit(void)
-{
- thread_t td = curthread;
- globaldata_t gd = mycpu;
-
- if (td->td_flags & TDF_VERBOSE)
- printf("kthread %p %s has exited\n", td, td->td_comm);
- crit_enter();
- lwkt_deschedule_self(td);
- ++gd->gd_tdfreecount;
- if (td->td_flags & TDF_SYSTHREAD)
- --gd->gd_sys_threads;
- --gd->gd_num_threads;
- TAILQ_INSERT_TAIL(&gd->gd_tdfreeq, td, td_threadq);
- cpu_thread_exit();
-}
-
-/*
- * Userland override of lwkt_gdinit. Called from mi_gdinit(). Note that
- * critical sections do not work until lwkt_init_thread() is called. The
- * idle thread will be left in a critical section.
- */
-void
-lwkt_gdinit(struct globaldata *gd)
-{
- int i;
-
- for (i = 0; i < sizeof(gd->gd_tdrunq)/sizeof(gd->gd_tdrunq[0]); ++i)
- TAILQ_INIT(&gd->gd_tdrunq[i]);
- gd->gd_runqmask = 0;
- gd->gd_curthread = &gd->gd_idlethread;
- TAILQ_INIT(&gd->gd_tdallq);
-
- /* Set up this cpu's idle thread */
- lwkt_init_thread(&gd->gd_idlethread,
- libcaps_alloc_stack(LWKT_THREAD_STACK), LWKT_THREAD_STACK,
- 0, gd);
- cpu_set_thread_handler(&gd->gd_idlethread, lwkt_exit, lwkt_idleloop, NULL);
-}
-
-/*
- * Start threading.
- */
-void
-lwkt_start_threading(thread_t td)
-{
- lwkt_switch();
-}
-
#######################################################################
# $Id: pfi.conf,v 1.7 2005/02/24 23:23:15 cpressey Exp $
-# $DragonFly: src/nrelease/gui/etc/defaults/pfi.conf,v 1.2 2008/10/23 16:45:36 swildner Exp $
# Defaults for pfi.conf.
# A space-separated list of what services to restart when we are done
pfi_run=""
# What transport layer the DFUI in the installer should use. Valid
-# values are currently "caps", "npipe", and "tcp".
+# values are currently "npipe" and "tcp".
pfi_dfui_transport="tcp"
#######################################################################
# $Id: pfi.conf,v 1.7 2005/02/24 23:23:15 cpressey Exp $
-# $DragonFly: src/nrelease/installer/etc/defaults/pfi.conf,v 1.9 2008/10/23 16:45:36 swildner Exp $
# Defaults for pfi.conf.
# A space-separated list of what services to restart when we are done
pfi_run=""
# What transport layer the DFUI in the installer should use. Valid
-# values are currently "caps", "npipe", and "tcp".
+# values are currently "npipe" and "tcp".
pfi_dfui_transport="tcp"
kern/lwkt_token.c standard
kern/lwkt_msgport.c standard
kern/lwkt_serialize.c standard
-kern/lwkt_caps.c standard
kern/kern_dsched.c standard
kern/kern_sensors.c standard
kern/kern_spinlock.c standard
{ AS(varsym_list_args), (sy_call_t *)sys_varsym_list }, /* 452 = varsym_list */
{ AS(upc_register_args), (sy_call_t *)sys_upc_register }, /* 453 = upc_register */
{ AS(upc_control_args), (sy_call_t *)sys_upc_control }, /* 454 = upc_control */
- { AS(caps_sys_service_args), (sy_call_t *)sys_caps_sys_service }, /* 455 = caps_sys_service */
- { AS(caps_sys_client_args), (sy_call_t *)sys_caps_sys_client }, /* 456 = caps_sys_client */
- { AS(caps_sys_close_args), (sy_call_t *)sys_caps_sys_close }, /* 457 = caps_sys_close */
- { AS(caps_sys_put_args), (sy_call_t *)sys_caps_sys_put }, /* 458 = caps_sys_put */
- { AS(caps_sys_reply_args), (sy_call_t *)sys_caps_sys_reply }, /* 459 = caps_sys_reply */
- { AS(caps_sys_get_args), (sy_call_t *)sys_caps_sys_get }, /* 460 = caps_sys_get */
- { AS(caps_sys_wait_args), (sy_call_t *)sys_caps_sys_wait }, /* 461 = caps_sys_wait */
- { AS(caps_sys_abort_args), (sy_call_t *)sys_caps_sys_abort }, /* 462 = caps_sys_abort */
- { AS(caps_sys_getgen_args), (sy_call_t *)sys_caps_sys_getgen }, /* 463 = caps_sys_getgen */
- { AS(caps_sys_setgen_args), (sy_call_t *)sys_caps_sys_setgen }, /* 464 = caps_sys_setgen */
+ { 0, (sy_call_t *)sys_nosys }, /* 455 = obsolete caps_sys_service */
+ { 0, (sy_call_t *)sys_nosys }, /* 456 = obsolete caps_sys_client */
+ { 0, (sy_call_t *)sys_nosys }, /* 457 = obsolete caps_sys_close */
+ { 0, (sy_call_t *)sys_nosys }, /* 458 = obsolete caps_sys_put */
+ { 0, (sy_call_t *)sys_nosys }, /* 459 = obsolete caps_sys_reply */
+ { 0, (sy_call_t *)sys_nosys }, /* 460 = obsolete caps_sys_get */
+ { 0, (sy_call_t *)sys_nosys }, /* 461 = obsolete caps_sys_wait */
+ { 0, (sy_call_t *)sys_nosys }, /* 462 = obsolete caps_sys_abort */
+ { 0, (sy_call_t *)sys_nosys }, /* 463 = obsolete caps_sys_getgen */
+ { 0, (sy_call_t *)sys_nosys }, /* 464 = obsolete caps_sys_setgen */
{ AS(exec_sys_register_args), (sy_call_t *)sys_exec_sys_register }, /* 465 = exec_sys_register */
{ AS(exec_sys_unregister_args), (sy_call_t *)sys_exec_sys_unregister }, /* 466 = exec_sys_unregister */
{ AS(sys_checkpoint_args), (sy_call_t *)sys_sys_checkpoint }, /* 467 = sys_checkpoint */
#include <sys/jail.h>
#include <sys/kern_syscall.h>
#include <sys/upcall.h>
-#include <sys/caps.h>
#include <sys/unistd.h>
#include <sys/eventhandler.h>
#include <sys/dsched.h>
/* NOT REACHED */
}
- caps_exit(lp->lwp_thread);
-
/* are we a task leader? */
if (p == p->p_leader) {
struct kill_args killArgs;
*
* @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
* $FreeBSD: src/sys/kern/kern_fork.c,v 1.72.2.14 2003/06/26 04:15:10 silby Exp $
- * $DragonFly: src/sys/kern/kern_fork.c,v 1.77 2008/05/18 20:02:02 nth Exp $
*/
#include "opt_ktrace.h"
#include <sys/ktrace.h>
#include <sys/unistd.h>
#include <sys/jail.h>
-#include <sys/caps.h>
#include <vm/vm.h>
#include <sys/lock.h>
* and make the child ready to run.
*/
cpu_fork(origlp, lp, flags);
- caps_fork(origlp->lwp_thread, lp->lwp_thread);
kqueue_init(&lp->lwp_kqueue, destproc->p_fd);
/*
+++ /dev/null
-/*
- * Copyright (c) 2003,2004 The DragonFly Project. All rights reserved.
- *
- * This code is derived from software contributed to The DragonFly Project
- * by Matthew Dillon <dillon@backplane.com>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name of The DragonFly Project nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific, prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/sys/kern/lwkt_caps.c,v 1.13 2007/02/26 21:41:08 corecode Exp $
- */
-
-/*
- * This module implements the DragonFly LWKT IPC rendezvous and message
- * passing API which operates between userland processes, between userland
- * threads, and between userland processes and kernel threads. This API
- * is known as the CAPS interface.
- *
- * Generally speaking this module abstracts the LWKT message port interface
- * into userland Clients and Servers rendezvous through ports named
- * by or wildcarded by (name,uid,gid). The kernel provides system calls
- * which may be assigned to the mp_* fields in a userland-supplied
- * kernel-managed port, and a registration interface which associates an
- * upcall with a userland port. The kernel tracks authentication information
- * and deals with connection failures by automatically replying to unreplied
- * messages.
- *
- * From the userland perspective a client/server connection involves two
- * message ports on the client and two message ports on the server.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/sysproto.h>
-#include <sys/malloc.h>
-#include <sys/proc.h>
-#include <sys/ucred.h>
-#include <sys/caps.h>
-#include <sys/sysctl.h>
-
-#include <sys/mplock2.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-
-static int caps_process_msg(caps_kinfo_t caps, caps_kmsg_t msg, struct caps_sys_get_args *uap);
-static void caps_free(caps_kinfo_t caps);
-static void caps_free_msg(caps_kmsg_t msg);
-static int caps_name_check(const char *name, size_t len);
-static caps_kinfo_t caps_free_msg_mcaps(caps_kmsg_t msg);
-static caps_kinfo_t kern_caps_sys_service(const char *name, uid_t uid,
- gid_t gid, struct ucred *cred,
- int flags, int *error);
-static caps_kinfo_t kern_caps_sys_client(const char *name, uid_t uid,
- gid_t gid, struct ucred *cred, int flags, int *error);
-
-#define CAPS_HSIZE 64
-#define CAPS_HMASK (CAPS_HSIZE - 1)
-
-static caps_kinfo_t caps_hash_ary[CAPS_HSIZE];
-static int caps_waitsvc;
-
-MALLOC_DEFINE(M_CAPS, "caps", "caps IPC messaging");
-
-static int caps_enabled;
-SYSCTL_INT(_kern, OID_AUTO, caps_enabled,
- CTLFLAG_RW, &caps_enabled, 0, "Enable CAPS");
-
-/************************************************************************
- * INLINE SUPPORT FUNCTIONS *
- ************************************************************************/
-
-static __inline
-struct caps_kinfo **
-caps_hash(const char *name, int len)
-{
- int hv = 0x7123F4B3;
-
- while (--len >= 0)
- hv = (hv << 5) ^ name[len] ^ (hv >> 23);
- return(&caps_hash_ary[(hv ^ (hv >> 16)) & CAPS_HMASK]);
-}
-
-static __inline
-void
-caps_hold(caps_kinfo_t caps)
-{
- ++caps->ci_refs;
-}
-
-static __inline
-void
-caps_drop(caps_kinfo_t caps)
-{
- if (--caps->ci_refs == 0)
- caps_free(caps);
-}
-
-/************************************************************************
- * STATIC SUPPORT FUNCTIONS *
- ************************************************************************/
-
-static
-caps_kinfo_t
-caps_find(const char *name, int len, uid_t uid, gid_t gid)
-{
- caps_kinfo_t caps;
- struct caps_kinfo **chash;
-
- chash = caps_hash(name, len);
- for (caps = *chash; caps; caps = caps->ci_hnext) {
- if ((uid == (uid_t)-1 || uid == caps->ci_uid) &&
- (gid == (gid_t)-1 || gid == caps->ci_gid) &&
- len == caps->ci_namelen &&
- bcmp(name, caps->ci_name, len) == 0
- ) {
- caps_hold(caps);
- break;
- }
- }
- return(caps);
-}
-
-static
-caps_kinfo_t
-caps_find_id(thread_t td, int id)
-{
- caps_kinfo_t caps;
-
- for (caps = td->td_caps; caps; caps = caps->ci_tdnext) {
- if (caps->ci_id == id) {
- caps_hold(caps);
- break;
- }
- }
- return(caps);
-}
-
-static
-caps_kinfo_t
-caps_alloc(thread_t td, const char *name, int len, uid_t uid, gid_t gid,
- int flags, caps_type_t type)
-{
- struct caps_kinfo **chash;
- caps_kinfo_t caps;
- caps_kinfo_t ctmp;
-
- caps = kmalloc(offsetof(struct caps_kinfo, ci_name[len+1]),
- M_CAPS, M_WAITOK|M_ZERO);
- TAILQ_INIT(&caps->ci_msgpendq);
- TAILQ_INIT(&caps->ci_msguserq);
- caps->ci_uid = uid; /* -1 == not registered for uid search */
- caps->ci_gid = gid; /* -1 == not registered for gid search */
- caps->ci_type = type;
- caps->ci_refs = 1; /* CAPKF_TDLIST reference */
- caps->ci_namelen = len;
- caps->ci_flags = flags;
- bcopy(name, caps->ci_name, len + 1);
- if (type == CAPT_SERVICE) {
- chash = caps_hash(caps->ci_name, len);
- caps->ci_hnext = *chash;
- *chash = caps;
- caps->ci_flags |= CAPKF_HLIST;
- }
- if (td->td_caps) {
- caps->ci_id = td->td_caps->ci_id + 1;
- if (caps->ci_id < 0) {
- /*
- * It is virtually impossible for this case to occur.
- */
- caps->ci_id = 1;
- while ((ctmp = caps_find_id(td, caps->ci_id)) != NULL) {
- caps_drop(ctmp);
- ++caps->ci_id;
- }
- }
- } else {
- caps->ci_id = 1;
- }
- caps->ci_flags |= CAPKF_TDLIST;
- caps->ci_tdnext = td->td_caps;
- caps->ci_td = td;
- td->td_caps = caps;
- return(caps);
-}
-
-static
-caps_kmsg_t
-caps_alloc_msg(caps_kinfo_t caps)
-{
- caps_kmsg_t msg;
-
- msg = kmalloc(sizeof(struct caps_kmsg), M_CAPS, M_WAITOK|M_ZERO);
- msg->km_msgid.c_id = (off_t)(uintptr_t)msg;
- return(msg);
-}
-
-static
-caps_kmsg_t
-caps_find_msg(caps_kinfo_t caps, off_t msgid)
-{
- caps_kmsg_t msg;
-
- TAILQ_FOREACH(msg, &caps->ci_msguserq, km_node) {
- if (msg->km_msgid.c_id == msgid)
- return(msg);
- }
- TAILQ_FOREACH(msg, &caps->ci_msgpendq, km_node) {
- if (msg->km_msgid.c_id == msgid)
- return(msg);
- }
- return(NULL);
-}
-
-static
-caps_kinfo_t
-caps_load_ccr(caps_kinfo_t caps, caps_kmsg_t msg, struct lwp *lp,
- void *udata, int ubytes)
-{
- struct ucred *cr = lp ? lp->lwp_thread->td_ucred : proc0.p_ucred;
- caps_kinfo_t rcaps;
- int i;
-
- /*
- * replace km_mcaps with new VM state, return the old km_mcaps. The
- * caller is expected to drop the rcaps ref count on return so we do
- * not do it ourselves.
- */
- rcaps = caps_free_msg_mcaps(msg); /* can be NULL */
- caps_hold(caps);
- msg->km_mcaps = caps;
- xio_init_ubuf(&msg->km_xio, udata, ubytes, XIOF_READ);
-
- msg->km_ccr.pid = lp ? lp->lwp_proc->p_pid : -1;
- msg->km_ccr.uid = cr->cr_ruid;
- msg->km_ccr.euid = cr->cr_uid;
- msg->km_ccr.gid = cr->cr_rgid;
- msg->km_ccr.ngroups = MIN(cr->cr_ngroups, CAPS_MAXGROUPS);
- for (i = 0; i < msg->km_ccr.ngroups; ++i)
- msg->km_ccr.groups[i] = cr->cr_groups[i];
- return(rcaps);
-}
-
-static void
-caps_dequeue_msg(caps_kinfo_t caps, caps_kmsg_t msg)
-{
- if (msg->km_flags & CAPKMF_ONUSERQ)
- TAILQ_REMOVE(&caps->ci_msguserq, msg, km_node);
- if (msg->km_flags & CAPKMF_ONPENDQ)
- TAILQ_REMOVE(&caps->ci_msgpendq, msg, km_node);
- msg->km_flags &= ~(CAPKMF_ONPENDQ|CAPKMF_ONUSERQ);
-}
-
-static void
-caps_put_msg(caps_kinfo_t caps, caps_kmsg_t msg, caps_msg_state_t state)
-{
- KKASSERT((msg->km_flags & (CAPKMF_ONUSERQ|CAPKMF_ONPENDQ)) == 0);
-
- msg->km_flags |= CAPKMF_ONPENDQ;
- msg->km_flags &= ~CAPKMF_PEEKED;
- msg->km_state = state;
- TAILQ_INSERT_TAIL(&caps->ci_msgpendq, msg, km_node);
-
- /*
- * Instead of waking up the service for both new messages and disposals,
- * just wakeup the service for new messages and it will process the
- * previous disposal in the same loop, reducing the number of context
- * switches required to run an IPC.
- */
- if (state != CAPMS_DISPOSE)
- wakeup(caps);
- caps_drop(caps);
-}
-
-/*
- * caps_free_msg_mcaps()
- */
-static
-caps_kinfo_t
-caps_free_msg_mcaps(caps_kmsg_t msg)
-{
- caps_kinfo_t mcaps;
-
- mcaps = msg->km_mcaps; /* may be NULL */
- msg->km_mcaps = NULL;
- if (msg->km_xio.xio_npages)
- xio_release(&msg->km_xio);
- return(mcaps);
-}
-
-/*
- * caps_free_msg()
- *
- * Free a caps placeholder message. The message must not be on any queues.
- */
-static void
-caps_free_msg(caps_kmsg_t msg)
-{
- caps_kinfo_t rcaps;
-
- if ((rcaps = caps_free_msg_mcaps(msg)) != NULL)
- caps_drop(rcaps);
- kfree(msg, M_CAPS);
-}
-
-/*
- * Validate the service name
- */
-static int
-caps_name_check(const char *name, size_t len)
-{
- size_t i;
- char c;
-
- for (i = len - 1; i >= 0; --i) {
- c = name[i];
- if (c >= '0' && c <= '9')
- continue;
- if (c >= 'a' && c <= 'z')
- continue;
- if (c >= 'A' && c <= 'Z')
- continue;
- if (c == '_' || c == '.')
- continue;
- return(EINVAL);
- }
- return(0);
-}
-
-/*
- * caps_term()
- *
- * Terminate portions of a caps info structure. This is used to close
- * an end-point or to flush particular messages on an end-point.
- *
- * This function should not be called with CAPKF_TDLIST unless the caller
- * has an additional hold on the caps structure.
- */
-static void
-caps_term(caps_kinfo_t caps, int flags, caps_kinfo_t cflush)
-{
- struct thread *td = curthread;
- struct caps_kinfo **scan;
- caps_kmsg_t msg;
-
- if (flags & CAPKF_TDLIST)
- caps->ci_flags |= CAPKF_CLOSED;
-
- if (flags & CAPKF_FLUSH) {
- int mflags;
- struct caps_kmsg_queue tmpuserq;
- struct caps_kmsg_queue tmppendq;
- caps_kinfo_t rcaps;
-
- TAILQ_INIT(&tmpuserq);
- TAILQ_INIT(&tmppendq);
-
- while ((msg = TAILQ_FIRST(&caps->ci_msgpendq)) != NULL ||
- (msg = TAILQ_FIRST(&caps->ci_msguserq)) != NULL
- ) {
- mflags = msg->km_flags & (CAPKMF_ONUSERQ|CAPKMF_ONPENDQ);
- caps_dequeue_msg(caps, msg);
-
- if (cflush && msg->km_mcaps != cflush) {
- if (mflags & CAPKMF_ONUSERQ)
- TAILQ_INSERT_TAIL(&tmpuserq, msg, km_node);
- else
- TAILQ_INSERT_TAIL(&tmppendq, msg, km_node);
- } else {
- /*
- * Dispose of the message. If the received message is a
- * request we must reply it. If the received message is
- * a reply we must return it for disposal. If the
- * received message is a disposal request we simply free it.
- */
- switch(msg->km_state) {
- case CAPMS_REQUEST:
- case CAPMS_REQUEST_RETRY:
- rcaps = caps_load_ccr(caps, msg, td->td_lwp, NULL, 0);
- if (rcaps->ci_flags & CAPKF_CLOSED) {
- /*
- * can't reply, if we never read the message (its on
- * the pending queue), or if we are closed ourselves,
- * we can just free the message. Otherwise we have
- * to send ourselves a disposal request (multi-threaded
- * services have to deal with disposal requests for
- * messages that might be in progress).
- */
- if ((caps->ci_flags & CAPKF_CLOSED) ||
- (mflags & CAPKMF_ONPENDQ)
- ) {
- caps_free_msg(msg);
- caps_drop(rcaps);
- } else {
- caps_drop(rcaps);
- caps_hold(caps); /* for message */
- caps_put_msg(caps, msg, CAPMS_DISPOSE);
- }
- } else {
- /*
- * auto-reply to the originator. rcaps already
- * has a dangling hold so we do not have to hold it
- * again.
- */
- caps_put_msg(rcaps, msg, CAPMS_REPLY);
- }
- break;
- case CAPMS_REPLY:
- case CAPMS_REPLY_RETRY:
- rcaps = caps_load_ccr(caps, msg, td->td_lwp, NULL, 0);
- if (caps == rcaps || (rcaps->ci_flags & CAPKF_CLOSED)) {
- caps_free_msg(msg); /* degenerate disposal case */
- caps_drop(rcaps);
- } else {
- caps_put_msg(rcaps, msg, CAPMS_DISPOSE);
- }
- break;
- case CAPMS_DISPOSE:
- caps_free_msg(msg);
- break;
- }
- }
- }
- while ((msg = TAILQ_FIRST(&tmpuserq)) != NULL) {
- TAILQ_REMOVE(&tmpuserq, msg, km_node);
- TAILQ_INSERT_TAIL(&caps->ci_msguserq, msg, km_node);
- msg->km_flags |= CAPKMF_ONUSERQ;
- }
- while ((msg = TAILQ_FIRST(&tmppendq)) != NULL) {
- TAILQ_REMOVE(&tmppendq, msg, km_node);
- TAILQ_INSERT_TAIL(&caps->ci_msgpendq, msg, km_node);
- msg->km_flags |= CAPKMF_ONPENDQ;
- }
- }
- if ((flags & CAPKF_HLIST) && (caps->ci_flags & CAPKF_HLIST)) {
- for (scan = caps_hash(caps->ci_name, caps->ci_namelen);
- *scan != caps;
- scan = &(*scan)->ci_hnext
- ) {
- KKASSERT(*scan != NULL);
- }
- *scan = caps->ci_hnext;
- caps->ci_hnext = (void *)-1;
- caps->ci_flags &= ~CAPKF_HLIST;
- }
- if ((flags & CAPKF_TDLIST) && (caps->ci_flags & CAPKF_TDLIST)) {
- for (scan = &caps->ci_td->td_caps;
- *scan != caps;
- scan = &(*scan)->ci_tdnext
- ) {
- KKASSERT(*scan != NULL);
- }
- *scan = caps->ci_tdnext;
- caps->ci_flags &= ~CAPKF_TDLIST;
- caps->ci_tdnext = (void *)-1;
- caps->ci_td = NULL;
- caps_drop(caps);
- }
- if ((flags & CAPKF_RCAPS) && (caps->ci_flags & CAPKF_RCAPS)) {
- caps_kinfo_t ctmp;
-
- caps->ci_flags &= ~CAPKF_RCAPS;
- if ((ctmp = caps->ci_rcaps)) {
- caps->ci_rcaps = NULL;
- caps_term(ctmp, CAPKF_FLUSH, caps);
- caps_drop(ctmp);
- }
- }
-}
-
-static void
-caps_free(caps_kinfo_t caps)
-{
- KKASSERT(TAILQ_EMPTY(&caps->ci_msgpendq));
- KKASSERT(TAILQ_EMPTY(&caps->ci_msguserq));
- KKASSERT((caps->ci_flags & (CAPKF_HLIST|CAPKF_TDLIST)) == 0);
- kfree(caps, M_CAPS);
-}
-
-/************************************************************************
- * PROCESS SUPPORT FUNCTIONS *
- ************************************************************************/
-
-/*
- * Create dummy entries in p2 so we can return the appropriate
- * error code. Robust userland code will check the error for a
- * forked condition and reforge the connection.
- */
-void
-caps_fork(struct thread *td1, struct thread *td2)
-{
- caps_kinfo_t caps1;
- caps_kinfo_t caps2;
-
- /*
- * Create dummy entries with the same id's as the originals. Note
- * that service entries are not re-added to the hash table. The
- * dummy entries return an ENOTCONN error allowing userland code to
- * detect that a fork occured. Userland must reconnect to the service.
- */
- for (caps1 = td1->td_caps; caps1; caps1 = caps1->ci_tdnext) {
- if (caps1->ci_flags & CAPF_NOFORK)
- continue;
- caps2 = caps_alloc(td2,
- caps1->ci_name, caps1->ci_namelen,
- caps1->ci_uid, caps1->ci_gid,
- caps1->ci_flags & CAPF_UFLAGS, CAPT_FORKED);
- caps2->ci_id = caps1->ci_id;
- }
-
- /*
- * Reverse the list order to maintain highest-id-first
- */
- caps2 = td2->td_caps;
- td2->td_caps = NULL;
- while (caps2) {
- caps1 = caps2->ci_tdnext;
- caps2->ci_tdnext = td2->td_caps;
- td2->td_caps = caps2;
- caps2 = caps1;
- }
-}
-
-void
-caps_exit(struct thread *td)
-{
- caps_kinfo_t caps;
-
- while ((caps = td->td_caps) != NULL) {
- caps_hold(caps);
- caps_term(caps, CAPKF_TDLIST|CAPKF_HLIST|CAPKF_FLUSH|CAPKF_RCAPS, NULL);
- caps_drop(caps);
- }
-}
-
-/************************************************************************
- * SYSTEM CALLS *
- ************************************************************************/
-
-/*
- * caps_sys_service(name, uid, gid, upcid, flags);
- *
- * Create an IPC service using the specified name, uid, gid, and flags.
- * Either uid or gid can be -1, but not both. The port identifier is
- * returned.
- *
- * upcid can either be an upcall or a kqueue identifier (XXX)
- *
- * MPALMOSTSAFE
- */
-int
-sys_caps_sys_service(struct caps_sys_service_args *uap)
-{
- struct ucred *cred = curthread->td_ucred;
- char name[CAPS_MAXNAMELEN];
- caps_kinfo_t caps;
- size_t len;
- int error;
-
- if (caps_enabled == 0)
- return(EOPNOTSUPP);
- if ((error = copyinstr(uap->name, name, CAPS_MAXNAMELEN, &len)) != 0)
- return(error);
- if ((ssize_t)--len <= 0)
- return(EINVAL);
- get_mplock();
-
- if ((error = caps_name_check(name, len)) == 0) {
- caps = kern_caps_sys_service(name, uap->uid, uap->gid, cred,
- uap->flags & CAPF_UFLAGS, &error);
- if (caps)
- uap->sysmsg_result = caps->ci_id;
- }
- rel_mplock();
- return(error);
-}
-
-/*
- * caps_sys_client(name, uid, gid, upcid, flags);
- *
- * Create an IPC client connected to the specified service. Either uid or gid
- * may be -1, indicating a wildcard, but not both. The port identifier is
- * returned.
- *
- * upcid can either be an upcall or a kqueue identifier (XXX)
- *
- * MPALMOSTSAFE
- */
-int
-sys_caps_sys_client(struct caps_sys_client_args *uap)
-{
- struct ucred *cred = curthread->td_ucred;
- char name[CAPS_MAXNAMELEN];
- caps_kinfo_t caps;
- size_t len;
- int error;
-
- if (caps_enabled == 0)
- return(EOPNOTSUPP);
- if ((error = copyinstr(uap->name, name, CAPS_MAXNAMELEN, &len)) != 0)
- return(error);
- if ((ssize_t)--len <= 0)
- return(EINVAL);
- get_mplock();
-
- if ((error = caps_name_check(name, len)) == 0) {
- caps = kern_caps_sys_client(name, uap->uid, uap->gid, cred,
- uap->flags & CAPF_UFLAGS, &error);
- if (caps)
- uap->sysmsg_result = caps->ci_id;
- }
- rel_mplock();
- return(error);
-}
-
-/*
- * MPALMOSTSAFE
- */
-int
-sys_caps_sys_close(struct caps_sys_close_args *uap)
-{
- struct thread *td = curthread;
- caps_kinfo_t caps;
- int error;
-
- get_mplock();
-
- if ((caps = caps_find_id(td, uap->portid)) != NULL) {
- caps_term(caps, CAPKF_TDLIST|CAPKF_HLIST|CAPKF_FLUSH|CAPKF_RCAPS,
- NULL);
- caps_drop(caps);
- error = 0;
- } else {
- error = EINVAL;
- }
- rel_mplock();
- return(error);
-}
-
-/*
- * MPALMOSTSAFE
- */
-int
-sys_caps_sys_setgen(struct caps_sys_setgen_args *uap)
-{
- struct thread *td = curthread;
- caps_kinfo_t caps;
- int error;
-
- get_mplock();
-
- if ((caps = caps_find_id(td, uap->portid)) != NULL) {
- if (caps->ci_type == CAPT_FORKED) {
- error = ENOTCONN;
- } else {
- caps->ci_gen = uap->gen;
- error = 0;
- }
- caps_drop(caps);
- } else {
- error = EINVAL;
- }
- rel_mplock();
- return(error);
-}
-
-/*
- * MPALMOSTSAFE
- */
-int
-sys_caps_sys_getgen(struct caps_sys_getgen_args *uap)
-{
- struct thread *td = curthread;
- caps_kinfo_t caps;
- int error;
-
- get_mplock();
-
- if ((caps = caps_find_id(td, uap->portid)) != NULL) {
- if (caps->ci_type == CAPT_FORKED) {
- error = ENOTCONN;
- } else if (caps->ci_rcaps == NULL) {
- error = EINVAL;
- } else {
- uap->sysmsg_result64 = caps->ci_rcaps->ci_gen;
- error = 0;
- }
- caps_drop(caps);
- } else {
- error = EINVAL;
- }
- rel_mplock();
- return(error);
-}
-
-/*
- * caps_sys_put(portid, msg, msgsize)
- *
- * Send an opaque message of the specified size to the specified port. This
- * function may only be used with a client port. The message id is returned.
- *
- * MPALMOSTSAFE
- */
-int
-sys_caps_sys_put(struct caps_sys_put_args *uap)
-{
- struct thread *td = curthread;
- caps_kinfo_t caps;
- caps_kmsg_t msg;
- int error;
-
- if (uap->msgsize < 0)
- return(EINVAL);
- get_mplock();
-
- if ((caps = caps_find_id(td, uap->portid)) == NULL) {
- error = EINVAL;
- goto done;
- }
- if (caps->ci_type == CAPT_FORKED) {
- error = ENOTCONN;
- } else if (caps->ci_rcaps == NULL) {
- error = EINVAL;
- } else if (caps->ci_cmsgcount > CAPS_MAXINPROG) {
- /*
- * If this client has queued a large number of messages return
- * ENOBUFS. The client must process some replies before it can
- * send new messages. The server can also throttle a client by
- * holding its replies. XXX allow a server to refuse messages from
- * a client.
- */
- error = ENOBUFS;
- } else {
- msg = caps_alloc_msg(caps);
- uap->sysmsg_offset = msg->km_msgid.c_id;
-
- /*
- * If the remote end is closed return ENOTCONN immediately, otherwise
- * send it to the remote end.
- *
- * Note: since this is a new message, caps_load_ccr() returns a remote
- * caps of NULL.
- */
- if (caps->ci_rcaps->ci_flags & CAPKF_CLOSED) {
- error = ENOTCONN;
- caps_free_msg(msg);
- } else {
- /*
- * new message, load_ccr returns NULL. hold rcaps for put_msg
- */
- error = 0;
- caps_load_ccr(caps, msg, td->td_lwp, uap->msg, uap->msgsize);
- caps_hold(caps->ci_rcaps);
- ++caps->ci_cmsgcount;
- caps_put_msg(caps->ci_rcaps, msg, CAPMS_REQUEST); /* drops rcaps */
- }
- }
- caps_drop(caps);
-done:
- rel_mplock();
- return(error);
-}
-
-/*
- * caps_sys_reply(portid, msg, msgsize, msgid)
- *
- * Reply to the message referenced by the specified msgid, supplying opaque
- * data back to the originator.
- *
- * MPALMOSTSAFE
- */
-int
-sys_caps_sys_reply(struct caps_sys_reply_args *uap)
-{
- struct thread *td = curthread;
- caps_kinfo_t caps;
- caps_kinfo_t rcaps;
- caps_kmsg_t msg;
- int error;
-
- if (uap->msgsize < 0)
- return(EINVAL);
- get_mplock();
-
- if ((caps = caps_find_id(td, uap->portid)) == NULL) {
- error = EINVAL;
- goto done;
- }
- if (caps->ci_type == CAPT_FORKED) {
- /*
- * The caps structure is just a fork placeholder, tell the caller
- * that he has to reconnect.
- */
- error = ENOTCONN;
- } else if ((msg = caps_find_msg(caps, uap->msgcid)) == NULL) {
- /*
- * Could not find message being replied to (other side might have
- * gone away).
- */
- error = EINVAL;
- } else if ((msg->km_flags & CAPKMF_ONUSERQ) == 0) {
- /*
- * Trying to reply to a non-replyable message
- */
- error = EINVAL;
- } else {
- /*
- * If the remote end is closed requeue to ourselves for disposal.
- * Otherwise send the reply to the other end (the other end will
- * return a passive DISPOSE to us when it has eaten the data)
- */
- error = 0;
- caps_dequeue_msg(caps, msg);
- if (msg->km_mcaps->ci_flags & CAPKF_CLOSED) {
- caps_drop(caps_load_ccr(caps, msg, td->td_lwp, NULL, 0));
- caps_hold(caps); /* ref for message */
- caps_put_msg(caps, msg, CAPMS_DISPOSE);
- } else {
- rcaps = caps_load_ccr(caps, msg, td->td_lwp, uap->msg, uap->msgsize);
- caps_put_msg(rcaps, msg, CAPMS_REPLY);
- }
- }
- caps_drop(caps);
-done:
- rel_mplock();
- return(error);
-}
-
-/*
- * caps_sys_get(portid, msg, maxsize, msgid, ccr)
- *
- * Retrieve the next ready message on the port, store its message id in
- * uap->msgid and return the length of the message. If the message is too
- * large to fit the message id, length, and creds are still returned, but
- * the message is not dequeued (the caller is expected to call again with
- * a larger buffer or to reply the messageid if it does not want to handle
- * the message).
- *
- * EWOULDBLOCK is returned if no messages are pending. Note that 0-length
- * messages are perfectly acceptable so 0 can be legitimately returned.
- *
- * MPALMOSTSAFE
- */
-int
-sys_caps_sys_get(struct caps_sys_get_args *uap)
-{
- struct thread *td = curthread;
- caps_kinfo_t caps;
- caps_kmsg_t msg;
- int error;
-
- if (uap->maxsize < 0)
- return(EINVAL);
- get_mplock();
-
- if ((caps = caps_find_id(td, uap->portid)) != NULL) {
- if (caps->ci_type == CAPT_FORKED) {
- error = ENOTCONN;
- } else if ((msg = TAILQ_FIRST(&caps->ci_msgpendq)) == NULL) {
- error = EWOULDBLOCK;
- } else {
- error = caps_process_msg(caps, msg, uap);
- }
- caps_drop(caps);
- } else {
- error = EINVAL;
- }
- rel_mplock();
- return(error);
-}
-
-/*
- * caps_sys_wait(portid, msg, maxsize, msgid, ccr)
- *
- * Retrieve the next ready message on the port, store its message id in
- * uap->msgid and return the length of the message. If the message is too
- * large to fit the message id, length, and creds are still returned, but
- * the message is not dequeued (the caller is expected to call again with
- * a larger buffer or to reply the messageid if it does not want to handle
- * the message).
- *
- * This function blocks until interrupted or a message is received.
- * Note that 0-length messages are perfectly acceptable so 0 can be
- * legitimately returned.
- *
- * MPALMOSTSAFE
- */
-int
-sys_caps_sys_wait(struct caps_sys_wait_args *uap)
-{
- struct thread *td = curthread;
- caps_kinfo_t caps;
- caps_kmsg_t msg;
- int error;
-
- if (uap->maxsize < 0)
- return(EINVAL);
- get_mplock();
-
- if ((caps = caps_find_id(td, uap->portid)) != NULL) {
- if (caps->ci_type == CAPT_FORKED) {
- error = ENOTCONN;
- } else {
- error = 0;
- while ((msg = TAILQ_FIRST(&caps->ci_msgpendq)) == NULL) {
- if ((error = tsleep(caps, PCATCH, "caps", 0)) != 0)
- break;
- }
- if (error == 0) {
- error = caps_process_msg(caps, msg,
- (struct caps_sys_get_args *)uap);
- }
- }
- caps_drop(caps);
- } else {
- error = EINVAL;
- }
- rel_mplock();
- return(error);
-}
-
-static int
-caps_process_msg(caps_kinfo_t caps, caps_kmsg_t msg,
- struct caps_sys_get_args *uap)
-{
- struct thread *td = curthread;
- int error = 0;
- int msgsize;
- caps_kinfo_t rcaps;
-
- msg->km_flags |= CAPKMF_PEEKED;
- msgsize = msg->km_xio.xio_bytes;
- if (msgsize <= uap->maxsize)
- caps_dequeue_msg(caps, msg);
-
- if (msg->km_xio.xio_bytes != 0) {
- error = xio_copy_xtou(&msg->km_xio, 0, uap->msg,
- min(msg->km_xio.xio_bytes, uap->maxsize));
- if (error) {
- if (msg->km_mcaps->ci_td && msg->km_mcaps->ci_td->td_proc) {
- kprintf("xio_copy_xtou: error %d from proc %d\n",
- error, msg->km_mcaps->ci_td->td_proc->p_pid);
- }
- if (msgsize > uap->maxsize)
- caps_dequeue_msg(caps, msg);
- msgsize = 0;
- error = 0;
- }
- }
-
- if (uap->msgid)
- error = copyout(&msg->km_msgid, uap->msgid, sizeof(msg->km_msgid));
- if (uap->ccr)
- error = copyout(&msg->km_ccr, uap->ccr, sizeof(msg->km_ccr));
- if (error == 0)
- uap->sysmsg_result = msgsize;
-
- /*
- * If the message was dequeued we must deal with it.
- */
- if (msgsize <= uap->maxsize) {
- switch(msg->km_state) {
- case CAPMS_REQUEST:
- case CAPMS_REQUEST_RETRY:
- TAILQ_INSERT_TAIL(&caps->ci_msguserq, msg, km_node);
- msg->km_flags |= CAPKMF_ONUSERQ;
- break;
- case CAPMS_REPLY:
- case CAPMS_REPLY_RETRY:
- --caps->ci_cmsgcount;
- rcaps = caps_load_ccr(caps, msg, td->td_lwp, NULL, 0);
- if (caps == rcaps || (rcaps->ci_flags & CAPKF_CLOSED)) {
- /* degenerate disposal case */
- caps_free_msg(msg);
- caps_drop(rcaps);
- } else {
- caps_put_msg(rcaps, msg, CAPMS_DISPOSE);
- }
- break;
- case CAPMS_DISPOSE:
- caps_free_msg(msg);
- break;
- }
- }
- return(error);
-}
-
-/*
- * caps_sys_abort(portid, msgcid, flags)
- *
- * Abort a previously sent message. You must still wait for the message
- * to be returned after sending the abort request. This function will
- * return the appropriate CAPS_ABORT_* code depending on what it had
- * to do.
- *
- * MPALMOSTSAFE
- */
-int
-sys_caps_sys_abort(struct caps_sys_abort_args *uap)
-{
- uap->sysmsg_result = CAPS_ABORT_NOTIMPL;
- return(0);
-}
-
-/*
- * KERNEL SYSCALL SEPARATION SUPPORT FUNCTIONS
- */
-
-static
-caps_kinfo_t
-kern_caps_sys_service(const char *name, uid_t uid, gid_t gid,
- struct ucred *cred, int flags, int *error)
-{
- struct thread *td = curthread;
- caps_kinfo_t caps;
- int len;
-
- len = strlen(name);
-
- /*
- * Make sure we can use the uid and gid
- */
- if (cred) {
- if (cred->cr_uid != 0 && uid != (uid_t)-1 && cred->cr_uid != uid) {
- *error = EPERM;
- return(NULL);
- }
- if (cred->cr_uid != 0 && gid != (gid_t)-1 && !groupmember(gid, cred)) {
- *error = EPERM;
- return(NULL);
- }
- }
-
- /*
- * Handle CAPF_EXCL
- */
- if (flags & CAPF_EXCL) {
- if ((caps = caps_find(name, strlen(name), uid, gid)) != NULL) {
- caps_drop(caps);
- *error = EEXIST;
- return(NULL);
- }
- }
-
- /*
- * Create the service
- */
- caps = caps_alloc(td, name, len,
- uid, gid, flags & CAPF_UFLAGS, CAPT_SERVICE);
- wakeup(&caps_waitsvc);
- return(caps);
-}
-
-static
-caps_kinfo_t
-kern_caps_sys_client(const char *name, uid_t uid, gid_t gid,
- struct ucred *cred, int flags, int *error)
-{
- struct thread *td = curthread;
- caps_kinfo_t caps, rcaps;
- int len;
-
- len = strlen(name);
-
- /*
- * Locate the CAPS service (rcaps ref is for caps->ci_rcaps)
- */
-again:
- if ((rcaps = caps_find(name, len, uid, gid)) == NULL) {
- if (flags & CAPF_WAITSVC) {
- char cbuf[32];
- ksnprintf(cbuf, sizeof(cbuf), "C%s", name);
- *error = tsleep(&caps_waitsvc, PCATCH, cbuf, 0);
- if (*error == 0)
- goto again;
- } else {
- *error = ENOENT;
- }
- return(NULL);
- }
-
- /*
- * Check permissions
- */
- if (cred) {
- *error = EACCES;
- if ((flags & CAPF_USER) && (rcaps->ci_flags & CAPF_USER)) {
- if (rcaps->ci_uid != (uid_t)-1 && rcaps->ci_uid == cred->cr_uid)
- *error = 0;
- }
- if ((flags & CAPF_GROUP) && (rcaps->ci_flags & CAPF_GROUP)) {
- if (rcaps->ci_gid != (gid_t)-1 && groupmember(rcaps->ci_gid, cred))
- *error = 0;
- }
- if ((flags & CAPF_WORLD) && (rcaps->ci_flags & CAPF_WORLD)) {
- *error = 0;
- }
- if (*error) {
- caps_drop(rcaps);
- return(NULL);
- }
- } else {
- *error = 0;
- }
-
- /*
- * Allocate the client side and connect to the server
- */
- caps = caps_alloc(td, name, len,
- uid, gid, flags & CAPF_UFLAGS, CAPT_CLIENT);
- caps->ci_rcaps = rcaps;
- caps->ci_flags |= CAPKF_RCAPS;
- return(caps);
-}
-
#include <sys/kthread.h>
#include <machine/cpu.h>
#include <sys/lock.h>
-#include <sys/caps.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $DragonFly: src/sys/kern/lwkt_serialize.c,v 1.18 2008/10/04 14:22:44 swildner Exp $
*/
/*
* This API provides a fast locked-bus-cycle-based serializer. It's
#include <machine/cpufunc.h>
#include <machine/specialreg.h>
#include <sys/lock.h>
-#include <sys/caps.h>
struct exp_backoff {
int backoff;
#include <sys/kthread.h>
#include <machine/cpu.h>
#include <sys/lock.h>
-#include <sys/caps.h>
#include <sys/spinlock.h>
#include <sys/ktr.h>
*/
if (td->td_flags & TDF_VERBOSE)
kprintf("kthread %p %s has exited\n", td, td->td_comm);
- caps_exit(td);
biosched_done(td);
dsched_exit_thread(td);
#include <sys/kthread.h>
#include <machine/cpu.h>
#include <sys/lock.h>
-#include <sys/caps.h>
#include <sys/spinlock.h>
#include <sys/thread2.h>
"varsym_list", /* 452 = varsym_list */
"upc_register", /* 453 = upc_register */
"upc_control", /* 454 = upc_control */
- "caps_sys_service", /* 455 = caps_sys_service */
- "caps_sys_client", /* 456 = caps_sys_client */
- "caps_sys_close", /* 457 = caps_sys_close */
- "caps_sys_put", /* 458 = caps_sys_put */
- "caps_sys_reply", /* 459 = caps_sys_reply */
- "caps_sys_get", /* 460 = caps_sys_get */
- "caps_sys_wait", /* 461 = caps_sys_wait */
- "caps_sys_abort", /* 462 = caps_sys_abort */
- "caps_sys_getgen", /* 463 = caps_sys_getgen */
- "caps_sys_setgen", /* 464 = caps_sys_setgen */
+ "obs_caps_sys_service", /* 455 = obsolete caps_sys_service */
+ "obs_caps_sys_client", /* 456 = obsolete caps_sys_client */
+ "obs_caps_sys_close", /* 457 = obsolete caps_sys_close */
+ "obs_caps_sys_put", /* 458 = obsolete caps_sys_put */
+ "obs_caps_sys_reply", /* 459 = obsolete caps_sys_reply */
+ "obs_caps_sys_get", /* 460 = obsolete caps_sys_get */
+ "obs_caps_sys_wait", /* 461 = obsolete caps_sys_wait */
+ "obs_caps_sys_abort", /* 462 = obsolete caps_sys_abort */
+ "obs_caps_sys_getgen", /* 463 = obsolete caps_sys_getgen */
+ "obs_caps_sys_setgen", /* 464 = obsolete caps_sys_setgen */
"exec_sys_register", /* 465 = exec_sys_register */
"exec_sys_unregister", /* 466 = exec_sys_unregister */
"sys_checkpoint", /* 467 = sys_checkpoint */
452 STD BSD { int varsym_list(int level, char *buf, int maxsize, int *marker); }
453 STD BSD { int upc_register(struct upcall *upc, void *ctxfunc, void *func, void *data); }
454 STD BSD { int upc_control(int cmd, int upcid, void *data); }
-455 STD BSD { int caps_sys_service(const char *name, uid_t uid, gid_t gid, int upcid, int flags); }
-456 STD BSD { int caps_sys_client(const char *name, uid_t uid, gid_t gid, int upcid, int flags); }
-457 STD BSD { int caps_sys_close(int portid); }
-458 STD BSD { off_t caps_sys_put(int portid, void *msg, int msgsize); }
-459 STD BSD { int caps_sys_reply(int portid, void *msg, int msgsize, off_t msgcid); }
-460 STD BSD { int caps_sys_get(int portid, void *msg, int maxsize, struct caps_msgid *msgid, struct caps_cred *ccr); }
-461 STD BSD { int caps_sys_wait(int portid, void *msg, int maxsize, struct caps_msgid *msgid, struct caps_cred *ccr); }
-462 STD BSD { int caps_sys_abort(int portid, off_t msgcid, int flags); }
-463 STD BSD { off_t caps_sys_getgen(int portid); }
-464 STD BSD { int caps_sys_setgen(int portid, off_t gen); }
+455 OBSOL BSD caps_sys_service
+456 OBSOL BSD caps_sys_client
+457 OBSOL BSD caps_sys_close
+458 OBSOL BSD caps_sys_put
+459 OBSOL BSD caps_sys_reply
+460 OBSOL BSD caps_sys_get
+461 OBSOL BSD caps_sys_wait
+462 OBSOL BSD caps_sys_abort
+463 OBSOL BSD caps_sys_getgen
+464 OBSOL BSD caps_sys_setgen
465 STD BSD { int exec_sys_register(void *entry); }
466 STD BSD { int exec_sys_unregister(int id); }
467 STD BSD { int sys_checkpoint(int type, int fd, pid_t pid, int retval); }
+++ /dev/null
-/*
- * SYS/CAPS.H
- *
- * Implements an architecture independant Capability Service API
- *
- * $DragonFly: src/sys/sys/caps.h,v 1.11 2007/02/26 21:41:08 corecode Exp $
- */
-
-#ifndef _SYS_CAPS_H_
-#define _SYS_CAPS_H_
-
-#ifndef _SYS_TYPES_H_
-#include <sys/types.h>
-#endif
-#ifndef _SYS_MSGPORT_H_
-#include <sys/msgport.h>
-#endif
-#ifndef _SYS_XIO_H_
-#include <sys/xio.h>
-#endif
-
-typedef enum caps_msg_state {
- CAPMS_REQUEST,
- CAPMS_REQUEST_RETRY, /* internal / FUTURE */
- CAPMS_REPLY,
- CAPMS_REPLY_RETRY, /* internal / FUTURE */
- CAPMS_DISPOSE
-} caps_msg_state_t;
-
-typedef struct caps_msgid {
- off_t c_id;
- caps_msg_state_t c_state;
- int c_reserved01;
-} *caps_msgid_t;
-
-typedef enum caps_type {
- CAPT_UNKNOWN, CAPT_CLIENT, CAPT_SERVICE, CAPT_REMOTE, CAPT_FORKED
-} caps_type_t;
-
-typedef int64_t caps_gen_t;
-
-/*
- * Note: upper 16 bits reserved for kernel use
- */
-#define CAPF_UFLAGS 0xFFFF
-#define CAPF_USER 0x0001
-#define CAPF_GROUP 0x0002
-#define CAPF_WORLD 0x0004
-#define CAPF_EXCL 0x0008
-#define CAPF_ANYCLIENT (CAPF_USER|CAPF_GROUP|CAPF_WORLD)
-#define CAPF_WCRED 0x0010 /* waiting for cred */
-#define CAPF_NOFORK 0x0020 /* do not create a dummy entry on fork */
-#define CAPF_WAITSVC 0x0040 /* block if service not available */
-/* FUTURE: CAPF_ASYNC - support async services */
-/* FUTURE: CAPF_NOGROUPS - don't bother filling in the groups[] array */
-/* FUTURE: CAPF_TERM - send termination request to existing service */
-/* FUTURE: CAPF_TAKE - take over existing service's connections */
-/* FUTURE: CAPF_DISPOSE_IMM - need immediate dispose wakeups */
-
-/*
- * Abort codes
- */
-#define CAPS_ABORT_NOTIMPL 0 /* abort not implemented, no action */
-#define CAPS_ABORT_RETURNED 1 /* already returned, no action */
-#define CAPS_ABORT_BEFORESERVER 2 /* caught before the server got it */
-#define CAPS_ABORT_ATSERVER 3 /* server had retrieved message */
-
-#define CAPF_ABORT_HARD 0x0001 /* rip out from under server (3) */
-
-#define CAPS_MAXGROUPS 16
-#define CAPS_MAXNAMELEN 64
-#define CAPS_MAXINPROG 128
-
-struct thread;
-
-typedef struct caps_port {
- struct lwkt_port cp_lport;
- int cp_portid; /* caps port id */
- int cp_upcallid; /* upcall id */
-} *caps_port_t;
-
-typedef struct caps_cred {
- pid_t pid;
- uid_t uid;
- uid_t euid;
- gid_t gid;
- int ngroups;
- int cacheid;
- gid_t groups[CAPS_MAXGROUPS];
-} *caps_cred_t;
-
-#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
-
-struct proc;
-struct caps_kmsg;
-
-TAILQ_HEAD(caps_kmsg_queue, caps_kmsg);
-
-/*
- * caps_kinfo - Holds a client or service registration
- *
- * ci_msgpendq: holds the kernel copy of the message after it has been
- * sent to the local port. The message is matched up against
- * replies and automatically replied if the owner closes its
- * connection.
- */
-typedef struct caps_kinfo {
- struct lwkt_port ci_lport; /* embedded local port */
- struct caps_kinfo *ci_tdnext; /* per-process list */
- struct caps_kinfo *ci_hnext; /* registration hash table */
- struct thread *ci_td; /* owner */
- struct caps_kmsg_queue ci_msgpendq; /* pending reply (just rcvd) */
- struct caps_kmsg_queue ci_msguserq; /* pending reply (user holds) */
- struct caps_kinfo *ci_rcaps; /* connected to remote */
- int ci_cmsgcount; /* client in-progress msgs */
- int ci_id;
- int ci_flags;
- int ci_refs;
- caps_type_t ci_type;
- caps_gen_t ci_gen;
- uid_t ci_uid;
- gid_t ci_gid;
- int ci_namelen;
- char ci_name[4]; /* variable length */
- /* ci_name must be last element */
-} *caps_kinfo_t;
-
-/* note: user flags are held in the low 16 bits */
-#define CAPKF_TDLIST 0x00010000
-#define CAPKF_HLIST 0x00020000
-#define CAPKF_FLUSH 0x00040000
-#define CAPKF_RCAPS 0x00080000
-#define CAPKF_CLOSED 0x00100000
-#define CAPKF_MWAIT 0x00200000
-
-/*
- * Kernel caps message. The kernel keepps track of messagse received,
- * undergoing processing by the service, and returned. User-supplied data
- * is copied on reception rather then transmission.
- */
-typedef struct caps_kmsg {
- TAILQ_ENTRY(caps_kmsg) km_node;
- caps_kinfo_t km_mcaps; /* message sender */
- struct xio km_xio; /* mcaps user data */
- struct caps_cred km_ccr; /* caps cred for msg */
- struct caps_msgid km_msgid;
- int km_flags;
-} *caps_kmsg_t;
-
-#define km_state km_msgid.c_state
-
-#define CAPKMF_ONUSERQ 0x0001
-#define CAPKMF_ONPENDQ 0x0002
-#define CAPKMF_REPLY 0x0004
-#define CAPKMF_CDONE 0x0008
-#define CAPKMF_PEEKED 0x0010
-#define CAPKMF_ABORTED 0x0020
-
-#endif
-
-#ifdef _KERNEL
-
-/*
- * kernel support
- */
-void caps_exit(struct thread *td);
-void caps_fork(struct thread *td1, struct thread *td2);
-
-#else
-
-/*
- * Userland API (libcaps)
- */
-caps_port_t caps_service(const char *, uid_t, gid_t, mode_t, int);
-caps_port_t caps_client(const char *, uid_t, gid_t, int);
-
-/*
- * Syscall API
- */
-int caps_sys_service(const char *, uid_t, gid_t, int, int);
-int caps_sys_client(const char *, uid_t, gid_t, int, int);
-off_t caps_sys_put(int, void *, int);
-int caps_sys_reply(int, void *, int, off_t);
-int caps_sys_get(int, void *, int, caps_msgid_t, caps_cred_t);
-int caps_sys_wait(int, void *, int, caps_msgid_t, caps_cred_t);
-int caps_sys_abort(int, off_t, int);
-int caps_sys_setgen(int, caps_gen_t);
-caps_gen_t caps_sys_getgen(int);
-int caps_sys_close(int);
-
-#endif
-
-#endif
-
#define SYS_varsym_list 452
#define SYS_upc_register 453
#define SYS_upc_control 454
-#define SYS_caps_sys_service 455
-#define SYS_caps_sys_client 456
-#define SYS_caps_sys_close 457
-#define SYS_caps_sys_put 458
-#define SYS_caps_sys_reply 459
-#define SYS_caps_sys_get 460
-#define SYS_caps_sys_wait 461
-#define SYS_caps_sys_abort 462
-#define SYS_caps_sys_getgen 463
-#define SYS_caps_sys_setgen 464
+ /* 455 is obsolete caps_sys_service */
+ /* 456 is obsolete caps_sys_client */
+ /* 457 is obsolete caps_sys_close */
+ /* 458 is obsolete caps_sys_put */
+ /* 459 is obsolete caps_sys_reply */
+ /* 460 is obsolete caps_sys_get */
+ /* 461 is obsolete caps_sys_wait */
+ /* 462 is obsolete caps_sys_abort */
+ /* 463 is obsolete caps_sys_getgen */
+ /* 464 is obsolete caps_sys_setgen */
#define SYS_exec_sys_register 465
#define SYS_exec_sys_unregister 466
#define SYS_sys_checkpoint 467
varsym_list.o \
upc_register.o \
upc_control.o \
- caps_sys_service.o \
- caps_sys_client.o \
- caps_sys_close.o \
- caps_sys_put.o \
- caps_sys_reply.o \
- caps_sys_get.o \
- caps_sys_wait.o \
- caps_sys_abort.o \
- caps_sys_getgen.o \
- caps_sys_setgen.o \
exec_sys_register.o \
exec_sys_unregister.o \
sys_checkpoint.o \
int upcid; char upcid_[PAD_(int)];
void * data; char data_[PAD_(void *)];
};
-struct caps_sys_service_args {
-#ifdef _KERNEL
- struct sysmsg sysmsg;
-#endif
- const char * name; char name_[PAD_(const char *)];
- uid_t uid; char uid_[PAD_(uid_t)];
- gid_t gid; char gid_[PAD_(gid_t)];
- int upcid; char upcid_[PAD_(int)];
- int flags; char flags_[PAD_(int)];
-};
-struct caps_sys_client_args {
-#ifdef _KERNEL
- struct sysmsg sysmsg;
-#endif
- const char * name; char name_[PAD_(const char *)];
- uid_t uid; char uid_[PAD_(uid_t)];
- gid_t gid; char gid_[PAD_(gid_t)];
- int upcid; char upcid_[PAD_(int)];
- int flags; char flags_[PAD_(int)];
-};
-struct caps_sys_close_args {
-#ifdef _KERNEL
- struct sysmsg sysmsg;
-#endif
- int portid; char portid_[PAD_(int)];
-};
-struct caps_sys_put_args {
-#ifdef _KERNEL
- struct sysmsg sysmsg;
-#endif
- int portid; char portid_[PAD_(int)];
- void * msg; char msg_[PAD_(void *)];
- int msgsize; char msgsize_[PAD_(int)];
-};
-struct caps_sys_reply_args {
-#ifdef _KERNEL
- struct sysmsg sysmsg;
-#endif
- int portid; char portid_[PAD_(int)];
- void * msg; char msg_[PAD_(void *)];
- int msgsize; char msgsize_[PAD_(int)];
- off_t msgcid; char msgcid_[PAD_(off_t)];
-};
-struct caps_sys_get_args {
-#ifdef _KERNEL
- struct sysmsg sysmsg;
-#endif
- int portid; char portid_[PAD_(int)];
- void * msg; char msg_[PAD_(void *)];
- int maxsize; char maxsize_[PAD_(int)];
- struct caps_msgid * msgid; char msgid_[PAD_(struct caps_msgid *)];
- struct caps_cred * ccr; char ccr_[PAD_(struct caps_cred *)];
-};
-struct caps_sys_wait_args {
-#ifdef _KERNEL
- struct sysmsg sysmsg;
-#endif
- int portid; char portid_[PAD_(int)];
- void * msg; char msg_[PAD_(void *)];
- int maxsize; char maxsize_[PAD_(int)];
- struct caps_msgid * msgid; char msgid_[PAD_(struct caps_msgid *)];
- struct caps_cred * ccr; char ccr_[PAD_(struct caps_cred *)];
-};
-struct caps_sys_abort_args {
-#ifdef _KERNEL
- struct sysmsg sysmsg;
-#endif
- int portid; char portid_[PAD_(int)];
- off_t msgcid; char msgcid_[PAD_(off_t)];
- int flags; char flags_[PAD_(int)];
-};
-struct caps_sys_getgen_args {
-#ifdef _KERNEL
- struct sysmsg sysmsg;
-#endif
- int portid; char portid_[PAD_(int)];
-};
-struct caps_sys_setgen_args {
-#ifdef _KERNEL
- struct sysmsg sysmsg;
-#endif
- int portid; char portid_[PAD_(int)];
- off_t gen; char gen_[PAD_(off_t)];
-};
struct exec_sys_register_args {
#ifdef _KERNEL
struct sysmsg sysmsg;
int sys_varsym_list (struct varsym_list_args *);
int sys_upc_register (struct upc_register_args *);
int sys_upc_control (struct upc_control_args *);
-int sys_caps_sys_service (struct caps_sys_service_args *);
-int sys_caps_sys_client (struct caps_sys_client_args *);
-int sys_caps_sys_close (struct caps_sys_close_args *);
-int sys_caps_sys_put (struct caps_sys_put_args *);
-int sys_caps_sys_reply (struct caps_sys_reply_args *);
-int sys_caps_sys_get (struct caps_sys_get_args *);
-int sys_caps_sys_wait (struct caps_sys_wait_args *);
-int sys_caps_sys_abort (struct caps_sys_abort_args *);
-int sys_caps_sys_getgen (struct caps_sys_getgen_args *);
-int sys_caps_sys_setgen (struct caps_sys_setgen_args *);
int sys_exec_sys_register (struct exec_sys_register_args *);
int sys_exec_sys_unregister (struct exec_sys_unregister_args *);
int sys_sys_checkpoint (struct sys_checkpoint_args *);
struct varsym_list_args varsym_list;
struct upc_register_args upc_register;
struct upc_control_args upc_control;
- struct caps_sys_service_args caps_sys_service;
- struct caps_sys_client_args caps_sys_client;
- struct caps_sys_close_args caps_sys_close;
- struct caps_sys_put_args caps_sys_put;
- struct caps_sys_reply_args caps_sys_reply;
- struct caps_sys_get_args caps_sys_get;
- struct caps_sys_wait_args caps_sys_wait;
- struct caps_sys_abort_args caps_sys_abort;
- struct caps_sys_getgen_args caps_sys_getgen;
- struct caps_sys_setgen_args caps_sys_setgen;
struct exec_sys_register_args exec_sys_register;
struct exec_sys_unregister_args exec_sys_unregister;
struct sys_checkpoint_args sys_checkpoint;
* threads.
*/
struct md_intr_info;
-struct caps_kinfo;
struct thread {
TAILQ_ENTRY(thread) td_threadq;
char td_comm[MAXCOMLEN+1]; /* typ 16+1 bytes */
struct thread *td_preempted; /* we preempted this thread */
struct ucred *td_ucred; /* synchronized from p_ucred */
- struct caps_kinfo *td_caps; /* list of client and server registrations */
+ void *td_unused04; /* for future fields */
lwkt_tokref_t td_toks_have; /* tokens we own */
lwkt_tokref_t td_toks_stop; /* tokens we want */
struct lwkt_tokref td_toks_array[LWKT_MAXTOKENS];
+++ /dev/null
-# $DragonFly: src/test/caps/Makefile,v 1.8 2004/08/18 09:10:30 dillon Exp $
-#
-
-# thr{1,2,3} disabled (obsolete at the moment)
-TARGETS= /tmp/caps_s /tmp/caps_c /tmp/caps_e /tmp/caps_d
-
-CFLAGS= -O2 -g -DSMP
-CFLAGS+=-I${.CURDIR}/../../lib -I${.CURDIR}/../../lib/libcaps/${MACHINE_ARCH}
-
-all: $(TARGETS)
-
-#/tmp/caps1: caps1.c
-# $(CC) $(CFLAGS) caps1.c -lcaps -o /tmp/caps1
-#
-
-/tmp/thr1: thr1.c
- $(CC) $(CFLAGS) thr1.c -lcaps -o /tmp/thr1
-
-/tmp/thr2: thr2.c
- $(CC) $(CFLAGS) thr2.c -lcaps -o /tmp/thr2
-
-/tmp/thr3: thr3.c
- $(CC) $(CFLAGS) thr3.c -lcaps -o /tmp/thr3
-
-/tmp/caps_s: server.c
- $(CC) $(CFLAGS) server.c -o /tmp/caps_s
-
-/tmp/caps_c: client.c
- $(CC) $(CFLAGS) client.c -o /tmp/caps_c
-
-/tmp/caps_e: encoder.c
- $(CC) $(CFLAGS) encoder.c -lcaps -o /tmp/caps_e
-
-/tmp/caps_d: decoder.c
- $(CC) $(CFLAGS) decoder.c -lcaps -o /tmp/caps_d
-
-clean:
- rm -f $(TARGETS)
+++ /dev/null
-/*
- * CAPS1.C
- *
- * Simple IPC test. /tmp/cs1 -s in one window, /tmp/cs1 -c in another.
- *
- * $DragonFly: src/test/caps/caps1.c,v 1.1 2003/11/24 21:15:59 dillon Exp $
- */
-#include <sys/types.h>
-#include <libcaps/globaldata.h>
-#include <sys/thread.h>
-#include <sys/msgport.h>
-#include <sys/msgport2.h>
-#include <sys/thread2.h>
-#include <sys/caps.h>
-#include <stdio.h>
-#include <signal.h>
-
-int
-main(int ac, char **av)
-{
- caps_port_t port;
- lwkt_msg_t msg;
- struct lwkt_port replyport;
- struct lwkt_msg junkmsg;
- int i;
- int r;
- int quietOpt = 0;
- enum { UNKNOWN, CLIENT, SERVER } mode;
-
- signal(SIGPIPE, SIG_IGN);
-
- for (i = 1; i < ac; ++i) {
- char *ptr = av[i];
- if (*ptr != '-')
- continue;
- ptr += 2;
- switch(ptr[-1]) {
- case 's':
- mode = SERVER;
- break;
- case 'c':
- mode = CLIENT;
- break;
- case 'q':
- quietOpt = (*ptr) ? strtol(ptr, NULL, 0) : 1;
- break;
- }
- }
-
- switch(mode) {
- case SERVER:
- port = caps_service("test", -1, 0666, 0);
- if (quietOpt == 0)
- printf("caps_service port %p\n", port);
- while ((msg = lwkt_waitport(&port->lport, NULL)) != NULL) {
- if (quietOpt == 0) {
- printf("received msg %p %08x\n", msg, msg->ms_flags);
- printf("replyport: %p %p\n",
- msg->ms_reply_port, msg->ms_reply_port->mp_replyport);
- }
- msg->u.ms_result = ~msg->u.ms_result;
- lwkt_replymsg(msg, 23);
- }
- break;
- case CLIENT:
- lwkt_initport(&replyport, curthread);
- port = caps_client("test", -1, 0);
- if (quietOpt == 0)
- printf("caps_client port %p msg %p\n", port, &junkmsg);
- if (port == NULL) {
- printf("failed to connect\n");
- exit(1);
- }
- for (i = 0; ; ++i) {
- lwkt_initmsg(&junkmsg, &replyport, 0);
- junkmsg.u.ms_result = i;
- junkmsg.ms_msgsize = sizeof(junkmsg);
- junkmsg.ms_maxsize = sizeof(junkmsg);
- lwkt_beginmsg(&port->lport, &junkmsg);
- if (caps_client_waitreply(port, &junkmsg) == NULL) {
- printf("client failed\n");
- break;
- }
- if (quietOpt == 0) {
- printf("reply: error=%d/23 res=%d/%d\n",
- junkmsg.ms_error, ~junkmsg.u.ms_result, i);
- } else if (quietOpt == 1 && (i & 65535) == 0) {
- printf("reply: error=%d/23 res=%d/%d\n",
- junkmsg.ms_error, ~junkmsg.u.ms_result, i);
- }
- }
- break;
- }
- printf("exit\n");
- return(0);
-}
-
+++ /dev/null
-/*
- * $DragonFly: src/test/caps/client.c,v 1.3 2004/03/31 20:27:34 dillon Exp $
- */
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/caps.h>
-#include <sys/errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-int
-main(int ac, char **av)
-{
- int cid;
- int n;
- int count = 0;
- long long xcount = 0;
- int lostit = 0;
- int didfork = 0;
- int which = 0;
- char buf[256];
- struct caps_msgid msgid;
- off_t msgcid;
- caps_gen_t gen = 0;
- caps_gen_t ngen;
-
- cid = caps_sys_client("test", getuid(), getgid(), 0, CAPF_ANYCLIENT);
- for (;;) {
- errno = 0;
- if (cid >= 0) {
- msgcid = caps_sys_put(cid, "xyz", 3);
- ngen = caps_sys_getgen(cid);
- }
- if (cid < 0 || (msgcid < 0 && errno == ENOTCONN)) {
- if (lostit == 0)
- printf("%d client forked or lost connection, reconnecting\n", which);
- lostit = 1;
- caps_sys_close(cid);
- cid = caps_sys_client("test", getuid(), getgid(), 0,
- CAPF_ANYCLIENT | CAPF_WAITSVC);
- continue;
- }
- if (lostit) {
- printf("%d client resume on reconnect after lost connection\n", which);
- lostit = 0;
- }
- if (ngen != gen) {
- printf("%d client: note generation change %lld\n", which, ngen);
- gen = ngen;
- }
-#ifdef DEBUG
- printf("msgcid = %016llx %d\n", msgcid, errno);
-#endif
- n = caps_sys_wait(cid, buf, sizeof(buf), &msgid, NULL);
-#ifdef DEBUG
- printf("n = %d msgid=%016llx state=%d errno=%d\n", n, msgid.c_id, msgid.c_state, errno);
- if (n > 0)
- printf("REPLY: %*.*s\n", n, n, buf);
-#endif
- ++count;
- ++xcount;
- if ((count & 65535) == 0)
- printf("%d %lld\n", which, xcount);
- if (count == 100000000)
- count = 0;
- if (count == 1000 && didfork == 0 && which < 10) {
- if (fork() == 0) {
- usleep(100000);
- ++which;
- } else {
- printf("forked pid %d client #%d\n", (int)getpid(), which + 1);
- didfork = 1;
- }
- }
- }
- return(0);
-}
-
+++ /dev/null
-/*
- * DECODER.C
- *
- * Decode CAPS encoded buffers, one per line, into a struct passwd and
- * report the results.
- *
- * $DragonFly: src/test/caps/decoder.c,v 1.1 2004/03/07 23:36:45 dillon Exp $
- */
-#include <sys/types.h>
-#include <libcaps/caps_struct.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-int
-main(int ac, char **av)
-{
- int i;
- int n;
- int error;
- int len;
- char buf[1024];
- struct passwd pw;
-
- while (fgets(buf, sizeof(buf), stdin) != NULL) {
- len = strlen(buf);
- bzero(&pw, sizeof(pw));
- n = caps_decode(buf, len, &pw, &caps_passwd_struct, &error);
- printf("decode %d bytes error %d\n", n, error);
- if (error) {
- if (n > len)
- n = len;
- if (n && buf[n] == '\n') /* don't highlight a 'newline' */
- --n;
- printf("%*.*s", n, n, buf);
- printf("\033[7m%c\033[m", buf[n]);
- n = len - n - 1;
- if (n > 0)
- printf("%*.*s", n, n, buf + len - n);
- } else {
- printf("{\n");
- printf(" pw_name = \"%s\"\n", pw.pw_name);
- printf(" pw_passwd = \"%s\"\n", pw.pw_passwd);
- printf(" pw_uid = %d\n", pw.pw_uid);
- printf(" pw_gid = %d\n", pw.pw_gid);
- printf(" pw_change = %08llx\n", (long long)pw.pw_change);
- printf(" pw_class = \"%s\"\n", pw.pw_class);
- printf(" pw_gecos = \"%s\"\n", pw.pw_gecos);
- printf(" pw_dir = \"%s\"\n", pw.pw_dir);
- printf(" pw_shell = \"%s\"\n", pw.pw_shell);
- printf(" pw_expire = %08llx\n", (long long)pw.pw_expire);
- printf("}\n");
- }
- caps_struct_free_pointers(&pw, &caps_passwd_struct);
- }
- return(0);
-}
-
+++ /dev/null
-/*
- * ENCODER.C
- *
- * CAPS-Encode the passwd structure for the specified usernames, generate
- * to stdout.
- *
- * $DragonFly: src/test/caps/encoder.c,v 1.1 2004/03/07 23:36:45 dillon Exp $
- */
-#include <sys/types.h>
-#include <libcaps/caps_struct.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-int
-main(int ac, char **av)
-{
- int i;
- int n;
- char buf[1024];
-
- for (i = 1; i < ac; ++i) {
- struct passwd *pw;
-
- if ((pw = getpwnam(av[i])) == NULL) {
- printf("%s: lookup failed\n");
- continue;
- }
- n = caps_encode(buf, sizeof(buf), pw, &caps_passwd_struct);
- if (n > sizeof(buf)) {
- printf("buffer overflow during encoding\n");
- } else {
- buf[n] = 0;
- printf("%s\n", buf);
- }
- }
- return(0);
-}
-
+++ /dev/null
-/*
- * $DragonFly: src/test/caps/server.c,v 1.5 2004/08/24 13:45:54 drhodus Exp $
- */
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/caps.h>
-#include <sys/errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-int
-main(int ac, char **av)
-{
- int cid;
- int n;
- int count;
- char buf[256];
- struct caps_msgid msgid;
-
- count = 0;
-
- cid = caps_sys_service("test", getuid(), getgid(), 0, CAPF_ANYCLIENT);
- if (cid == -1) {
- perror("caps_sys_service");
- exit(1);
- }
- printf("cid = %d\n", cid);
- if (cid < 0)
- return(0);
- bzero(&msgid, sizeof(msgid));
- for (;;) {
- n = caps_sys_wait(cid, buf, sizeof(buf), &msgid, NULL);
-#ifdef DEBUG
- printf("n = %d msgid=%016llx state=%d errno=%d\n", n, msgid.c_id, msgid.c_state, errno);
- if (n > 0)
- printf("BUFFER: %*.*s\n", n, n, buf);
-#endif
- if (msgid.c_state != CAPMS_DISPOSE)
- n = caps_sys_reply(cid, "good", 4, msgid.c_id);
-#ifdef DEBUG
- printf("reply: n = %d\n", n);
-#endif
- if (++count % 1000000 == 0)
- caps_sys_setgen(cid, count);
- }
- return(0);
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/test/caps/thr1.c,v 1.1 2003/12/07 04:26:41 dillon Exp $
- */
-#include <stdio.h>
-#include <libcaps/defs.h>
-
-extern int mp_lock;
-
-static void thread1(void *data);
-static void thread2(void *data);
-
-int
-main(int ac, char **av)
-{
- thread_t td;
- thread_t td1;
- thread_t td2;
-
- uthread_init();
- td = curthread;
- printf("mainthread %p crit_count %d nest %d mp_lock %d\n",
- td, td->td_pri / TDPRI_CRIT, td->td_mpcount, mp_lock
- );
- lwkt_create(thread1, NULL, &td1, NULL, 0, -1, "thread1");
- lwkt_create(thread2, NULL, &td2, NULL, 0, -1, "thread2");
- printf("thread #1 %p #2 %p\n", td1, td2);
- printf("switching away from main (should come back before exit)\n");
- lwkt_switch();
- printf("Switched back to main, main Exiting\n");
- exit(1);
-}
-
-void
-thread1(void *data)
-{
- printf("thread1 running\n");
- printf("thread1 exiting\n");
-}
-
-void
-thread2(void *data)
-{
- printf("thread2 running\n");
- printf("thread2 exiting\n");
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/test/caps/thr2.c,v 1.1 2003/12/07 04:26:41 dillon Exp $
- */
-#include <stdio.h>
-#include <libcaps/defs.h>
-
-extern int mp_lock;
-
-static void thread1(void *data);
-static void thread2(void *data);
-
-int
-main(int ac, char **av)
-{
- thread_t td;
- thread_t td1;
- thread_t td2;
-
- uthread_init();
- lwkt_create(thread1, NULL, &td1, NULL, 0, -1, "thread1");
- lwkt_create(thread2, NULL, &td2, NULL, 0, -1, "thread2");
- lwkt_switch();
- printf("Main Exiting\n");
- exit(1);
-}
-
-void
-thread1(void *data)
-{
- int i;
- for (i = 0; i < 1000000; ++i)
- lwkt_switch();
- printf("done1\n");
-}
-
-void
-thread2(void *data)
-{
- int i;
- for (i = 0; i < 1000000; ++i)
- lwkt_switch();
- printf("done2\n");
- exit(0);
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $DragonFly: src/test/caps/thr3.c,v 1.1 2003/12/07 04:26:41 dillon Exp $
- */
-#include <stdio.h>
-#include <libcaps/defs.h>
-
-extern int mp_lock;
-
-static void thread1(void *data);
-static void thread2(void *data);
-
-int
-main(int ac, char **av)
-{
- thread_t td;
- thread_t td1;
- thread_t td2;
- int tcpu;
-
- uthread_init();
- tcpu = caps_fork_vcpu();
- printf("caps_fork_vcpu %d\n", tcpu);
- lwkt_create(thread1, NULL, &td1, NULL, 0, -1, "thread1");
- lwkt_create(thread2, NULL, &td2, NULL, 0, tcpu, "thread2");
- lwkt_deschedule_self();
- lwkt_switch();
- printf("Main thread resumed after all children exiting.\n");
- printf("Running test a second time to see if UPC_CONTROL_WAIT works\n");
- lwkt_create(thread1, NULL, &td1, NULL, 0, -1, "thread1");
- lwkt_create(thread2, NULL, &td2, NULL, 0, tcpu, "thread2");
- lwkt_deschedule_self();
- lwkt_switch();
- printf("Main thread resumed after second test, exiting\n");
- exit(0);
-}
-
-void
-thread1(void *data)
-{
- int i;
-
- printf("start1 pri %d mp %d\n", curthread->td_pri, curthread->td_mpcount);
- rel_mplock();
- for (i = 0; i < 100000000; ++i)
- lwkt_switch();
- printf("done1 %d\n", (int)getpid());
-}
-
-void
-thread2(void *data)
-{
- int i;
-
- printf("start2 pri %d mp %d\n", curthread->td_pri, curthread->td_mpcount);
- for (i = 0; i < 10000000; ++i)
- lwkt_switch();
- printf("done2 %d\n", (int)getpid());
-}
-
usage(char **argv)
{
fprintf(stderr, _("Usage: %s [-o rootdir] [-r rendezvous] "
- "[-t caps|npipe|tcp]\n"), argv[0]);
+ "[-t npipe|tcp]\n"), argv[0]);
exit(1);
}
usage(char **argv)
{
fprintf(stderr, _("Usage: %s "
- "[-b backdrop] [-r rendezvous] [-t caps|npipe|tcp]\n"),
+ "[-b backdrop] [-r rendezvous] [-t npipe|tcp]\n"),
argv[0]);
exit(1);
}
-# $DragonFly: src/usr.sbin/installer/libdfui/Makefile,v 1.3 2008/08/29 22:51:56 swildner Exp $
-
LIB= dfui
-SRCS= conn_caps.c conn_npipe.c conn_tcp.c connection.c decode.c \
+SRCS= conn_npipe.c conn_tcp.c connection.c decode.c \
dump.c encode.c form.c lang.c system.c
CFLAGS+=-I${.CURDIR}/..
abstract user interaction interface with which an application program
(termed the backend) can communicate with a user via a concreate user
interface terminal program (termed the frontend.) The frontend and the
-backend can communicate over several kinds of transport layers (TCP,
-CAPS, and Named Pipes.) The protocol is abstract enough so that the
+backend can communicate over several kinds of transport layers (TCP
+and Named Pipes.) The protocol is abstract enough so that the
frontend can occupy nearly any medium (GUI, addressable text console,
teletype, voice synthesis/recognition, etc) with little to no `fudging'
of the semantics (i.e. the structure and nature of the information that
+++ /dev/null
-/*
- * Copyright (c)2004 Cat's Eye Technologies. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * Neither the name of Cat's Eye Technologies nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * conn_caps.c
- * $Id: conn_caps.c,v 1.12 2005/02/06 19:53:19 cpressey Exp $
- * This code was derived in part from:
- * $_DragonFly: src/test/caps/client.c,v 1.3 2004/03/31 20:27:34 dillon Exp $
- * $_DragonFly: src/test/caps/server.c,v 1.4 2004/03/06 22:15:00 dillon Exp $
- * and is therefore also subject to the license conditions on those files.
- */
-
-#include "system.h"
-#ifdef HAS_CAPS
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/caps.h>
-#include <sys/errno.h>
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <libaura/mem.h>
-#include <libaura/buffer.h>
-
-#define NEEDS_DFUI_STRUCTURE_DEFINITIONS
-#include "dfui.h"
-#undef NEEDS_DFUI_STRUCTURE_DEFINITIONS
-#include "encoding.h"
-#include "dump.h"
-#include "conn_caps.h"
-
-/***** BACKEND ******/
-
-/** High Level **/
-
-/*
- * Connect to the frontend.
- */
-dfui_err_t
-dfui_caps_be_start(struct dfui_connection *c)
-{
- T_CAPS(c)->cid = caps_sys_service(c->rendezvous, getuid(), getgid(),
- 0, CAPF_ANYCLIENT);
- return(T_CAPS(c)->cid < 0 ? DFUI_FAILURE : DFUI_SUCCESS);
-}
-
-/*
- * Tell the frontend that we're done and disconnect from it.
- */
-dfui_err_t
-dfui_caps_be_stop(struct dfui_connection *c)
-{
- if (dfui_caps_be_ll_exchange(c, DFUI_BE_MSG_STOP, "")) {
- caps_sys_close(T_CAPS(c)->cid);
- return(DFUI_SUCCESS);
- } else
- return(DFUI_FAILURE);
-}
-
-/** Low Level **/
-
-/*
- * Exchange a message with the frontend. This involves two receive()/reply()
- * cycles: one to provide our message, one to get a reply from the frontend.
- *
- * Note that this does not immediately send the message to the frontend -
- * it can't, because we're a service and it's a client. What it does is
- * keep the message handy and wait for a frontend request to come in. It
- * then replies to that request with our message.
- *
- * The protocol looks something like the following, using the PRESENT and
- * SUBMIT exchange as an example:
- *
- * frontend (client) | backend (service)
- * ------------------+------------------
- *
- * [stage 1]
- * READY --> ll_receive()
- * <-- PRESENT(form) ll_reply()
- *
- * [stage 2]
- * SUBMIT(form) --> ll_receive()
- * <-- READY ll_reply()
- *
- * Each of those exchanges is a pair of calls, on our end, to
- * dfui_caps_be_ll_receive() and dfui_caps_be_ll_reply().
- *
- * The set of messages that the client can pass us is determined by
- * the conversation state:
- *
- * o In stage 1, only READY and ABORT are meaningful.
- * o After a PRESENT, the messages SUBMIT and ABORT are meaningul
- * in stage 2.
- * o During a PROG_*, the messages CONTINUE, CANCEL, and ABORT
- * are meaningful in stage 2.
- *
- * If the frontend sends us with READY in stage 2, we assume it has
- * fallen out of sync, so we send the same initial reply again, going
- * back to stage 1 as it were.
- *
- * After this call, the message is available in c->ebuf.
- */
-dfui_err_t
-dfui_caps_be_ll_exchange(struct dfui_connection *c, char msgtype, const char *msg)
-{
- char *fmsg;
-
- /*
- * Construct our message to send.
- */
-
- fmsg = aura_malloc(strlen(msg) + 2, "exchange message");
- fmsg[0] = msgtype;
- strcpy(fmsg + 1, msg);
-
- /*
- * Get the frontend's message.
- */
-
- dfui_caps_be_ll_receive(c);
-
- /*
- * Frontend message should have been either READY or ABORT.
- * If ABORT, we get out of here pronto.
- */
-
- if (aura_buffer_buf(c->ebuf)[0] == DFUI_FE_MSG_ABORT) {
- aura_free(fmsg, "exchange message");
- return(DFUI_FAILURE);
- }
-
- /* XXX if (!READY) ??? */
-
- do {
- dfui_caps_be_ll_reply(c, fmsg);
-
- /*
- * Here, the frontend has picked up our request and is
- * processing it. We have to wait for the response.
- */
-
- dfui_caps_be_ll_receive(c);
-
- /*
- * Did we get READY from this?
- * If so, loop!
- */
-
- } while (aura_buffer_buf(c->ebuf)[0] == DFUI_FE_MSG_READY);
-
- fmsg[0] = DFUI_BE_MSG_READY;
- fmsg[1] = '\0';
- dfui_caps_be_ll_reply(c, fmsg);
-
- aura_free(fmsg, "exchange message");
- return(DFUI_SUCCESS);
-}
-
-/*
- * Receive a message from the frontend.
- * This call is synchronous.
- * After this call, the message is available in c->ebuf.
- */
-dfui_err_t
-dfui_caps_be_ll_receive(struct dfui_connection *c)
-{
- /*
- * XXX Eventually, the message should be received directly
- * into c->ebuf. For now, receive into T_CAPS(c)->buf,
- * and copy into c->ebuf.
- */
- do {
- T_CAPS(c)->wresult = caps_sys_wait(T_CAPS(c)->cid, T_CAPS(c)->buf,
- T_CAPS(c)->size, &T_CAPS(c)->msgid, NULL);
- if (T_CAPS(c)->wresult < 0)
- return(DFUI_FAILURE);
- /*
- * This might have been a CAPMS_DISPOSE message from the kernel.
- * If so, just accept it and try, try again.
- */
- dfui_debug("DISPOSE?<<%s>>\n",
- T_CAPS(c)->msgid.c_state == CAPMS_DISPOSE ? "Yes" : "No");
- } while (T_CAPS(c)->msgid.c_state == CAPMS_DISPOSE);
-
- aura_buffer_set(c->ebuf, T_CAPS(c)->buf, T_CAPS(c)->wresult);
- dfui_debug("RECV<<%s>>\n", aura_buffer_buf(c->ebuf));
- return(DFUI_SUCCESS);
-}
-
-/*
- * Send a NUL-terminated reply to the frontend.
- */
-dfui_err_t
-dfui_caps_be_ll_reply(struct dfui_connection *c, const char *fmsg)
-{
- dfui_debug("SEND<<%s>>\n", fmsg);
- T_CAPS(c)->wresult = caps_sys_reply(T_CAPS(c)->cid,
- __DECONST(char *, fmsg), strlen(fmsg), T_CAPS(c)->msgid.c_id);
-
- /*
- * We may get a CAPMS_DISPOSE message after this, if the client
- * process is still around. If so, it'll be handled in the next
- * call to dfui_caps_be_ll_receive().
- */
-
- return(DFUI_SUCCESS);
-}
-
-/******** FRONTEND ********/
-
-/** High Level **/
-
-dfui_err_t
-dfui_caps_fe_connect(struct dfui_connection *c)
-{
- T_CAPS(c)->cid = caps_sys_client(c->rendezvous, getuid(), getgid(), 0,
- CAPF_ANYCLIENT | CAPF_WAITSVC);
- return(T_CAPS(c)->cid > 0 ? DFUI_SUCCESS : DFUI_FAILURE);
-}
-
-dfui_err_t
-dfui_caps_fe_disconnect(struct dfui_connection *c)
-{
- caps_sys_close(T_CAPS(c)->cid);
- return(DFUI_SUCCESS);
-}
-
-/** Low Level **/
-
-/*
- * Ask for, and subsequently receieve, a message from the backend.
- * msgtype should be one of the DFUI_FE_MSG_* constants.
- * This call is synchronous.
- * After this call, the encoded message is available in c->ebuf.
- */
-dfui_err_t
-dfui_caps_fe_ll_request(struct dfui_connection *c, char msgtype, const char *msg)
-{
- char *fmsg;
- off_t msgcid = 0;
-
- /*
- * First, assert that the connection is open.
- */
-
- if (c == NULL || T_CAPS(c)->cid < 0)
- return(DFUI_FAILURE);
-
- /*
- * Construct a message.
- */
-
- fmsg = aura_malloc(strlen(msg) + 2, "exchange message");
- fmsg[0] = msgtype;
- strcpy(fmsg + 1, msg);
- dfui_debug("SEND<<%s>>\n", fmsg);
-
- /*
- * Send a NUL-terminated message to the backend.
- */
-
- errno = 0;
- msgcid = caps_sys_put(T_CAPS(c)->cid, fmsg, strlen(fmsg));
- if (msgcid < 0 && errno == ENOTCONN)
- return(DFUI_FAILURE);
-
- /*
- * Receive a reply from the backend.
- * If our message was a READY, this should be a message like PRESENT.
- * Otherwise it should simply be a READY.
- */
-
- dfui_debug("WAITING<<>>\n");
-
- T_CAPS(c)->wresult = caps_sys_wait(T_CAPS(c)->cid, T_CAPS(c)->buf,
- T_CAPS(c)->size, &T_CAPS(c)->msgid, NULL);
- if (T_CAPS(c)->wresult < 0)
- return(DFUI_FAILURE);
-
- aura_buffer_set(c->ebuf, T_CAPS(c)->buf, T_CAPS(c)->wresult);
- dfui_debug("RECV<<%s>>\n", aura_buffer_buf(c->ebuf));
-
- aura_free(fmsg, "exchange message");
-
- return(DFUI_SUCCESS);
-}
-
-#endif /* HAS_CAPS */
+++ /dev/null
-/*
- * Copyright (c)2004 Cat's Eye Technologies. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * Neither the name of Cat's Eye Technologies nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * conn_caps.h
- * $Id: conn_caps.h,v 1.7 2005/02/06 19:53:19 cpressey Exp $
- */
-
-#ifndef __CONN_CAPS_H_
-#define __CONN_CAPS_H_
-
-#include "system.h"
-#ifdef HAS_CAPS
-
-#include <sys/caps.h>
-
-#include "dfui.h"
-
-struct dfui_conn_caps {
- int cid; /* the caps id for the connection */
- int wresult; /* result of last caps_sys_wait/get */
- struct caps_msgid msgid; /* msgid of the last msg recvd */
- char *buf; /* XXX last message recvd */
- size_t size; /* XXX size of msg recv buffer */
-};
-
-#define T_CAPS(c) ((struct dfui_conn_caps *)c->t_data)
-
-dfui_err_t dfui_caps_be_start(struct dfui_connection *);
-dfui_err_t dfui_caps_be_stop(struct dfui_connection *);
-
-dfui_err_t dfui_caps_be_ll_exchange(struct dfui_connection *,
- char, const char *);
-dfui_err_t dfui_caps_be_ll_receive(struct dfui_connection *);
-dfui_err_t dfui_caps_be_ll_reply(struct dfui_connection *, const char *);
-
-dfui_err_t dfui_caps_fe_connect(struct dfui_connection *);
-dfui_err_t dfui_caps_fe_disconnect(struct dfui_connection *);
-
-dfui_err_t dfui_caps_fe_ll_request(struct dfui_connection *, char, const char *);
-
-#endif /* HAS_CAPS */
-#endif /* !__CONN_CAPS_H_ */
#include "encoding.h"
#include "dump.h"
-#include "conn_caps.h"
#include "conn_npipe.h"
#include "conn_tcp.h"
struct dfui_connection *c = NULL;
if (
-#ifdef HAS_CAPS
- transport == DFUI_TRANSPORT_CAPS ||
-#endif
#ifdef HAS_NPIPE
transport == DFUI_TRANSPORT_NPIPE ||
#endif
c->t_data = NULL;
switch (transport) {
-#ifdef HAS_CAPS
- case DFUI_TRANSPORT_CAPS:
- AURA_MALLOC(c->t_data, dfui_conn_caps);
- T_CAPS(c)->cid = 0;
- bzero(&T_CAPS(c)->msgid, sizeof(T_CAPS(c)->msgid));
-
- /*
- * XXX Ideally, this value should grow as needed.
- * However, CAPS currently has a size limit of
- * 128K internally.
- */
- T_CAPS(c)->size = 128 * 1024;
- if ((T_CAPS(c)->buf = aura_malloc(T_CAPS(c)->size, "CAPS buffer")) == NULL) {
- AURA_FREE(T_CAPS(c), dfui_conn_caps);
- aura_free(c->rendezvous, "rendezvous string");
- AURA_FREE(c, dfui_connection);
- return(NULL);
- }
-
- /*
- * Set up dispatch functions.
- */
- c->be_start = dfui_caps_be_start;
- c->be_stop = dfui_caps_be_stop;
- c->be_ll_exchange = dfui_caps_be_ll_exchange;
-
- c->fe_connect = dfui_caps_fe_connect;
- c->fe_disconnect = dfui_caps_fe_disconnect;
- c->fe_ll_request = dfui_caps_fe_ll_request;
- break;
-#endif /* HAS_CAPS */
-
#ifdef HAS_NPIPE
case DFUI_TRANSPORT_NPIPE:
AURA_MALLOC(c->t_data, dfui_conn_npipe);
return;
switch (c->transport) {
-#ifdef HAS_CAPS
- case DFUI_TRANSPORT_CAPS:
- if (T_CAPS(c) != NULL) {
- if (T_CAPS(c)->buf != NULL)
- aura_free(T_CAPS(c)->buf, "CAPS buffer");
- AURA_FREE(T_CAPS(c), dfui_conn_caps);
- }
- break;
-#endif
#ifdef HAS_NPIPE
case DFUI_TRANSPORT_NPIPE:
if (T_NPIPE(c) != NULL) {
* Transports.
*/
-#define DFUI_TRANSPORT_CAPS 1
-#define DFUI_TRANSPORT_NPIPE 2
-#define DFUI_TRANSPORT_TCP 3
+#define DFUI_TRANSPORT_NPIPE 1
+#define DFUI_TRANSPORT_TCP 2
/*
* Message types.
/* Connections */
struct dfui_connection {
- int transport; /* transport layer: CAPS, NPIPE, or TCP */
+ int transport; /* transport layer: NPIPE or TCP */
char *rendezvous; /* rendezvous point */
struct aura_buffer *ebuf; /* last message recvd */
int is_connected; /* was a connection actually established? */
}
int
-has_caps(void)
-{
-#ifdef HAS_CAPS
- return 1;
-#endif
- return 0;
-}
-
-int
has_npipe(void)
{
#ifdef HAS_NPIPE
int
get_transport(const char *transport_name)
{
- if (strcmp(transport_name, "caps") == 0) {
- if (has_caps())
- return DFUI_TRANSPORT_CAPS;
- return(0);
- } else if (strcmp(transport_name, "npipe") == 0) {
+ if (strcmp(transport_name, "npipe") == 0) {
if (has_npipe())
return DFUI_TRANSPORT_NPIPE;
return(0);
#define HAS_TCP
#define HAS_NPIPE
-#define HAS_CAPS
#define OPERATING_SYSTEM_NAME "DragonFly BSD"
#define OPERATING_SYSTEM_URL "http://www.dragonflybsd.org"
char *ostype(void);
int has_tcp(void);
int has_npipe(void);
-int has_caps(void);
int get_transport(const char *);
int user_get_transport(const char *);