summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bgpd/Makefile.am35
-rw-r--r--bgpd/bgp_main.c24
-rw-r--r--bgpd/bgp_nexthop.c33
-rw-r--r--bgpd/bgp_peer.c3
-rw-r--r--bgpd/bgp_zebra.c4
-rw-r--r--lib/if.c2
-rw-r--r--lib/zclient.c264
-rw-r--r--lib/zclient.h7
-rw-r--r--tests/test-stream.c10
9 files changed, 288 insertions, 94 deletions
diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am
index 55aad179..ef5e735d 100644
--- a/bgpd/Makefile.am
+++ b/bgpd/Makefile.am
@@ -11,24 +11,27 @@ noinst_LIBRARIES = libbgp.a
sbin_PROGRAMS = bgpd
libbgp_a_SOURCES = \
- bgpd.c bgp_fsm.c bgp_aspath.c bgp_community.c bgp_attr.c \
- bgp_debug.c bgp_route.c bgp_zebra.c bgp_open.c bgp_routemap.c \
- bgp_packet.c bgp_network.c bgp_filter.c bgp_regex.c bgp_clist.c \
- bgp_dump.c bgp_snmp.c bgp_ecommunity.c bgp_mplsvpn.c bgp_nexthop.c \
- bgp_peer.c bgp_damp.c bgp_table.c bgp_advertise.c bgp_vty.c \
- bgp_engine.c bgp_session.c bgp_connection.c \
- bgp_common.c bgp_notification.c bgp_peer_index.c bgp_msg_write.c \
- bgp_route_refresh.c bgp_msg_read.c bgp_open_state.c
+ bgp_advertise.c bgp_aspath.c bgp_attr.c \
+ bgp_clist.c bgp_common.c bgp_community.c bgp_connection.c \
+ bgp_damp.c bgpd.c bgp_debug.c bgp_dump.c \
+ bgp_ecommunity.c bgp_engine.c bgp_filter.c bgp_fsm.c \
+ bgp_main.c bgp_mplsvpn.c bgp_msg_read.c bgp_msg_write.c \
+ bgp_network.c bgp_nexthop.c bgp_notification.c bgp_open.c \
+ bgp_open_state.c bgp_packet.c bgp_peer.c bgp_peer_index.c \
+ bgp_regex.c bgp_route.c bgp_routemap.c bgp_route_refresh.c \
+ bgp_session.c bgp_snmp.c bgp_table.c bgp_vty.c \
+ bgp_zebra.c
noinst_HEADERS = \
- bgp_aspath.h bgp_attr.h bgp_community.h bgp_debug.h bgp_fsm.h \
- bgp_network.h bgp_open.h bgp_packet.h bgp_regex.h bgp_route.h \
- bgpd.h bgp_filter.h bgp_clist.h bgp_dump.h bgp_zebra.h \
- bgp_ecommunity.h bgp_mplsvpn.h bgp_nexthop.h bgp_damp.h bgp_table.h \
- bgp_peer.h bgp_advertise.h bgp_snmp.h bgp_vty.h \
- bgp_engine.h bgp_session.h bgp_connection.h \
- bgp_common.h bgp_notification.h bgp_peer_index.h bgp_msg_write.h \
- bgp_route_refresh.h bgp.h bgp_msg_read.h bgp_open_state.h
+ bgp_advertise.h bgp_aspath.h bgp_attr.h bgp_clist.h \
+ bgp_common.h bgp_community.h bgp_connection.h bgp_damp.h \
+ bgp_debug.h bgpd.h bgp_dump.h bgp_ecommunity.h \
+ bgp_engine.h bgp_filter.h bgp_fsm.h bgp.h \
+ bgp_mplsvpn.h bgp_msg_read.h bgp_msg_write.h bgp_network.h \
+ bgp_nexthop.h bgp_notification.h bgp_open.h bgp_open_state.h \
+ bgp_packet.h bgp_peer.h bgp_peer_index.h bgp_regex.h \
+ bgp_route.h bgp_route_refresh.h bgp_session.h bgp_snmp.h \
+ bgp_table.h bgp_vty.h bgp_zebra.h
bgpd_SOURCES = bgp_main.c
bgpd_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index e98d841e..6f04d63f 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -51,6 +51,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_filter.h"
#include "bgpd/bgp_network.h"
#include "bgpd/bgp_engine.h"
+#include "bgpd/bgp_zebra.h"
/* bgpd options, we use GNU getopt library. */
static const struct option longopts[] =
@@ -401,10 +402,18 @@ init_second_stage(int pthreads)
bgp_nexus->event_hook[1] = bgp_event_hook;
confirm(NUM_EVENT_HOOK >= 2);
- /* vty can use either nexus or threads. For bgp client we always
- * want nexus, regardless of pthreads.
+ /* vty and zclient can use either nexus or threads.
+ * For bgp client we always want nexus, regardless of pthreads.
*/
vty_init_r(cli_nexus, routing_nexus);
+ zclient_init_r(routing_nexus);
+
+ /* Now we have our nexus we can init BGP. */
+ /* BGP related initialization. */
+ bgp_init ();
+
+ /* Sort CLI commands. */
+ sort_node ();
}
/* Main routine of bgpd. Treatment of argument and start bgp finite
@@ -418,6 +427,7 @@ main (int argc, char **argv)
int dryrun = 0;
char *progname;
int tmp_port;
+ int threaded = 0;
/* Set umask before anything for security */
umask (0027);
@@ -506,8 +516,7 @@ main (int argc, char **argv)
usage (progname, 0);
break;
case 't':
- if (!qpthreads_enabled)
- init_second_stage(1);
+ threaded = 1;
break;
default:
usage (progname, 1);
@@ -527,11 +536,8 @@ main (int argc, char **argv)
vty_init (master);
memory_init ();
- /* BGP related initialization. */
- bgp_init ();
-
- /* Sort CLI commands. */
- sort_node ();
+ if (threaded)
+ init_second_stage(1);
/* Parse config file. */
vty_read_config_first_cmd_special (config_file, config_default, after_first_cmd);
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index 7a096faa..32dae086 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -1082,29 +1082,6 @@ bgp_import (struct thread *t)
return 0;
}
-/* Connect to zebra for nexthop lookup. */
-static int
-zlookup_connect (struct thread *t)
-{
- struct zclient *zlookup;
-
- zlookup = THREAD_ARG (t);
- zlookup->t_connect = NULL;
-
- if (zlookup->sock != -1)
- return 0;
-
-#ifdef HAVE_TCP_ZEBRA
- zlookup->sock = zclient_socket ();
-#else
- zlookup->sock = zclient_socket_un (ZEBRA_SERV_PATH);
-#endif /* HAVE_TCP_ZEBRA */
- if (zlookup->sock < 0)
- return -1;
-
- return 0;
-}
-
/* Check specified multiaccess next-hop. */
int
bgp_multiaccess_check_v4 (struct in_addr nexthop, char *peer)
@@ -1282,13 +1259,9 @@ bgp_scan_init (void)
zlookup = zclient_new ();
zlookup->sock = -1;
- /* TODO: reinstate zebra interface when ready */
- if (0)
- {
- zlookup->enable = 1 ;
- zlookup->t_connect = thread_add_event (master, zlookup_connect,
- zlookup, 0);
- } ;
+ /* enable zebra client and schedule connection */
+ zlookup->enable = 1 ;
+ zlookup_schedule(zlookup);
bgp_scan_interval = BGP_SCAN_INTERVAL_DEFAULT;
bgp_import_interval = BGP_IMPORT_INTERVAL_DEFAULT;
diff --git a/bgpd/bgp_peer.c b/bgpd/bgp_peer.c
index dca9054d..f314e17b 100644
--- a/bgpd/bgp_peer.c
+++ b/bgpd/bgp_peer.c
@@ -51,7 +51,7 @@
#include "plist.h"
#include "mqueue.h"
#include "workqueue.h"
-#include "if.c"
+#include "if.h"
#ifdef HAVE_SNMP
#include "bgpd/bgp_snmp.h"
@@ -129,7 +129,6 @@ bgp_session_do_event(mqueue_block mqb, mqb_flag_t flag)
default:
/* If now Stopped, then for some reason the BGP Engine has either */
/* stopped trying to connect, or the session has been stopped. */
- /* TODO: stop from BGP Engine requires a Disable to be sent... */
if (args->stopped)
bgp_session_has_stopped(peer);
break ;
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index a9f13da2..19fefb9b 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1042,11 +1042,9 @@ bgp_zebra_init (void)
zclient->ipv6_route_delete = zebra_read_ipv6;
#endif /* HAVE_IPV6 */
- /* TODO: restore zebra when have threaded it !! */
-#if 1
+ /* disable zebra client */
zclient->enable = 0 ; /* disable it */
zclient_stop(zclient) ; /* and make sure all threads stopped */
-#endif
/* Interface related init. */
if_init ();
diff --git a/lib/if.c b/lib/if.c
index e3107116..d14cfb93 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -664,7 +664,7 @@ connected_log (struct connected *connected, char *str)
strncat (logbuf, inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
BUFSIZ - strlen(logbuf));
}
- zlog (NULL, LOG_INFO, logbuf);
+ zlog (NULL, LOG_INFO, "%s", logbuf);
}
/* If two connected address has same prefix return 1. */
diff --git a/lib/zclient.c b/lib/zclient.c
index d3d53227..8cfa5d52 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -32,18 +32,25 @@
#include "zclient.h"
#include "memory.h"
#include "table.h"
-
-/* Zebra client events. */
-enum event {ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT};
-/* Prototype for event manager. */
-static void zclient_event (enum event, struct zclient *);
+/* Zebra client events. */
+enum event {ZLOOKUP_SCHEDULE, ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT};
extern struct thread_master *master;
/* This file local debug flag. */
int zclient_debug = 0;
-
+
+/* Nexus to use, if any */
+static qpn_nexus zclient_nexus = NULL;
+
+/* prototypes */
+static int zclient_read (struct zclient *zclient);
+static void zclient_event (enum event, struct zclient *);
+static void zclient_event_r (enum event event, struct zclient *zclient);
+static void zclient_event_t (enum event event, struct zclient *zclient);
+static void zclient_connect_r (qtimer qtr, void* timer_info, qtime_t when);
+
/* Allocate zclient structure. */
struct zclient *
zclient_new ()
@@ -55,6 +62,13 @@ zclient_new ()
zclient->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
zclient->wb = buffer_new(0);
+ if (zclient_nexus)
+ {
+ zclient->qf = qps_file_init_new(zclient->qf, NULL);
+ zclient->qtr = qtimer_init_new(zclient->qtr, zclient_nexus->pile,
+ zclient_connect_r, zclient);
+ }
+
return zclient;
}
@@ -73,9 +87,29 @@ zclient_free (struct zclient *zclient)
if (zclient->wb)
buffer_free(zclient->wb);
+ /* qfile and qtimer */
+ if (zclient->qf)
+ {
+ qps_remove_file(zclient->qf);
+ qps_file_free(zclient->qf);
+ zclient->qf = NULL;
+ }
+ if (zclient->qtr)
+ {
+ qtimer_free(zclient->qtr);
+ zclient->qtr = NULL;
+ }
+
XFREE (MTYPE_ZCLIENT, zclient);
}
+/* Initialize to use a nexus (qpselect etc). */
+void
+zclient_init_r (qpn_nexus n)
+{
+ zclient_nexus = n;
+}
+
/* Initialize zebra client. Argument redist_default is unwanted
redistribute route type. */
void
@@ -108,6 +142,13 @@ zclient_init (struct zclient *zclient, int redist_default)
zclient_event (ZCLIENT_SCHEDULE, zclient);
}
+/* Schedule lookup connection */
+void
+zlookup_schedule(struct zclient *zclient)
+{
+ zclient_event (ZLOOKUP_SCHEDULE, zclient);
+}
+
/* Stop zebra client services. */
void
zclient_stop (struct zclient *zclient)
@@ -120,6 +161,12 @@ zclient_stop (struct zclient *zclient)
THREAD_OFF(zclient->t_connect);
THREAD_OFF(zclient->t_write);
+ if (zclient->qf)
+ qps_remove_file(zclient->qf);
+
+ if (zclient->qtr)
+ qtimer_unset(zclient->qtr);
+
/* Reset streams. */
stream_reset(zclient->ibuf);
stream_reset(zclient->obuf);
@@ -217,8 +264,37 @@ zclient_failed(struct zclient *zclient)
return -1;
}
+/* Write as much data as possible.
+ * nexus version */
+static void
+zclient_flush_data_r(qps_file qf, void* file_info)
+{
+ struct zclient *zclient = file_info;
+
+ qps_disable_modes(qf, qps_write_mbit);
+
+ if (zclient->sock < 0)
+ return;
+
+ switch (buffer_flush_available(zclient->wb, zclient->sock))
+ {
+ case BUFFER_ERROR:
+ zlog_warn("%s: buffer_flush_available failed on zclient fd %d, closing",
+ __func__, zclient->sock);
+ zclient_failed(zclient);
+ break;
+ case BUFFER_PENDING:
+ qps_enable_mode(qf, qps_write_mnum, zclient_flush_data_r) ;
+ break;
+ case BUFFER_EMPTY:
+ break;
+ }
+}
+
+/* Write as much data as possible.
+ * thread version */
static int
-zclient_flush_data(struct thread *thread)
+zclient_flush_data_t(struct thread *thread)
{
struct zclient *zclient = THREAD_ARG(thread);
@@ -233,7 +309,7 @@ zclient_flush_data(struct thread *thread)
return zclient_failed(zclient);
break;
case BUFFER_PENDING:
- zclient->t_write = thread_add_write(master, zclient_flush_data,
+ zclient->t_write = thread_add_write(master, zclient_flush_data_t,
zclient, zclient->sock);
break;
case BUFFER_EMPTY:
@@ -256,11 +332,17 @@ zclient_send_message(struct zclient *zclient)
return zclient_failed(zclient);
break;
case BUFFER_EMPTY:
- THREAD_OFF(zclient->t_write);
+ if (zclient_nexus)
+ qps_disable_modes(zclient->qf, qps_write_mbit);
+ else
+ THREAD_OFF(zclient->t_write);
break;
case BUFFER_PENDING:
- THREAD_WRITE_ON(master, zclient->t_write,
- zclient_flush_data, zclient, zclient->sock);
+ if (zclient_nexus)
+ qps_enable_mode(zclient->qf, qps_write_mnum, zclient_flush_data_r) ;
+ else
+ THREAD_WRITE_ON(master, zclient->t_write,
+ zclient_flush_data_t, zclient, zclient->sock);
break;
}
return 0;
@@ -313,6 +395,10 @@ zclient_start (struct zclient *zclient)
if (zclient->t_connect)
return 0;
+ /* Check timer */
+ if (zclient->qtr && qtr_is_active(zclient->qtr))
+ return 0;
+
/* Make socket. */
#ifdef HAVE_TCP_ZEBRA
zclient->sock = zclient_socket ();
@@ -336,6 +422,9 @@ zclient_start (struct zclient *zclient)
if (zclient_debug)
zlog_debug ("zclient connect success with socket [%d]", zclient->sock);
+ if (zclient_nexus)
+ qps_add_file(zclient_nexus->selection, zclient->qf, zclient->sock, zclient);
+
/* Create read thread. */
zclient_event (ZCLIENT_READ, zclient);
@@ -358,9 +447,24 @@ zclient_start (struct zclient *zclient)
}
/* This function is a wrapper function for calling zclient_start from
+ qtimer. */
+static void
+zclient_connect_r (qtimer qtr, void* timer_info, qtime_t when)
+{
+ struct zclient *zclient = timer_info;
+
+ qtimer_unset(qtr);
+
+ if (zclient_debug)
+ zlog_debug ("zclient_connect is called");
+
+ zclient_start (zclient);
+}
+
+/* This function is a wrapper function for calling zclient_start from
timer or event thread. */
static int
-zclient_connect (struct thread *t)
+zclient_connect_t (struct thread *t)
{
struct zclient *zclient;
@@ -372,7 +476,51 @@ zclient_connect (struct thread *t)
return zclient_start (zclient);
}
-
+
+/* Connect to zebra for nexthop lookup.
+ * thread version */
+static int
+zlookup_connect_t (struct thread *t)
+{
+ struct zclient *zlookup;
+
+ zlookup = THREAD_ARG (t);
+ zlookup->t_connect = NULL;
+
+ if (zlookup->sock != -1)
+ return 0;
+
+#ifdef HAVE_TCP_ZEBRA
+ zlookup->sock = zclient_socket ();
+#else
+ zlookup->sock = zclient_socket_un (ZEBRA_SERV_PATH);
+#endif /* HAVE_TCP_ZEBRA */
+ if (zlookup->sock < 0)
+ return -1;
+
+ return 0;
+}
+
+/* Connect to zebra for nexthop lookup.
+ * nexus version */
+static void
+zlookup_connect_r (qtimer qtr, void* timer_info, qtime_t when)
+{
+ struct zclient *zlookup = timer_info;
+
+ qtimer_unset(qtr);
+
+ if (zlookup->sock != -1)
+ return;
+
+#ifdef HAVE_TCP_ZEBRA
+ zlookup->sock = zclient_socket ();
+#else
+ zlookup->sock = zclient_socket_un (ZEBRA_SERV_PATH);
+#endif /* HAVE_TCP_ZEBRA */
+}
+
+
/*
* "xdr_encode"-like interface that allows daemon (client) to send
* a message to zebra server for a route that needs to be
@@ -791,20 +939,32 @@ zebra_interface_address_read (int type, struct stream *s)
return ifc;
}
-
+/* nexus: Zebra client message read function. */
+static void
+zclient_read_r (qps_file qf, void* file_info)
+{
+ struct zclient *zclient = file_info;
+ qps_disable_modes(qf, qps_read_mbit);
+ zclient_read(zclient);
+}
+
+/* thread: Zebra client message read function. */
+static int
+zclient_read_t (struct thread *thread)
+{
+ struct zclient *zclient = THREAD_ARG (thread);
+ zclient->t_read = NULL;
+ return zclient_read(zclient);
+}
+
/* Zebra client message read function. */
static int
-zclient_read (struct thread *thread)
+zclient_read (struct zclient *zclient)
{
int ret;
size_t already;
uint16_t length, command;
uint8_t marker, version;
- struct zclient *zclient;
-
- /* Get socket to zebra. */
- zclient = THREAD_ARG (thread);
- zclient->t_read = NULL;
/* Read zebra header (if we don't have it already). */
if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE)
@@ -991,15 +1151,30 @@ zclient_redistribute_default (int command, struct zclient *zclient)
zebra_message_send (zclient, command);
}
+/* Arm event. */
static void
zclient_event (enum event event, struct zclient *zclient)
{
+ if (zclient_nexus)
+ zclient_event_r(event, zclient);
+ else
+ zclient_event_t(event, zclient);
+}
+
+/* Arm event.
+ * nexus version */
+static void
+zclient_event_r (enum event event, struct zclient *zclient)
+{
switch (event)
{
+ case ZLOOKUP_SCHEDULE:
+ if (!qtr_is_active(zclient->qtr))
+ qtimer_set(zclient->qtr, qt_get_monotonic(), zlookup_connect_r) ;
+ break;
case ZCLIENT_SCHEDULE:
- if (! zclient->t_connect)
- zclient->t_connect =
- thread_add_event (master, zclient_connect, zclient, 0);
+ if (!qtr_is_active(zclient->qtr))
+ qtimer_set(zclient->qtr, qt_get_monotonic(), zclient_connect_r) ;
break;
case ZCLIENT_CONNECT:
if (zclient->fail >= 10)
@@ -1007,14 +1182,47 @@ zclient_event (enum event event, struct zclient *zclient)
if (zclient_debug)
zlog_debug ("zclient connect schedule interval is %d",
zclient->fail < 3 ? 10 : 60);
+ if (!qtr_is_active(zclient->qtr))
+ qtimer_set(zclient->qtr,
+ qt_add_monotonic(QTIME(zclient->fail < 3 ? 10 : 60)), zclient_connect_r) ;
+ break;
+ case ZCLIENT_READ:
+ qps_enable_mode(zclient->qf, qps_read_mnum, zclient_read_r) ;
+ break;
+ }
+}
+
+/* Arm event.
+ * thread version */
+static void
+zclient_event_t (enum event event, struct zclient *zclient)
+{
+ switch (event)
+ {
+ case ZLOOKUP_SCHEDULE:
+ if (! zclient->t_connect)
+ zclient->t_connect =
+ thread_add_event (master, zlookup_connect_t, zclient, 0);
+ break;
+ case ZCLIENT_SCHEDULE:
+ if (! zclient->t_connect)
+ zclient->t_connect =
+ thread_add_event (master, zclient_connect_t, zclient, 0);
+ break;
+ case ZCLIENT_CONNECT:
+ if (zclient->fail >= 10)
+ return;
+ if (zclient_debug)
+ zlog_debug ("zclient connect schedule interval is %d",
+ zclient->fail < 3 ? 10 : 60);
if (! zclient->t_connect)
- zclient->t_connect =
- thread_add_timer (master, zclient_connect, zclient,
- zclient->fail < 3 ? 10 : 60);
+ zclient->t_connect =
+ thread_add_timer (master, zclient_connect_t, zclient,
+ zclient->fail < 3 ? 10 : 60);
break;
case ZCLIENT_READ:
- zclient->t_read =
- thread_add_read (master, zclient_read, zclient, zclient->sock);
+ zclient->t_read =
+ thread_add_read (master, zclient_read_t, zclient, zclient->sock);
break;
}
}
diff --git a/lib/zclient.h b/lib/zclient.h
index 21786ab8..394407eb 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -24,6 +24,7 @@
/* For struct interface and struct connected. */
#include "if.h"
+#include "qpnexus.h"
/* For input/output buffer to zebra. */
#define ZEBRA_MAX_PACKET_SIZ 4096
@@ -60,6 +61,10 @@ struct zclient
/* Thread to write buffered data to zebra. */
struct thread *t_write;
+ /* If using nexus, qfile and qtimer */
+ qps_file qf;
+ qtimer qtr;
+
/* Redistribute information. */
u_char redist_default;
u_char redist[ZEBRA_ROUTE_MAX];
@@ -121,11 +126,13 @@ struct zapi_ipv4
/* Prototypes of zebra client service functions. */
extern struct zclient *zclient_new (void);
+extern void zclient_init_r (qpn_nexus);
extern void zclient_init (struct zclient *, int);
extern int zclient_start (struct zclient *);
extern void zclient_stop (struct zclient *);
extern void zclient_reset (struct zclient *);
extern void zclient_free (struct zclient *);
+extern void zlookup_schedule(struct zclient *);
/* Get TCP socket connection to zebra daemon at loopback address. */
extern int zclient_socket (void);
diff --git a/tests/test-stream.c b/tests/test-stream.c
index 785ce588..e145436f 100644
--- a/tests/test-stream.c
+++ b/tests/test-stream.c
@@ -2,7 +2,7 @@
#include <stream.h>
#include <thread.h>
-static long int ham = 0xdeadbeefdeadbeef;
+static int64_t ham = 0xdeadbeefdeadbeef;
struct thread_master *master;
static void
@@ -11,9 +11,9 @@ print_stream (struct stream *s)
size_t getp = stream_get_getp (s);
printf ("endp: %ld, readable: %ld, writeable: %ld\n",
- stream_get_endp (s),
- STREAM_READABLE (s),
- STREAM_WRITEABLE (s));
+ (long int)stream_get_endp (s),
+ (long int)STREAM_READABLE (s),
+ (long int)STREAM_WRITEABLE (s));
while (STREAM_READABLE (s))
{
@@ -48,7 +48,7 @@ main (void)
printf ("c: 0x%hhx\n", stream_getc (s));
printf ("w: 0x%hx\n", stream_getw (s));
printf ("l: 0x%x\n", stream_getl (s));
- printf ("q: 0x%lx\n", stream_getq (s));
+ printf ("q: 0x%llx\n", (long long unsigned)stream_getq (s));
return 0;
}