Module Name:    src
Committed By:   bouyer
Date:           Sat Feb  4 22:26:16 UTC 2017

Modified Files:
        src/tests/net/can [bouyer-socketcan]: Makefile t_can.c
Added Files:
        src/tests/net/can [bouyer-socketcan]: h_canutils.c h_canutils.h

Log Message:
Factor out reading from a can socket, and move to a helper file.


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/tests/net/can/Makefile
cvs rdiff -u -r0 -r1.1.2.1 src/tests/net/can/h_canutils.c \
    src/tests/net/can/h_canutils.h
cvs rdiff -u -r1.1.2.2 -r1.1.2.3 src/tests/net/can/t_can.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/tests/net/can/Makefile
diff -u src/tests/net/can/Makefile:1.1.2.1 src/tests/net/can/Makefile:1.1.2.2
--- src/tests/net/can/Makefile:1.1.2.1	Sun Jan 15 20:29:01 2017
+++ src/tests/net/can/Makefile	Sat Feb  4 22:26:16 2017
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.1.2.1 2017/01/15 20:29:01 bouyer Exp $
+# $NetBSD: Makefile,v 1.1.2.2 2017/02/04 22:26:16 bouyer Exp $
 #
 
 .include <bsd.own.mk>
@@ -6,6 +6,7 @@
 TESTSDIR=	${TESTSBASE}/net/can
 
 TESTS_C=	t_can
+SRCS.t_can=	t_can.c h_canutils.c
 
 # XXX we don't use INET here, but we need rumpnet_netinet anyway:
 # common code in if.c is compiled with -DINET and will dereference ip_pktq,

Index: src/tests/net/can/t_can.c
diff -u src/tests/net/can/t_can.c:1.1.2.2 src/tests/net/can/t_can.c:1.1.2.3
--- src/tests/net/can/t_can.c:1.1.2.2	Mon Jan 16 18:04:27 2017
+++ src/tests/net/can/t_can.c	Sat Feb  4 22:26:16 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_can.c,v 1.1.2.2 2017/01/16 18:04:27 bouyer Exp $	*/
+/*	$NetBSD: t_can.c,v 1.1.2.3 2017/02/04 22:26:16 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2017 The NetBSD Foundation, Inc.
@@ -32,12 +32,11 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: t_can.c,v 1.1.2.2 2017/01/16 18:04:27 bouyer Exp $");
+__RCSID("$NetBSD: t_can.c,v 1.1.2.3 2017/02/04 22:26:16 bouyer Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
 #include <sys/resource.h>
-#include <sys/sysctl.h>
 #include <sys/wait.h>
 #include <sys/sockio.h>
 #include <sys/param.h>
@@ -49,7 +48,6 @@ __RCSID("$NetBSD: t_can.c,v 1.1.2.2 2017
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <signal.h>
 
 #include <net/if.h>
 #include <netcan/can.h>
@@ -58,37 +56,7 @@ __RCSID("$NetBSD: t_can.c,v 1.1.2.2 2017
 #include <rump/rump_syscalls.h>
 
 #include "h_macros.h"
-
-static void
-cancfg_rump_createif(const char *ifname)
-{
-	int s, rv;
-	struct ifreq ifr;
-
-	s = -1;
-	if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
-		atf_tc_fail_errno("if config socket");
-	}
-
-	memset(&ifr, 0, sizeof(ifr));
-	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
-
-	if ((rv = rump_sys_ioctl(s, SIOCIFCREATE, &ifr)) < 0) {
-		atf_tc_fail_errno("if config create");
-	}
-
-	memset(&ifr, 0, sizeof(ifr));
-	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
-
-	if ((rv = rump_sys_ioctl(s, SIOCGIFFLAGS, &ifr)) < 0) {
-		atf_tc_fail_errno("if config get flags");
-	}
-
-	ifr.ifr_flags |= IFF_UP;
-	if ((rv = rump_sys_ioctl(s, SIOCSIFFLAGS, &ifr)) < 0) {
-		atf_tc_fail_errno("if config set flags");
-	}
-}
+#include "h_canutils.h"
 
 ATF_TC(canlocreate);
 ATF_TC_HEAD(canlocreate, tc)
@@ -197,38 +165,12 @@ ATF_TC_BODY(cannoown, tc)
 	}
 
 	/* now try to read */
