mirror of https://github.com/aria2/aria2
Update wslay
parent
dda0b62fb9
commit
28562b3f6d
|
@ -1,6 +1,6 @@
|
||||||
The MIT License
|
The MIT License
|
||||||
|
|
||||||
Copyright (c) 2011, 2012 Tatsuhiro Tsujikawa
|
Copyright (c) 2011, 2012, 2015 Tatsuhiro Tsujikawa
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -23,8 +23,3 @@
|
||||||
SUBDIRS = lib tests
|
SUBDIRS = lib tests
|
||||||
|
|
||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
EXTRA_DIST = examples/Makefile \
|
|
||||||
examples/fork-echoserv.c \
|
|
||||||
examples/echoserv.cc \
|
|
||||||
examples/testclient.cc
|
|
||||||
|
|
|
@ -1,41 +1,47 @@
|
||||||
wslay 0.1.1
|
wslay 1.0.0
|
||||||
===========
|
===========
|
||||||
|
|
||||||
Release Note
|
Release Note
|
||||||
------------
|
------------
|
||||||
|
|
||||||
This release fixes the example programs and tutorial. It does not
|
This release fixes several build issues. Most changes were introduced
|
||||||
change library code at all, so the library version has not been
|
by contributors. Thank you for all the contributions in this project.
|
||||||
changed.
|
Because wslay is very stable since the previous release (more than 2
|
||||||
|
years ago), we mark this release 1.0.0.
|
||||||
|
|
||||||
Changes
|
Changes
|
||||||
-------
|
-------
|
||||||
|
|
||||||
* Fixed example source code and tutorial.
|
* Fix NULL check in wslay_frame_context_init.
|
||||||
|
|
||||||
|
Patch from Witchakorn Kamolpornwijit
|
||||||
|
|
||||||
wslay 0.1.0
|
* the examples uses epoll and thus only be built on linux
|
||||||
===========
|
|
||||||
|
|
||||||
Release Note
|
Patch from Kazuho Oku
|
||||||
------------
|
|
||||||
|
|
||||||
This is the initial release of wslay WebSocket C library.
|
* build: allow one to build out-of-tree documentation
|
||||||
|
|
||||||
Wslay is a WebSocket library written in C. It implements the protocol
|
Patch from Vincent Bernat
|
||||||
version 13 described in RFC 6455. This library offers 2 levels of API:
|
|
||||||
event-based API and frame-based low-level API. For event-based API, it
|
|
||||||
is suitable for non-blocking reactor pattern style. You can set
|
|
||||||
callbacks in various events. For frame-based API, you can send
|
|
||||||
WebSocket frame directly. Wslay only supports data transfer part of
|
|
||||||
WebSocket protocol and does not perform opening handshake in HTTP.
|
|
||||||
|
|
||||||
Wslay does not perform any I/O operations for its own. Instead, it
|
* build: fix `./configure` when nettle is not present
|
||||||
offers callbacks for them. This makes Wslay independent on any I/O
|
|
||||||
frameworks, SSL, sockets, etc. This makes Wslay protable across
|
|
||||||
various platforms and the application authors can choose freely IO
|
|
||||||
frameworks.
|
|
||||||
|
|
||||||
Visit http://wslay.sourceforge.net/ for the API reference and
|
`PKG_CHECK_MODULES` will fail unless we give it an action to execute
|
||||||
tutorial.
|
on failure. When nettle is not available, we set `have_nettle` to
|
||||||
|
`no`.
|
||||||
|
|
||||||
|
Patch from Vincent Bernat
|
||||||
|
|
||||||
|
* Adds the ability to override the version header include with a
|
||||||
|
define. This enables projects to set the build version from the
|
||||||
|
compile environment and avoid the need to generate the version
|
||||||
|
header.
|
||||||
|
|
||||||
|
Patch from Ben Vanik
|
||||||
|
|
||||||
|
* Improve http_handshake in fork-echoserver.
|
||||||
|
|
||||||
|
Patch from Gurjeet Singh
|
||||||
|
|
||||||
|
* Don't send any pending control frame other than Close control frame
|
||||||
|
after Close is queued.
|
||||||
|
|
|
@ -22,7 +22,7 @@ Wslay supports:
|
||||||
|
|
||||||
Wslay does not perform any I/O operations for its own. Instead, it
|
Wslay does not perform any I/O operations for its own. Instead, it
|
||||||
offers callbacks for them. This makes Wslay independent on any I/O
|
offers callbacks for them. This makes Wslay independent on any I/O
|
||||||
frameworks, SSL, sockets, etc. This makes Wslay protable across
|
frameworks, SSL, sockets, etc. This makes Wslay portable across
|
||||||
various platforms and the application authors can choose freely I/O
|
various platforms and the application authors can choose freely I/O
|
||||||
frameworks.
|
frameworks.
|
||||||
|
|
||||||
|
@ -30,3 +30,31 @@ See Autobahn test reports:
|
||||||
`server <http://wslay.sourceforge.net/autobahn/reports/servers/index.html>`_
|
`server <http://wslay.sourceforge.net/autobahn/reports/servers/index.html>`_
|
||||||
and
|
and
|
||||||
`client <http://wslay.sourceforge.net/autobahn/reports/clients/index.html>`_.
|
`client <http://wslay.sourceforge.net/autobahn/reports/clients/index.html>`_.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
|
||||||
|
`Sphinx <http://sphinx.pocoo.org/>`_ is used to generate man pages.
|
||||||
|
|
||||||
|
To build and run the unit test programs, the following packages are
|
||||||
|
needed:
|
||||||
|
|
||||||
|
* cunit >= 2.1
|
||||||
|
|
||||||
|
To build and run the example programs, the following packages are
|
||||||
|
needed:
|
||||||
|
|
||||||
|
* nettle >= 2.4
|
||||||
|
|
||||||
|
|
||||||
|
Build from git
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Building from git is easy, but please be sure that at least autoconf 2.68 is
|
||||||
|
used.::
|
||||||
|
|
||||||
|
$ autoreconf -i
|
||||||
|
$ automake
|
||||||
|
$ autoconf
|
||||||
|
$ ./configure
|
||||||
|
$ make
|
||||||
|
|
|
@ -21,14 +21,14 @@ dnl LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
dnl OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
dnl OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
dnl WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
dnl WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
AC_PREREQ(2.61)
|
AC_PREREQ(2.61)
|
||||||
AC_INIT([wslay], [0.1.1], [t-tujikawa@users.sourceforge.net])
|
AC_INIT([wslay], [1.0.1-DEV], [t-tujikawa@users.sourceforge.net])
|
||||||
LT_PREREQ([2.2.6])
|
LT_PREREQ([2.2.6])
|
||||||
LT_INIT()
|
LT_INIT()
|
||||||
AC_CONFIG_AUX_DIR([.])
|
AC_CONFIG_AUX_DIR([.])
|
||||||
dnl See versioning rule:
|
dnl See versioning rule:
|
||||||
dnl http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
dnl http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||||
AC_SUBST(LT_CURRENT, 0)
|
AC_SUBST(LT_CURRENT, 0)
|
||||||
AC_SUBST(LT_REVISION, 0)
|
AC_SUBST(LT_REVISION, 1)
|
||||||
AC_SUBST(LT_AGE, 0)
|
AC_SUBST(LT_AGE, 0)
|
||||||
|
|
||||||
AC_CANONICAL_BUILD
|
AC_CANONICAL_BUILD
|
||||||
|
@ -42,15 +42,21 @@ AC_CONFIG_HEADERS([config.h])
|
||||||
|
|
||||||
dnl Checks for programs
|
dnl Checks for programs
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
|
AC_PROG_CXX
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
AC_PROG_LN_S
|
AC_PROG_LN_S
|
||||||
AC_PROG_MAKE_SET
|
AC_PROG_MAKE_SET
|
||||||
|
PKG_PROG_PKG_CONFIG([0.20])
|
||||||
|
|
||||||
AC_PATH_PROG([SPHINX_BUILD], [sphinx-build])
|
AC_PATH_PROG([SPHINX_BUILD], [sphinx-build])
|
||||||
AC_SUBST([SPHINX_BUILD])
|
AC_SUBST([SPHINX_BUILD])
|
||||||
AM_CONDITIONAL([HAVE_SPHINX_BUILD], [ test "x$SPHINX_BUILD" != "x" ])
|
AM_CONDITIONAL([HAVE_SPHINX_BUILD], [ test "x$SPHINX_BUILD" != "x" ])
|
||||||
|
|
||||||
# Checks for libraries.
|
# Checks for libraries.
|
||||||
|
|
||||||
|
# Nettle used in examples
|
||||||
|
PKG_CHECK_MODULES([NETTLE], [nettle >= 2.4], [have_nettle=yes], [have_nettle=no])
|
||||||
|
|
||||||
AC_CHECK_LIB([cunit], [CU_initialize_registry],
|
AC_CHECK_LIB([cunit], [CU_initialize_registry],
|
||||||
[have_cunit=yes], [have_cunit=no])
|
[have_cunit=yes], [have_cunit=no])
|
||||||
AM_CONDITIONAL([HAVE_CUNIT], [ test "x${have_cunit}" = "xyes" ])
|
AM_CONDITIONAL([HAVE_CUNIT], [ test "x${have_cunit}" = "xyes" ])
|
||||||
|
@ -91,9 +97,6 @@ AC_CHECK_TYPES([ptrdiff_t])
|
||||||
AC_C_BIGENDIAN
|
AC_C_BIGENDIAN
|
||||||
|
|
||||||
# Checks for library functions.
|
# Checks for library functions.
|
||||||
if test "x$cross_compiling" != "xyes"; then
|
|
||||||
AC_FUNC_MALLOC
|
|
||||||
fi
|
|
||||||
AC_CHECK_FUNCS([ \
|
AC_CHECK_FUNCS([ \
|
||||||
memmove \
|
memmove \
|
||||||
memset \
|
memset \
|
||||||
|
@ -102,6 +105,17 @@ AC_CHECK_FUNCS([ \
|
||||||
htons
|
htons
|
||||||
])
|
])
|
||||||
|
|
||||||
|
build_examples=no
|
||||||
|
if test "x${have_nettle}" = "xyes"; then
|
||||||
|
case $host_os in
|
||||||
|
linux*)
|
||||||
|
# the examples uses epoll
|
||||||
|
build_examples=yes
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL([ENABLE_EXAMPLES], [ test "x${build_examples}" = "xyes" ])
|
||||||
|
|
||||||
AC_CONFIG_FILES([
|
AC_CONFIG_FILES([
|
||||||
Makefile
|
Makefile
|
||||||
lib/Makefile
|
lib/Makefile
|
||||||
|
@ -109,6 +123,9 @@ AC_CONFIG_FILES([
|
||||||
lib/includes/Makefile
|
lib/includes/Makefile
|
||||||
lib/includes/wslay/wslayver.h
|
lib/includes/wslay/wslayver.h
|
||||||
tests/Makefile
|
tests/Makefile
|
||||||
|
examples/Makefile
|
||||||
|
doc/Makefile
|
||||||
|
doc/sphinx/conf.py
|
||||||
])
|
])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|
||||||
|
@ -121,4 +138,6 @@ AC_MSG_NOTICE([summary of build options:
|
||||||
CFlags: ${CFLAGS}
|
CFlags: ${CFLAGS}
|
||||||
Library types: Shared=${enable_shared}, Static=${enable_static}
|
Library types: Shared=${enable_shared}, Static=${enable_static}
|
||||||
CUnit: ${have_cunit}
|
CUnit: ${have_cunit}
|
||||||
|
Nettle: ${have_nettle}
|
||||||
|
Build examples: ${build_examples}
|
||||||
])
|
])
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
# Wslay - The WebSocket Library
|
|
||||||
|
|
||||||
# Copyright (c) 2011, 2012 Tatsuhiro Tsujikawa
|
|
||||||
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
# a copy of this software and associated documentation files (the
|
|
||||||
# "Software"), to deal in the Software without restriction, including
|
|
||||||
# without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
# permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
# the following conditions:
|
|
||||||
|
|
||||||
# The above copyright notice and this permission notice shall be
|
|
||||||
# included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
CC = gcc
|
|
||||||
CXX = g++
|
|
||||||
CFLAGS = -g -O2 -I../lib/includes
|
|
||||||
CXXFLAGS = $(CFLAGS)
|
|
||||||
LDFLAGS = -L../lib/.libs
|
|
||||||
LIBS = -lwslay -lnettle
|
|
||||||
|
|
||||||
PROGRAMS = fork-echoserv echoserv testclient
|
|
||||||
|
|
||||||
.PHONY: all
|
|
||||||
all: $(PROGRAMS)
|
|
||||||
|
|
||||||
fork-echoserv: fork-echoserv.c
|
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ fork-echoserv.c $(LIBS)
|
|
||||||
|
|
||||||
echoserv: echoserv.cc
|
|
||||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ echoserv.cc $(LIBS)
|
|
||||||
|
|
||||||
testclient: testclient.cc
|
|
||||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ testclient.cc $(LIBS)
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
rm -f *.o $(PROGRAMS)
|
|
|
@ -50,6 +50,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include <nettle/base64.h>
|
#include <nettle/base64.h>
|
||||||
#include <nettle/sha.h>
|
#include <nettle/sha.h>
|
||||||
|
@ -159,6 +160,80 @@ void create_accept_key(char *dst, const char *client_key)
|
||||||
dst[BASE64_ENCODE_RAW_LENGTH(20)] = '\0';
|
dst[BASE64_ENCODE_RAW_LENGTH(20)] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We parse HTTP header lines of the format
|
||||||
|
* \r\nfield_name: value1, value2, ... \r\n
|
||||||
|
*
|
||||||
|
* If the caller is looking for a specific value, we return a pointer to the
|
||||||
|
* start of that value, else we simply return the start of values list.
|
||||||
|
*/
|
||||||
|
static char*
|
||||||
|
http_header_find_field_value(char *header, char *field_name, char *value)
|
||||||
|
{
|
||||||
|
char *header_end,
|
||||||
|
*field_start,
|
||||||
|
*field_end,
|
||||||
|
*next_crlf,
|
||||||
|
*value_start;
|
||||||
|
int field_name_len;
|
||||||
|
|
||||||
|
/* Pointer to the last character in the header */
|
||||||
|
header_end = header + strlen(header) - 1;
|
||||||
|
|
||||||
|
field_name_len = strlen(field_name);
|
||||||
|
|
||||||
|
field_start = header;
|
||||||
|
|
||||||
|
do{
|
||||||
|
field_start = strstr(field_start+1, field_name);
|
||||||
|
|
||||||
|
field_end = field_start + field_name_len - 1;
|
||||||
|
|
||||||
|
if(field_start != NULL
|
||||||
|
&& field_start - header >= 2
|
||||||
|
&& field_start[-2] == '\r'
|
||||||
|
&& field_start[-1] == '\n'
|
||||||
|
&& header_end - field_end >= 1
|
||||||
|
&& field_end[1] == ':')
|
||||||
|
{
|
||||||
|
break; /* Found the field */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
continue; /* This is not the one; keep looking. */
|
||||||
|
}
|
||||||
|
} while(field_start != NULL);
|
||||||
|
|
||||||
|
if(field_start == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Find the field terminator */
|
||||||
|
next_crlf = strstr(field_start, "\r\n");
|
||||||
|
|
||||||
|
/* A field is expected to end with \r\n */
|
||||||
|
if(next_crlf == NULL)
|
||||||
|
return NULL; /* Malformed HTTP header! */
|
||||||
|
|
||||||
|
/* If not looking for a value, then return a pointer to the start of values string */
|
||||||
|
if(value == NULL)
|
||||||
|
return field_end+2;
|
||||||
|
|
||||||
|
value_start = strstr(field_start, value);
|
||||||
|
|
||||||
|
/* Value not found */
|
||||||
|
if(value_start == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Found the value we're looking for */
|
||||||
|
if(value_start > next_crlf)
|
||||||
|
return NULL; /* ... but after the CRLF terminator of the field. */
|
||||||
|
|
||||||
|
/* The value we found should be properly delineated from the other tokens */
|
||||||
|
if(isalnum(value_start[-1]) || isalnum(value_start[strlen(value)]))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return value_start;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Performs HTTP handshake. *fd* is the file descriptor of the
|
* Performs HTTP handshake. *fd* is the file descriptor of the
|
||||||
* connection to the client. This function returns 0 if it succeeds,
|
* connection to the client. This function returns 0 if it succeeds,
|
||||||
|
@ -195,13 +270,13 @@ int http_handshake(int fd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(strstr(header, "\r\nUpgrade: websocket\r\n") == NULL ||
|
|
||||||
strstr(header, "\r\nConnection: Upgrade\r\n") == NULL ||
|
if(http_header_find_field_value(header, "Upgrade", "websocket") == NULL ||
|
||||||
(keyhdstart = strstr(header, "\r\nSec-WebSocket-Key:")) == NULL) {
|
http_header_find_field_value(header, "Connection", "Upgrade") == NULL ||
|
||||||
|
(keyhdstart = http_header_find_field_value(header, "Sec-WebSocket-Key", NULL)) == NULL) {
|
||||||
fprintf(stderr, "HTTP Handshake: Missing required header fields");
|
fprintf(stderr, "HTTP Handshake: Missing required header fields");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
keyhdstart += 20;
|
|
||||||
for(; *keyhdstart == ' '; ++keyhdstart);
|
for(; *keyhdstart == ' '; ++keyhdstart);
|
||||||
keyhdend = keyhdstart;
|
keyhdend = keyhdstart;
|
||||||
for(; *keyhdend != '\r' && *keyhdend != ' '; ++keyhdend);
|
for(; *keyhdend != '\r' && *keyhdend != ' '; ++keyhdend);
|
||||||
|
|
|
@ -496,7 +496,7 @@ int update_reports(const char *host, const char *service)
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
if(argc < 2) {
|
if(argc < 3) {
|
||||||
std::cerr << "Usage: " << argv[0] << " HOST SERV" << std::endl;
|
std::cerr << "Usage: " << argv[0] << " HOST SERV" << std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,15 @@ extern "C" {
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <wslay/wslayver.h>
|
|
||||||
|
/*
|
||||||
|
* wslay/wslayver.h is generated from wslay/wslayver.h.in by
|
||||||
|
* configure. The projects which do not use autotools can set
|
||||||
|
* WSLAY_VERSION macro from outside to avoid to generating wslayver.h
|
||||||
|
*/
|
||||||
|
#ifndef WSLAY_VERSION
|
||||||
|
# include <wslay/wslayver.h>
|
||||||
|
#endif /* WSLAY_VERSION */
|
||||||
|
|
||||||
enum wslay_error {
|
enum wslay_error {
|
||||||
WSLAY_ERR_WANT_READ = -100,
|
WSLAY_ERR_WANT_READ = -100,
|
||||||
|
|
|
@ -135,6 +135,10 @@ static int wslay_event_byte_chunk_init
|
||||||
memset(*chunk, 0, sizeof(struct wslay_event_byte_chunk));
|
memset(*chunk, 0, sizeof(struct wslay_event_byte_chunk));
|
||||||
if(len) {
|
if(len) {
|
||||||
(*chunk)->data = (uint8_t*)malloc(len);
|
(*chunk)->data = (uint8_t*)malloc(len);
|
||||||
|
if((*chunk)->data == NULL) {
|
||||||
|
free(*chunk);
|
||||||
|
return WSLAY_ERR_NOMEM;
|
||||||
|
}
|
||||||
(*chunk)->data_length = len;
|
(*chunk)->data_length = len;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -37,7 +37,7 @@ int wslay_frame_context_init(wslay_frame_context_ptr *ctx,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
*ctx = (wslay_frame_context_ptr)malloc(sizeof(struct wslay_frame_context));
|
*ctx = (wslay_frame_context_ptr)malloc(sizeof(struct wslay_frame_context));
|
||||||
if(ctx == NULL) {
|
if(*ctx == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memset(*ctx, 0, sizeof(struct wslay_frame_context));
|
memset(*ctx, 0, sizeof(struct wslay_frame_context));
|
||||||
|
|
|
@ -40,10 +40,11 @@ struct wslay_stack* wslay_stack_new()
|
||||||
|
|
||||||
void wslay_stack_free(struct wslay_stack *stack)
|
void wslay_stack_free(struct wslay_stack *stack)
|
||||||
{
|
{
|
||||||
|
struct wslay_stack_cell *p;
|
||||||
if(!stack) {
|
if(!stack) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct wslay_stack_cell *p = stack->top;
|
p = stack->top;
|
||||||
while(p) {
|
while(p) {
|
||||||
struct wslay_stack_cell *next = p->next;
|
struct wslay_stack_cell *next = p->next;
|
||||||
free(p);
|
free(p);
|
||||||
|
|
Loading…
Reference in New Issue