-
-	memset(&cf_receive, 0, sizeof(cf_receive));
-	FD_ZERO(&rfds);
-	FD_SET(s, &rfds);
-	/* we should receive no message; wait for 2 seconds */
-	tmout.tv_sec = 2;
-	tmout.tv_usec = 0;
-	rv = rump_sys_select(s + 1, &rfds, NULL, NULL, &tmout);
-	switch(rv) {
-	case -1:
-		atf_tc_fail_errno("select");
-		break;
-	case 0:
-		/* timeout: expected case */
-		return;
-	default: break;
+	if (can_recvfrom(s, &cf_receive, &rv, &sa) < 0) {
+		if (errno ==  EWOULDBLOCK)
+			return; /* expected timeout */
+		atf_tc_fail_errno("can_recvfrom");
 	}
-	salen = sizeof(sa);
-	ATF_CHECK_MSG(FD_ISSET(s, &rfds), "select returns but s not in set");
-	if (( rv = rump_sys_recvfrom(s, &cf_receive, sizeof(cf_receive),
-	    0, (struct sockaddr *)&sa, &salen)) < 0) {
-		atf_tc_fail_errno("recvfrom");
-	}
-
-	ATF_CHECK_MSG(rv > 0, "short read on socket");
 
-	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive, sizeof(cf_send)) == 0,
-	    "recvfrom packet is not what we sent");
-	ATF_CHECK_MSG(sa.can_family == AF_CAN,
-	    "recvfrom provided wrong %d family", sa.can_family);
-	ATF_CHECK_MSG(salen == sizeof(sa),
-	    "recvfrom provided wrong size %d (!= %d)", salen, sizeof(sa));
 	ATF_CHECK_MSG(sa.can_ifindex == ifr.ifr_ifindex,
 	   "recvfrom provided wrong ifindex %d (!= %d)",
 	    sa.can_ifindex, ifr.ifr_ifindex);
@@ -320,13 +262,10 @@ ATF_TC_BODY(canwritelo, tc)
 		atf_tc_fail_errno("write");
 	}
 
-	memset(&cf_receive, 0, sizeof(cf_receive));
-	if (( rv = rump_sys_read(s, &cf_receive, sizeof(cf_receive))) < 0) {
-		atf_tc_fail_errno("read");
+	if (can_read(s, &cf_receive, &rv) < 0) {
+		atf_tc_fail_errno("can_read");
 	}
 
-	ATF_CHECK_MSG(rv > 0, "short read on socket");
-
 	memset(&cf_send, 0, sizeof(cf_send));
 	cf_send.can_id = 1;
 	cf_send.can_dlc = 1;
@@ -433,13 +372,10 @@ ATF_TC_BODY(cansendtolo, tc)
 		atf_tc_fail_errno("sendto");
 	}
 
-	memset(&cf_receive, 0, sizeof(cf_receive));
-	if (( rv = rump_sys_read(s, &cf_receive, sizeof(cf_receive))) < 0) {
+	if (can_read(s, &cf_receive, &rv) < 0) {
 		atf_tc_fail_errno("read");
 	}
 
-	ATF_CHECK_MSG(rv > 0, "short read on socket");
-
 	memset(&cf_send, 0, sizeof(cf_send));
 	cf_send.can_id = 1;
 	cf_send.can_dlc = 1;
@@ -504,13 +440,10 @@ ATF_TC_BODY(cansendtowrite, tc)
 		atf_tc_fail_errno("sendto");
 	}
 
-	memset(&cf_receive, 0, sizeof(cf_receive));
-	if (( rv = rump_sys_read(s, &cf_receive, sizeof(cf_receive))) < 0) {
+	if (can_read(s, &cf_receive, &rv) < 0) {
 		atf_tc_fail_errno("read");
 	}
 
-	ATF_CHECK_MSG(rv > 0, "short read on socket");
-
 	memset(&cf_send, 0, sizeof(cf_send));
 	cf_send.can_id = 1;
 	cf_send.can_dlc = 1;
@@ -595,24 +528,18 @@ ATF_TC_BODY(canreadlocal, tc)
 		atf_tc_fail_errno("write");
 	}
 
-	memset(&cf_receive2, 0, sizeof(cf_receive2));
-	if (( rv2 = rump_sys_read(s2, &cf_receive2, sizeof(cf_receive2))) < 0) {
-		atf_tc_fail_errno("read");
+	if (can_read(s2, &cf_receive2, &rv2) < 0) {
+		atf_tc_fail_errno("can_read");
 	}
 
-	ATF_CHECK_MSG(rv2 > 0, "short read on socket");
-
 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2, sizeof(cf_send)) == 0,
 	    "received (2) packet is not what we sent");
 
 	/* now check first socket */
-	memset(&cf_receive1, 0, sizeof(cf_receive1));
-	if (( rv1 = rump_sys_read(s1, &cf_receive1, sizeof(cf_receive1))) < 0) {
-		atf_tc_fail_errno("read");
+	if (can_read(s1, &cf_receive1, &rv1) < 0) {
+		atf_tc_fail_errno("can_read");
 	}
 
-	ATF_CHECK_MSG(rv1 > 0, "short read on socket");
-
 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1, sizeof(cf_send)) == 0,
 	    "received (1) packet is not what we sent");
 }
@@ -683,33 +610,21 @@ ATF_TC_BODY(canrecvfrom, tc)
 		atf_tc_fail_errno("write");
 	}
 
-	memset(&cf_receive2, 0, sizeof(cf_receive2));
-	if (( rv2 = rump_sys_read(s2, &cf_receive2, sizeof(cf_receive2))) < 0) {
-		atf_tc_fail_errno("read");
+	if (can_read(s2, &cf_receive2, &rv2) < 0) {
+		atf_tc_fail_errno("can_read");
 	}
 
-	ATF_CHECK_MSG(rv2 > 0, "short read on socket");
-
 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2, sizeof(cf_send)) == 0,
 	    "received (2) packet is not what we sent");
 
 	/* now check first socket */
-	memset(&cf_receive1, 0, sizeof(cf_receive1));
 	memset(&sa, 0, sizeof(sa));
-	salen = sizeof(sa);
-	if (( rv1 = rump_sys_recvfrom(s1, &cf_receive1, sizeof(cf_receive1),
-	    0, (struct sockaddr *)&sa, &salen)) < 0) {
-		atf_tc_fail_errno("recvfrom");
+	if (can_recvfrom(s1, &cf_receive1, &rv1, &sa) < 0) {
+		atf_tc_fail_errno("can_recvfrom");
 	}
 
-	ATF_CHECK_MSG(rv1 > 0, "short read on socket");
-
 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1, sizeof(cf_send)) == 0,
 	    "recvfrom (1) packet is not what we sent");
-	ATF_CHECK_MSG(sa.can_family == AF_CAN,
-	    "recvfrom provided wrong %d family", sa.can_family);
-	ATF_CHECK_MSG(salen == sizeof(sa),
-	    "recvfrom provided wrong size %d (!= %d)", salen, sizeof(sa));
 	ATF_CHECK_MSG(sa.can_ifindex == ifr.ifr_ifindex,
 	   "recvfrom provided wrong ifindex %d (!= %d)",
 	    sa.can_ifindex, ifr.ifr_ifindex);
@@ -719,7 +634,7 @@ ATF_TC(canbindfilter);
 ATF_TC_HEAD(canbindfilter, tc)
 {
 
-	atf_tc_set_md_var(tc, "descr", "check that  socket bound to an interface doens't get other interface's messages");
+	atf_tc_set_md_var(tc, "descr", "check that socket bound to an interface doens't get other interface's messages");
 	atf_tc_set_md_var(tc, "timeout", "5");
 }
 
@@ -804,48 +719,23 @@ ATF_TC_BODY(canbindfilter, tc)
 		atf_tc_fail_errno("write");
 	}
 
-	memset(&cf_receive2, 0, sizeof(cf_receive2));
-	if (( rv2 = rump_sys_read(s2, &cf_receive2, sizeof(cf_receive2))) < 0) {
+	if (can_read(s2, &cf_receive2, &rv2) < 0) {
 		atf_tc_fail_errno("read");
 	}
 
-	ATF_CHECK_MSG(rv2 > 0, "short read on socket");
-
 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2, sizeof(cf_send)) == 0,
 	    "received (2) packet is not what we sent");
 
 	/* now check first socket */
-	memset(&cf_receive1, 0, sizeof(cf_receive1));
-	FD_ZERO(&rfds);
-	FD_SET(s1, &rfds);
-	/* we should receive no message; wait for 2 seconds */
-	tmout.tv_sec = 2;
-	tmout.tv_usec = 0;
-	rv1 = rump_sys_select(s1 + 1, &rfds, NULL, NULL, &tmout);
-	switch(rv1) {
-	case -1:
-		atf_tc_fail_errno("select");
-		break;
-	case 0:
-		/* timeout: expected case */
-		return;
-	default: break;
-	}
-	salen = sizeof(sa);
-	ATF_CHECK_MSG(FD_ISSET(s1, &rfds), "select returns but s1 not in set");
-	if (( rv1 = rump_sys_recvfrom(s1, &cf_receive1, sizeof(cf_receive1),
-	    0, (struct sockaddr *)&sa, &salen)) < 0) {
-		atf_tc_fail_errno("recvfrom");
+	if (can_recvfrom(s1, &cf_receive1, &rv1, &sa) < 0) {
+		if (errno == EWOULDBLOCK) {
+			/* expected case */
+			return;
+		}
+		atf_tc_fail_errno("can_recvfrom");
 	}
-
-	ATF_CHECK_MSG(rv1 > 0, "short read on socket");
-
 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1, sizeof(cf_send)) == 0,
 	    "recvfrom (1) packet is not what we sent");
-	ATF_CHECK_MSG(sa.can_family == AF_CAN,
-	    "recvfrom provided wrong %d family", sa.can_family);
-	ATF_CHECK_MSG(salen == sizeof(sa),
-	    "recvfrom provided wrong size %d (!= %d)", salen, sizeof(sa));
 	ATF_CHECK_MSG(sa.can_ifindex == ifr.ifr_ifindex,
 	   "recvfrom provided wrong ifindex %d (!= %d)",
 	    sa.can_ifindex, ifr.ifr_ifindex);
@@ -1022,4 +912,3 @@ ATF_TP_ADD_TCS(tp)
         ATF_TP_ADD_TC(tp, cannoloop);
 	return atf_no_error();
 }
-

Added files:

Index: src/tests/net/can/h_canutils.c
diff -u /dev/null src/tests/net/can/h_canutils.c:1.1.2.1
--- /dev/null	Sat Feb  4 22:26:16 2017
+++ src/tests/net/can/h_canutils.c	Sat Feb  4 22:26:16 2017
@@ -0,0 +1,161 @@
+/*	$NetBSD: h_canutils.c,v 1.1.2.1 2017/02/04 22:26:16 bouyer Exp $	*/
+
+/*-
+ * Copyright (c) 2017 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Manuel Bouyer
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: h_canutils.c,v 1.1.2.1 2017/02/04 22:26:16 bouyer Exp $");
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+#include <sys/sockio.h>
+#include <sys/param.h>
+
+#include <atf-c.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <net/if.h>
+#include <netcan/can.h>
+
+#include <rump/rump.h>
+#include <rump/rump_syscalls.h>
+
+#include "h_macros.h"
+#include "h_canutils.h"
+
+void
+cancfg_rump_createif(const char *ifname)
+{
+	int s, rv;
+	struct ifreq ifr;
+
+	s = -1;
+	if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
+		atf_tc_fail_errno("if config socket");
+	}
+
+	memset(&ifr, 0, sizeof(ifr));
+	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+
+	if ((rv = rump_sys_ioctl(s, SIOCIFCREATE, &ifr)) < 0) {
+		atf_tc_fail_errno("if config create");
+	}
+
+	memset(&ifr, 0, sizeof(ifr));
+	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+
+	if ((rv = rump_sys_ioctl(s, SIOCGIFFLAGS, &ifr)) < 0) {
+		atf_tc_fail_errno("if config get flags");
+	}
+
+	ifr.ifr_flags |= IFF_UP;
+	if ((rv = rump_sys_ioctl(s, SIOCSIFFLAGS, &ifr)) < 0) {
+		atf_tc_fail_errno("if config set flags");
+	}
+}
+
+int
+can_recvfrom(int s, struct can_frame *cf, int *len, struct sockaddr_can *sa)
+{
+	int salen;
+	fd_set rfds;
+	struct timeval tmout;
+	int rv;
+
+	memset(cf,  0, sizeof(struct can_frame));
+	FD_ZERO(&rfds);
+	FD_SET(s, &rfds);
+	/* we should receive no message; wait for 2 seconds */
+	tmout.tv_sec = 2;
+	tmout.tv_usec = 0;
+	rv = rump_sys_select(s + 1, &rfds, NULL, NULL, &tmout);
+	switch(rv) {
+	case -1:
+		atf_tc_fail_errno("select");
+		/* NOTREACHED */
+	case 0:
+		/* timeout */
+		errno = EWOULDBLOCK;
+		return -1;
+	default: break;
+	}
+	ATF_CHECK_MSG(FD_ISSET(s, &rfds), "select returns but s not in set");
+	salen = sizeof(struct sockaddr_can);
+	if (( *len = rump_sys_recvfrom(s, cf, sizeof(struct can_frame),
+	    0, (struct sockaddr *)sa, &salen)) < 0) {
+		atf_tc_fail_errno("recvfrom");
+	}
+	ATF_CHECK_MSG(rv > 0, "short read on socket");
+	ATF_CHECK_MSG(sa->can_family == AF_CAN,
+	    "recvfrom provided wrong %d family", sa->can_family);       
+        ATF_CHECK_MSG(salen == sizeof(struct sockaddr_can),
+            "recvfrom provided wrong size %d (!= %d)", salen, sizeof(sa));
+	return 0;
+}
+
+int
+can_read(int s, struct can_frame *cf, int *len)
+{
+	fd_set rfds;
+	struct timeval tmout;
+	int rv;
+
+	memset(cf,  0, sizeof(struct can_frame));
+	FD_ZERO(&rfds);
+	FD_SET(s, &rfds);
+	/* we should receive no message; wait for 2 seconds */
+	tmout.tv_sec = 2;
+	tmout.tv_usec = 0;
+	rv = rump_sys_select(s + 1, &rfds, NULL, NULL, &tmout);
+	switch(rv) {
+	case -1:
+		atf_tc_fail_errno("select");
+		/* NOTREACHED */
+	case 0:
+		/* timeout */
+		errno = EWOULDBLOCK;
+		return -1;
+	default: break;
+	}
+	ATF_CHECK_MSG(FD_ISSET(s, &rfds), "select returns but s not in set");
+	if (( *len = rump_sys_read(s, cf, sizeof(struct can_frame))) < 0) {
+		atf_tc_fail_errno("read");
+	}
+	ATF_CHECK_MSG(rv > 0, "short read on socket");
+	return 0;
+}
Index: src/tests/net/can/h_canutils.h
diff -u /dev/null src/tests/net/can/h_canutils.h:1.1.2.1
--- /dev/null	Sat Feb  4 22:26:16 2017
+++ src/tests/net/can/h_canutils.h	Sat Feb  4 22:26:16 2017
@@ -0,0 +1,36 @@
+/*	$NetBSD: h_canutils.h,v 1.1.2.1 2017/02/04 22:26:16 bouyer Exp $	*/
+
+/*-
+ * Copyright (c) 2017 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Manuel Bouyer
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+void cancfg_rump_createif(const char *);
+int can_recvfrom(int, struct can_frame *, int *, struct sockaddr_can *);
+int can_read(int, struct can_frame *, int *);
+

Reply via email to