From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.1 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE, SPF_PASS,USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BE392C10DCE for ; Fri, 6 Mar 2020 12:38:47 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 794D52073B for ; Fri, 6 Mar 2020 12:38:47 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="CtCc6G23" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 794D52073B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:36008 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jACFa-0003SZ-MH for qemu-devel@archiver.kernel.org; Fri, 06 Mar 2020 07:38:46 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:56384) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jACEk-0002eI-Fd for qemu-devel@nongnu.org; Fri, 06 Mar 2020 07:37:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jACEh-0007wA-LJ for qemu-devel@nongnu.org; Fri, 06 Mar 2020 07:37:53 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:48747 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1jACEh-0007uO-DM for qemu-devel@nongnu.org; Fri, 06 Mar 2020 07:37:51 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583498271; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HRc3/wEVrnsWDXDZIirGQ2jp4V7h8oBZ/PL8yoD87go=; b=CtCc6G23TrNeyY7548Q6SOWlZKFZfvl3cXqFGYZZX/8GXG6pKCAdOFiIa112i+Snv41QCc e1aNjsU08P0wGEUGCkoErybIXB/9RRTU5P/DV2s/lmvjDxQ5HMCyAelZr5fBDHzR+RjG+W +0p6A5r8qZioT3PSb25uEsHTxRwsdo8= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-367-_7d95CvdPGucnJ9ZXcs6sA-1; Fri, 06 Mar 2020 07:37:46 -0500 X-MC-Unique: _7d95CvdPGucnJ9ZXcs6sA-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 0471C800D50; Fri, 6 Mar 2020 12:37:45 +0000 (UTC) Received: from [10.3.117.177] (ovpn-117-177.phx2.redhat.com [10.3.117.177]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8BAC760BEC; Fri, 6 Mar 2020 12:37:38 +0000 (UTC) Subject: Re: [PATCH v8 01/10] error: auto propagated local_err To: Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org References: <20200306051536.27803-1-vsementsov@virtuozzo.com> <20200306051536.27803-2-vsementsov@virtuozzo.com> From: Eric Blake Organization: Red Hat, Inc. Message-ID: <41229b66-eedb-1c30-4849-a8076080117e@redhat.com> Date: Fri, 6 Mar 2020 06:37:37 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0 MIME-Version: 1.0 In-Reply-To: <20200306051536.27803-2-vsementsov@virtuozzo.com> Content-Language: en-US X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Stefano Stabellini , Michael Roth , qemu-block@nongnu.org, Paul Durrant , Laszlo Ersek , Christian Schoenebeck , Greg Kurz , armbru@redhat.com, Gerd Hoffmann , Stefan Hajnoczi , Anthony Perard , xen-devel@lists.xenproject.org, Max Reitz , =?UTF-8?Q?Philippe_Mathieu-Daud=c3=a9?= , Stefan Berger Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" On 3/5/20 11:15 PM, Vladimir Sementsov-Ogievskiy wrote: > Here is introduced ERRP_AUTO_PROPAGATE macro, to be used at start of > functions with an errp OUT parameter. As an aid to writing imperative-style commit messages, I like to prepend an implicit "Apply this patch to..." before the user's text, to see if things still make sense. By that construct, this paragraph might read better as: Introduce a new ERRP_AUTO_PROPAGATE macro, ... > > It has three goals: > > 1. Fix issue with error_fatal and error_prepend/error_append_hint: user > can't see this additional information, because exit() happens in > error_setg earlier than information is added. [Reported by Greg Kurz] > > 2. Fix issue with error_abort and error_propagate: when we wrap > error_abort by local_err+error_propagate, the resulting coredump will > refer to error_propagate and not to the place where error happened. > (the macro itself doesn't fix the issue, but it allows us to [3.] drop > the local_err+error_propagate pattern, which will definitely fix the > issue) [Reported by Kevin Wolf] > > 3. Drop local_err+error_propagate pattern, which is used to workaround > void functions with errp parameter, when caller wants to know resulting > status. (Note: actually these functions could be merely updated to > return int error code). > > To achieve these goals, later patches will add invocations > of this macro at the start of functions with either use > error_prepend/error_append_hint (solving 1) or which use > local_err+error_propagate to check errors, switching those > functions to use *errp instead (solving 2 and 3). > > Signed-off-by: Vladimir Sementsov-Ogievskiy > --- I have lots of grammar suggestions for the comments (and I know Markus is generally okay doing wording tweaks, so it may still end up different than my suggestions): > +++ b/include/qapi/error.h > @@ -15,6 +15,8 @@ > /* > * Error reporting system loosely patterned after Glib's GError. > * > + * = Deal with Error object = > + * > * Create an error: > * error_setg(&err, "situation normal, all fouled up"); > * > @@ -47,28 +49,88 @@ > * reporting it (primarily useful in testsuites): > * error_free_or_abort(&err); > * > - * Pass an existing error to the caller: > - * error_propagate(errp, err); > - * where Error **errp is a parameter, by convention the last one. > + * = Deal with Error ** function parameter = > * > - * Pass an existing error to the caller with the message modified: > - * error_propagate_prepend(errp, err); > + * Function may use error system to return errors. In this case function > + * defines Error **errp parameter, which should be the last one (except for > + * functions which varidic argument list), which has the following API: A function may use the error system to return errors. In this case, the function defines an Error **errp parameter, by convention the last one (with exceptions for functions using ... or va_list). > * > - * Avoid > - * error_propagate(errp, err); > - * error_prepend(errp, "Could not frobnicate '%s': ", name); > - * because this fails to prepend when @errp is &error_fatal. > + * Caller may pass as errp: The caller may then pass in the following errp values: > + * 1. &error_abort > + * This means abort on any error Any error will result in abort() > + * 2. &error_fatal > + * Exit with non-zero return code on error Any error will result in exit() with a non-zero status > + * 3. NULL > + * Ignore errors Any error will be ignored > + * 4. Another value 4. The address of a NULL-initialized Error *err > + * On error allocate error object and set errp Any error will populate errp with an error object > * > - * Create a new error and pass it to the caller: > - * error_setg(errp, "situation normal, all fouled up"); > + * Error API functions with Error ** (like error_setg) argument supports these > + * rules, so user functions just need to use them appropriately (read below). The following rules then implement the correct semantics desired by the caller. > * > - * Call a function and receive an error from it: > + * Simple pass error to the caller: Create a new error to pass to the caller: > + * error_setg(errp, "Some error"); You lost the fun wording in Markus' earlier example ("situation normal, all fouled up"). > + * > + * Subcall of another errp-based function, passing the error to the caller > + * f(..., errp); Calling another errp-based function: > + * > + * == Checking success of subcall == > + * > + * If function returns error code in addition to errp (which is recommended), If a function returns a value indicating an error in addition to setting errp (which is recommended), then > + * you don't need any additional code, just do: > + * int ret = f(..., errp); > + * if (ret < 0) { > + * ... handle error ... > + * return ret; > + * } > + * > + * If function returns nothing (which is not recommended API) and the only way > + * to check success is checking errp, we must care about cases [1-3] above. We > + * need to use macro ERRP_AUTO_PROPAGATE (see below for details) like this: If a function returns nothing (not recommended for new code), the only way to check success is by consulting errp; doing this safely requires the use of the ERRP_AUTO_PROPAGATE macro, like this: > + * > + * int our_func(..., Error **errp) { > + * ERRP_AUTO_PROPAGATE(); > + * ... > + * subcall(..., errp); > + * if (*errp) { > + * ... > + * return -ERRNO; do we want ERRNO capitalized here? > + * } > + * ... > + * } > + * > + * ERRP_AUTO_PROPAGATE cares about Error ** API, wraps original errp if needed, > + * so that it can be safely used (including dereferencing), and auto-propagates > + * error to original errp on function end. ERRP_AUTO_PROPAGATE takes care of wrapping the original errp as needed, so that the rest of the function can directly use errp (including dereferencing), where any errors will then be propagated on to the original errp when leaving the function. > + * > + * In some cases, we need to check result of subcall, but do not want to > + * propagate the Error object to our caller. In such cases we don't need > + * ERRP_AUTO_PROPAGATE, but just a local Error object: > + * > + * Receive an error and not pass it: > * Error *err = NULL; > - * foo(arg, &err); > + * subcall(arg, &err); > * if (err) { > * handle the error... > + * error_free(err); > * } > * > + * Note, that before ERRP_AUTO_PROPAGATE introduction the pattern above (with > + * error_propagate() instead of error_free()) was used to check and pass error > + * to the caller. Now this is DEPRECATED* (see below). Hmm - if we bulk-convert the entire tree, then there won't be any deprecated uses to be worth documenting. But if we do keep this paragraph: Note that older code that did not use ERRP_AUTO_PROPAGATE would instead need a local Err variable and the use of error_propagate() to properly handle all possible caller values of errp. > + * > + * Note also, that if you want to use error_append_hint/error_prepend or their > + * variants, you must use ERRP_AUTO_PROPAGATE too. Otherwise, in case of > + * error_fatal, you'll miss the chance to insert your additional information > + * into Error object. Note that any function that wants to modify an error object, such as by calling error_append_hint or error_prepend, must use ERRP_AUTO_PROPAGATE, in order for a caller's use of &error_fatal to see the additional information. > + * > + * In rare cases, we need to pass existing Error object to the caller by hand: > + * error_propagate(errp, err); > + * > + * Pass an existing error to the caller with the message modified: > + * error_propagate_prepend(errp, err); > + * > + * > * Call a function ignoring errors: > * foo(arg, NULL); > * > @@ -78,26 +140,6 @@ > * Call a function treating errors as fatal: > * foo(arg, &error_fatal); > * > - * Receive an error and pass it on to the caller: > - * Error *err = NULL; > - * foo(arg, &err); > - * if (err) { > - * handle the error... > - * error_propagate(errp, err); > - * } > - * where Error **errp is a parameter, by convention the last one. > - * > - * Do *not* "optimize" this to > - * foo(arg, errp); > - * if (*errp) { // WRONG! > - * handle the error... > - * } > - * because errp may be NULL! > - * > - * But when all you do with the error is pass it on, please use > - * foo(arg, errp); > - * for readability. > - * > * Receive and accumulate multiple errors (first one wins): > * Error *err = NULL, *local_err = NULL; > * foo(arg, &err); > @@ -114,6 +156,61 @@ > * handle the error... > * } > * because this may pass a non-null err to bar(). > + * > + * DEPRECATED* > + * Again, I'm not sure we need this section in the codebase if we do a bulk conversion. But moving it to the commit message is still useful. > + * The following pattern of receiving checking and passing the caller of the > + * error by hand is deprecated now: The following pattern of receiving, checking, and then forwarding an error to the caller by hand is now deprecated: > + * > + * Error *err = NULL; > + * foo(arg, &err); > + * if (err) { > + * handle the error... > + * error_propagate(errp, err); > + * } > + * > + * Instead, use ERRP_AUTO_PROPAGATE macro (defined below). Drop "(defined below)". > + * > + * The old pattern is deprecated because of two things: > + * > + * 1. Issue with error_abort and error_propagate: when we wrap error_abort by > + * local_err+error_propagate, the resulting coredump will refer to > + * error_propagate and not to the place where error happened. > + * > + * 2. A lot of extra code of the same pattern > + * > + * How to update old code to use ERRP_AUTO_PROPAGATE? > + * > + * All you need is to add ERRP_AUTO_PROPAGATE() invocation at function start, > + * than you may safely dereference errp to check errors and do not need any > + * additional local Error variables or calls to error_propagate(). > + * > + * Example: > + * > + * old code > + * > + * void fn(..., Error **errp) { > + * Error *err = NULL; > + * foo(arg, &err); > + * if (err) { > + * handle the error... > + * error_propagate(errp, err); > + * return; > + * } > + * ... > + * } > + * > + * updated code > + * > + * void fn(..., Error **errp) { > + * ERRP_AUTO_PROPAGATE(); > + * foo(arg, errp); > + * if (*errp) { > + * handle the error... > + * return; > + * } > + * ... > + * } Again, I'm thinking the above example is more useful in the commit message instead of permanently in the .h file. > */ > > #ifndef ERROR_H > @@ -322,6 +419,46 @@ void error_set_internal(Error **errp, > ErrorClass err_class, const char *fmt, ...) > GCC_FMT_ATTR(6, 7); > > +typedef struct ErrorPropagator { > + Error *local_err; > + Error **errp; > +} ErrorPropagator; > + > +static inline void error_propagator_cleanup(ErrorPropagator *prop) > +{ > + error_propagate(prop->errp, prop->local_err); > +} > + > +G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(ErrorPropagator, error_propagator_cleanup); > + > +/* > + * ERRP_AUTO_PROPAGATE > + * > + * This macro is created to be the first line of a function which use > + * Error **errp parameter to report error. It's needed only in cases where we > + * want to use error_prepend, error_append_hint or dereference *errp. It's > + * still safe (but useless) in other cases. This macro exists to assist with proper error handling in a function which uses an Error **errp parameter. It must be used as the first line of a function which modifies an error (with error_prepend, error_append_hint, or similar) or which wants to dereference *errp. It is still safe (but useless) to use in other functions. > + * > + * If errp is NULL or points to error_fatal, it is rewritten to point to a > + * local Error object, which will be automatically propagated to the original > + * errp on function exit (see error_propagator_cleanup). > + * > + * After invocation of this macro it is always safe to dereference errp > + * (as it's not NULL anymore) and to add information by error_prepend or > + * error_append_hint (as, if it was error_fatal, we swapped it with a > + * local_error to be propagated on cleanup). > + * > + * Note: we don't wrap the error_abort case, as we want resulting coredump > + * to point to the place where the error happened, not to error_propagate. > + */ > +#define ERRP_AUTO_PROPAGATE() \ > + g_auto(ErrorPropagator) _auto_errp_prop = {.errp = errp}; \ > + do { \ > + if (!errp || errp == &error_fatal) { \ > + errp = &_auto_errp_prop.local_err; \ > + } \ > + } while (0) > + > /* > * Special error destination to abort on error. > * See error_setg() and error_propagate() for details. > The macro itself looks correct. I'll leave it up to Markus how to handle the comment text, but you can add: Reviewed-by: Eric Blake -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.1 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE, SPF_PASS,USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6FFCBC10F00 for ; Fri, 6 Mar 2020 12:38:13 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 375792073B for ; Fri, 6 Mar 2020 12:38:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="BEc/0y5s" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 375792073B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jACEj-0005k5-VP; Fri, 06 Mar 2020 12:37:53 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jACEi-0005jp-G8 for xen-devel@lists.xenproject.org; Fri, 06 Mar 2020 12:37:52 +0000 X-Inumbo-ID: 4ad86a8e-5fa7-11ea-a7c0-12813bfff9fa Received: from us-smtp-delivery-1.mimecast.com (unknown [207.211.31.81]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTP id 4ad86a8e-5fa7-11ea-a7c0-12813bfff9fa; Fri, 06 Mar 2020 12:37:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583498270; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HRc3/wEVrnsWDXDZIirGQ2jp4V7h8oBZ/PL8yoD87go=; b=BEc/0y5sCc0UdNeqK6livH/Am0oZoS8jrA/Y8ERSFdnxM9rRTjZG3mXxiav07yDfR3NpWx eb+nNrS1pa3KqPYPuSr/RumBj8AfootxgaywQT/a8C8/h58NdhIgwq9W/g3FF1mHilng6R VV4DOCWZ4JwuB/5mZHN5nym2PtMP/p4= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-367-_7d95CvdPGucnJ9ZXcs6sA-1; Fri, 06 Mar 2020 07:37:46 -0500 X-MC-Unique: _7d95CvdPGucnJ9ZXcs6sA-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 0471C800D50; Fri, 6 Mar 2020 12:37:45 +0000 (UTC) Received: from [10.3.117.177] (ovpn-117-177.phx2.redhat.com [10.3.117.177]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8BAC760BEC; Fri, 6 Mar 2020 12:37:38 +0000 (UTC) To: Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org References: <20200306051536.27803-1-vsementsov@virtuozzo.com> <20200306051536.27803-2-vsementsov@virtuozzo.com> From: Eric Blake Organization: Red Hat, Inc. Message-ID: <41229b66-eedb-1c30-4849-a8076080117e@redhat.com> Date: Fri, 6 Mar 2020 06:37:37 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0 MIME-Version: 1.0 In-Reply-To: <20200306051536.27803-2-vsementsov@virtuozzo.com> Content-Language: en-US X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: Re: [Xen-devel] [PATCH v8 01/10] error: auto propagated local_err X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Stefano Stabellini , Michael Roth , qemu-block@nongnu.org, Paul Durrant , Laszlo Ersek , Christian Schoenebeck , Greg Kurz , armbru@redhat.com, Gerd Hoffmann , Stefan Hajnoczi , Anthony Perard , xen-devel@lists.xenproject.org, Max Reitz , =?UTF-8?Q?Philippe_Mathieu-Daud=c3=a9?= , Stefan Berger Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" T24gMy81LzIwIDExOjE1IFBNLCBWbGFkaW1pciBTZW1lbnRzb3YtT2dpZXZza2l5IHdyb3RlOgo+ IEhlcmUgaXMgaW50cm9kdWNlZCBFUlJQX0FVVE9fUFJPUEFHQVRFIG1hY3JvLCB0byBiZSB1c2Vk IGF0IHN0YXJ0IG9mCj4gZnVuY3Rpb25zIHdpdGggYW4gZXJycCBPVVQgcGFyYW1ldGVyLgoKQXMg YW4gYWlkIHRvIHdyaXRpbmcgaW1wZXJhdGl2ZS1zdHlsZSBjb21taXQgbWVzc2FnZXMsIEkgbGlr ZSB0byBwcmVwZW5kIAphbiBpbXBsaWNpdCAiQXBwbHkgdGhpcyBwYXRjaCB0by4uLiIgYmVmb3Jl IHRoZSB1c2VyJ3MgdGV4dCwgdG8gc2VlIGlmIAp0aGluZ3Mgc3RpbGwgbWFrZSBzZW5zZS4gIEJ5 IHRoYXQgY29uc3RydWN0LCB0aGlzIHBhcmFncmFwaCBtaWdodCByZWFkIApiZXR0ZXIgYXM6CgpJ bnRyb2R1Y2UgYSBuZXcgRVJSUF9BVVRPX1BST1BBR0FURSBtYWNybywgLi4uCgo+IAo+IEl0IGhh cyB0aHJlZSBnb2FsczoKPiAKPiAxLiBGaXggaXNzdWUgd2l0aCBlcnJvcl9mYXRhbCBhbmQgZXJy b3JfcHJlcGVuZC9lcnJvcl9hcHBlbmRfaGludDogdXNlcgo+IGNhbid0IHNlZSB0aGlzIGFkZGl0 aW9uYWwgaW5mb3JtYXRpb24sIGJlY2F1c2UgZXhpdCgpIGhhcHBlbnMgaW4KPiBlcnJvcl9zZXRn IGVhcmxpZXIgdGhhbiBpbmZvcm1hdGlvbiBpcyBhZGRlZC4gW1JlcG9ydGVkIGJ5IEdyZWcgS3Vy el0KPiAKPiAyLiBGaXggaXNzdWUgd2l0aCBlcnJvcl9hYm9ydCBhbmQgZXJyb3JfcHJvcGFnYXRl OiB3aGVuIHdlIHdyYXAKPiBlcnJvcl9hYm9ydCBieSBsb2NhbF9lcnIrZXJyb3JfcHJvcGFnYXRl LCB0aGUgcmVzdWx0aW5nIGNvcmVkdW1wIHdpbGwKPiByZWZlciB0byBlcnJvcl9wcm9wYWdhdGUg YW5kIG5vdCB0byB0aGUgcGxhY2Ugd2hlcmUgZXJyb3IgaGFwcGVuZWQuCj4gKHRoZSBtYWNybyBp dHNlbGYgZG9lc24ndCBmaXggdGhlIGlzc3VlLCBidXQgaXQgYWxsb3dzIHVzIHRvIFszLl0gZHJv cAo+IHRoZSBsb2NhbF9lcnIrZXJyb3JfcHJvcGFnYXRlIHBhdHRlcm4sIHdoaWNoIHdpbGwgZGVm aW5pdGVseSBmaXggdGhlCj4gaXNzdWUpIFtSZXBvcnRlZCBieSBLZXZpbiBXb2xmXQo+IAo+IDMu IERyb3AgbG9jYWxfZXJyK2Vycm9yX3Byb3BhZ2F0ZSBwYXR0ZXJuLCB3aGljaCBpcyB1c2VkIHRv IHdvcmthcm91bmQKPiB2b2lkIGZ1bmN0aW9ucyB3aXRoIGVycnAgcGFyYW1ldGVyLCB3aGVuIGNh bGxlciB3YW50cyB0byBrbm93IHJlc3VsdGluZwo+IHN0YXR1cy4gKE5vdGU6IGFjdHVhbGx5IHRo ZXNlIGZ1bmN0aW9ucyBjb3VsZCBiZSBtZXJlbHkgdXBkYXRlZCB0bwo+IHJldHVybiBpbnQgZXJy b3IgY29kZSkuCj4gCj4gVG8gYWNoaWV2ZSB0aGVzZSBnb2FscywgbGF0ZXIgcGF0Y2hlcyB3aWxs IGFkZCBpbnZvY2F0aW9ucwo+IG9mIHRoaXMgbWFjcm8gYXQgdGhlIHN0YXJ0IG9mIGZ1bmN0aW9u cyB3aXRoIGVpdGhlciB1c2UKPiBlcnJvcl9wcmVwZW5kL2Vycm9yX2FwcGVuZF9oaW50IChzb2x2 aW5nIDEpIG9yIHdoaWNoIHVzZQo+IGxvY2FsX2VycitlcnJvcl9wcm9wYWdhdGUgdG8gY2hlY2sg ZXJyb3JzLCBzd2l0Y2hpbmcgdGhvc2UKPiBmdW5jdGlvbnMgdG8gdXNlICplcnJwIGluc3RlYWQg KHNvbHZpbmcgMiBhbmQgMykuCj4gCj4gU2lnbmVkLW9mZi1ieTogVmxhZGltaXIgU2VtZW50c292 LU9naWV2c2tpeSA8dnNlbWVudHNvdkB2aXJ0dW96em8uY29tPgo+IC0tLQoKSSBoYXZlIGxvdHMg b2YgZ3JhbW1hciBzdWdnZXN0aW9ucyBmb3IgdGhlIGNvbW1lbnRzIChhbmQgSSBrbm93IE1hcmt1 cyAKaXMgZ2VuZXJhbGx5IG9rYXkgZG9pbmcgd29yZGluZyB0d2Vha3MsIHNvIGl0IG1heSBzdGls bCBlbmQgdXAgZGlmZmVyZW50IAp0aGFuIG15IHN1Z2dlc3Rpb25zKToKCj4gKysrIGIvaW5jbHVk ZS9xYXBpL2Vycm9yLmgKPiBAQCAtMTUsNiArMTUsOCBAQAo+ICAgLyoKPiAgICAqIEVycm9yIHJl cG9ydGluZyBzeXN0ZW0gbG9vc2VseSBwYXR0ZXJuZWQgYWZ0ZXIgR2xpYidzIEdFcnJvci4KPiAg ICAqCj4gKyAqID0gRGVhbCB3aXRoIEVycm9yIG9iamVjdCA9Cj4gKyAqCj4gICAgKiBDcmVhdGUg YW4gZXJyb3I6Cj4gICAgKiAgICAgZXJyb3Jfc2V0ZygmZXJyLCAic2l0dWF0aW9uIG5vcm1hbCwg YWxsIGZvdWxlZCB1cCIpOwo+ICAgICoKPiBAQCAtNDcsMjggKzQ5LDg4IEBACj4gICAgKiByZXBv cnRpbmcgaXQgKHByaW1hcmlseSB1c2VmdWwgaW4gdGVzdHN1aXRlcyk6Cj4gICAgKiAgICAgZXJy b3JfZnJlZV9vcl9hYm9ydCgmZXJyKTsKPiAgICAqCj4gLSAqIFBhc3MgYW4gZXhpc3RpbmcgZXJy b3IgdG8gdGhlIGNhbGxlcjoKPiAtICogICAgIGVycm9yX3Byb3BhZ2F0ZShlcnJwLCBlcnIpOwo+ IC0gKiB3aGVyZSBFcnJvciAqKmVycnAgaXMgYSBwYXJhbWV0ZXIsIGJ5IGNvbnZlbnRpb24gdGhl IGxhc3Qgb25lLgo+ICsgKiA9IERlYWwgd2l0aCBFcnJvciAqKiBmdW5jdGlvbiBwYXJhbWV0ZXIg PQo+ICAgICoKPiAtICogUGFzcyBhbiBleGlzdGluZyBlcnJvciB0byB0aGUgY2FsbGVyIHdpdGgg dGhlIG1lc3NhZ2UgbW9kaWZpZWQ6Cj4gLSAqICAgICBlcnJvcl9wcm9wYWdhdGVfcHJlcGVuZChl cnJwLCBlcnIpOwo+ICsgKiBGdW5jdGlvbiBtYXkgdXNlIGVycm9yIHN5c3RlbSB0byByZXR1cm4g ZXJyb3JzLiBJbiB0aGlzIGNhc2UgZnVuY3Rpb24KPiArICogZGVmaW5lcyBFcnJvciAqKmVycnAg cGFyYW1ldGVyLCB3aGljaCBzaG91bGQgYmUgdGhlIGxhc3Qgb25lIChleGNlcHQgZm9yCj4gKyAq IGZ1bmN0aW9ucyB3aGljaCB2YXJpZGljIGFyZ3VtZW50IGxpc3QpLCB3aGljaCBoYXMgdGhlIGZv bGxvd2luZyBBUEk6CgpBIGZ1bmN0aW9uIG1heSB1c2UgdGhlIGVycm9yIHN5c3RlbSB0byByZXR1 cm4gZXJyb3JzLiAgSW4gdGhpcyBjYXNlLCB0aGUgCmZ1bmN0aW9uIGRlZmluZXMgYW4gRXJyb3Ig KiplcnJwIHBhcmFtZXRlciwgYnkgY29udmVudGlvbiB0aGUgbGFzdCBvbmUgCih3aXRoIGV4Y2Vw dGlvbnMgZm9yIGZ1bmN0aW9ucyB1c2luZyAuLi4gb3IgdmFfbGlzdCkuCgo+ICAgICoKPiAtICog QXZvaWQKPiAtICogICAgIGVycm9yX3Byb3BhZ2F0ZShlcnJwLCBlcnIpOwo+IC0gKiAgICAgZXJy b3JfcHJlcGVuZChlcnJwLCAiQ291bGQgbm90IGZyb2JuaWNhdGUgJyVzJzogIiwgbmFtZSk7Cj4g LSAqIGJlY2F1c2UgdGhpcyBmYWlscyB0byBwcmVwZW5kIHdoZW4gQGVycnAgaXMgJmVycm9yX2Zh dGFsLgo+ICsgKiBDYWxsZXIgbWF5IHBhc3MgYXMgZXJycDoKClRoZSBjYWxsZXIgbWF5IHRoZW4g cGFzcyBpbiB0aGUgZm9sbG93aW5nIGVycnAgdmFsdWVzOgoKPiArICogMS4gJmVycm9yX2Fib3J0 Cj4gKyAqICAgIFRoaXMgbWVhbnMgYWJvcnQgb24gYW55IGVycm9yCgpBbnkgZXJyb3Igd2lsbCBy ZXN1bHQgaW4gYWJvcnQoKQoKPiArICogMi4gJmVycm9yX2ZhdGFsCj4gKyAqICAgIEV4aXQgd2l0 aCBub24temVybyByZXR1cm4gY29kZSBvbiBlcnJvcgoKQW55IGVycm9yIHdpbGwgcmVzdWx0IGlu IGV4aXQoKSB3aXRoIGEgbm9uLXplcm8gc3RhdHVzCgo+ICsgKiAzLiBOVUxMCj4gKyAqICAgIEln bm9yZSBlcnJvcnMKCkFueSBlcnJvciB3aWxsIGJlIGlnbm9yZWQKCj4gKyAqIDQuIEFub3RoZXIg dmFsdWUKCjQuIFRoZSBhZGRyZXNzIG9mIGEgTlVMTC1pbml0aWFsaXplZCBFcnJvciAqZXJyCgo+ ICsgKiAgICBPbiBlcnJvciBhbGxvY2F0ZSBlcnJvciBvYmplY3QgYW5kIHNldCBlcnJwCgpBbnkg ZXJyb3Igd2lsbCBwb3B1bGF0ZSBlcnJwIHdpdGggYW4gZXJyb3Igb2JqZWN0Cgo+ICAgICoKPiAt ICogQ3JlYXRlIGEgbmV3IGVycm9yIGFuZCBwYXNzIGl0IHRvIHRoZSBjYWxsZXI6Cj4gLSAqICAg ICBlcnJvcl9zZXRnKGVycnAsICJzaXR1YXRpb24gbm9ybWFsLCBhbGwgZm91bGVkIHVwIik7Cj4g KyAqIEVycm9yIEFQSSBmdW5jdGlvbnMgd2l0aCBFcnJvciAqKiAobGlrZSBlcnJvcl9zZXRnKSBh cmd1bWVudCBzdXBwb3J0cyB0aGVzZQo+ICsgKiBydWxlcywgc28gdXNlciBmdW5jdGlvbnMganVz dCBuZWVkIHRvIHVzZSB0aGVtIGFwcHJvcHJpYXRlbHkgKHJlYWQgYmVsb3cpLgoKVGhlIGZvbGxv d2luZyBydWxlcyB0aGVuIGltcGxlbWVudCB0aGUgY29ycmVjdCBzZW1hbnRpY3MgZGVzaXJlZCBi eSB0aGUgCmNhbGxlci4KCj4gICAgKgo+IC0gKiBDYWxsIGEgZnVuY3Rpb24gYW5kIHJlY2VpdmUg YW4gZXJyb3IgZnJvbSBpdDoKPiArICogU2ltcGxlIHBhc3MgZXJyb3IgdG8gdGhlIGNhbGxlcjoK CkNyZWF0ZSBhIG5ldyBlcnJvciB0byBwYXNzIHRvIHRoZSBjYWxsZXI6Cgo+ICsgKiAgICAgZXJy b3Jfc2V0ZyhlcnJwLCAiU29tZSBlcnJvciIpOwoKWW91IGxvc3QgdGhlIGZ1biB3b3JkaW5nIGlu IE1hcmt1cycgZWFybGllciBleGFtcGxlICgic2l0dWF0aW9uIG5vcm1hbCwgCmFsbCBmb3VsZWQg dXAiKS4KCj4gKyAqCj4gKyAqIFN1YmNhbGwgb2YgYW5vdGhlciBlcnJwLWJhc2VkIGZ1bmN0aW9u LCBwYXNzaW5nIHRoZSBlcnJvciB0byB0aGUgY2FsbGVyCj4gKyAqICAgICBmKC4uLiwgZXJycCk7 CgpDYWxsaW5nIGFub3RoZXIgZXJycC1iYXNlZCBmdW5jdGlvbjoKCj4gKyAqCj4gKyAqID09IENo ZWNraW5nIHN1Y2Nlc3Mgb2Ygc3ViY2FsbCA9PQo+ICsgKgo+ICsgKiBJZiBmdW5jdGlvbiByZXR1 cm5zIGVycm9yIGNvZGUgaW4gYWRkaXRpb24gdG8gZXJycCAod2hpY2ggaXMgcmVjb21tZW5kZWQp LAoKSWYgYSBmdW5jdGlvbiByZXR1cm5zIGEgdmFsdWUgaW5kaWNhdGluZyBhbiBlcnJvciBpbiBh ZGRpdGlvbiB0byBzZXR0aW5nIAplcnJwICh3aGljaCBpcyByZWNvbW1lbmRlZCksIHRoZW4KCj4g KyAqIHlvdSBkb24ndCBuZWVkIGFueSBhZGRpdGlvbmFsIGNvZGUsIGp1c3QgZG86Cj4gKyAqICAg ICBpbnQgcmV0ID0gZiguLi4sIGVycnApOwo+ICsgKiAgICAgaWYgKHJldCA8IDApIHsKPiArICog ICAgICAgICAuLi4gaGFuZGxlIGVycm9yIC4uLgo+ICsgKiAgICAgICAgIHJldHVybiByZXQ7Cj4g KyAqICAgICB9Cj4gKyAqCj4gKyAqIElmIGZ1bmN0aW9uIHJldHVybnMgbm90aGluZyAod2hpY2gg aXMgbm90IHJlY29tbWVuZGVkIEFQSSkgYW5kIHRoZSBvbmx5IHdheQo+ICsgKiB0byBjaGVjayBz dWNjZXNzIGlzIGNoZWNraW5nIGVycnAsIHdlIG11c3QgY2FyZSBhYm91dCBjYXNlcyBbMS0zXSBh Ym92ZS4gV2UKPiArICogbmVlZCB0byB1c2UgbWFjcm8gRVJSUF9BVVRPX1BST1BBR0FURSAoc2Vl IGJlbG93IGZvciBkZXRhaWxzKSBsaWtlIHRoaXM6CgpJZiBhIGZ1bmN0aW9uIHJldHVybnMgbm90 aGluZyAobm90IHJlY29tbWVuZGVkIGZvciBuZXcgY29kZSksIHRoZSBvbmx5IAp3YXkgdG8gY2hl Y2sgc3VjY2VzcyBpcyBieSBjb25zdWx0aW5nIGVycnA7IGRvaW5nIHRoaXMgc2FmZWx5IHJlcXVp cmVzIAp0aGUgdXNlIG9mIHRoZSBFUlJQX0FVVE9fUFJPUEFHQVRFIG1hY3JvLCBsaWtlIHRoaXM6 CgoKPiArICoKPiArICogICAgIGludCBvdXJfZnVuYyguLi4sIEVycm9yICoqZXJycCkgewo+ICsg KiAgICAgICAgIEVSUlBfQVVUT19QUk9QQUdBVEUoKTsKPiArICogICAgICAgICAuLi4KPiArICog ICAgICAgICBzdWJjYWxsKC4uLiwgZXJycCk7Cj4gKyAqICAgICAgICAgaWYgKCplcnJwKSB7Cj4g KyAqICAgICAgICAgICAgIC4uLgo+ICsgKiAgICAgICAgICAgICByZXR1cm4gLUVSUk5POwoKZG8g d2Ugd2FudCBFUlJOTyBjYXBpdGFsaXplZCBoZXJlPwoKPiArICogICAgICAgICB9Cj4gKyAqICAg ICAgICAgLi4uCj4gKyAqICAgICB9Cj4gKyAqCj4gKyAqIEVSUlBfQVVUT19QUk9QQUdBVEUgY2Fy ZXMgYWJvdXQgRXJyb3IgKiogQVBJLCB3cmFwcyBvcmlnaW5hbCBlcnJwIGlmIG5lZWRlZCwKPiAr ICogc28gdGhhdCBpdCBjYW4gYmUgc2FmZWx5IHVzZWQgKGluY2x1ZGluZyBkZXJlZmVyZW5jaW5n KSwgYW5kIGF1dG8tcHJvcGFnYXRlcwo+ICsgKiBlcnJvciB0byBvcmlnaW5hbCBlcnJwIG9uIGZ1 bmN0aW9uIGVuZC4KCkVSUlBfQVVUT19QUk9QQUdBVEUgdGFrZXMgY2FyZSBvZiB3cmFwcGluZyB0 aGUgb3JpZ2luYWwgZXJycCBhcyBuZWVkZWQsIApzbyB0aGF0IHRoZSByZXN0IG9mIHRoZSBmdW5j dGlvbiBjYW4gZGlyZWN0bHkgdXNlIGVycnAgKGluY2x1ZGluZyAKZGVyZWZlcmVuY2luZyksIHdo ZXJlIGFueSBlcnJvcnMgd2lsbCB0aGVuIGJlIHByb3BhZ2F0ZWQgb24gdG8gdGhlIApvcmlnaW5h bCBlcnJwIHdoZW4gbGVhdmluZyB0aGUgZnVuY3Rpb24uCgo+ICsgKgo+ICsgKiBJbiBzb21lIGNh c2VzLCB3ZSBuZWVkIHRvIGNoZWNrIHJlc3VsdCBvZiBzdWJjYWxsLCBidXQgZG8gbm90IHdhbnQg dG8KPiArICogcHJvcGFnYXRlIHRoZSBFcnJvciBvYmplY3QgdG8gb3VyIGNhbGxlci4gSW4gc3Vj aCBjYXNlcyB3ZSBkb24ndCBuZWVkCj4gKyAqIEVSUlBfQVVUT19QUk9QQUdBVEUsIGJ1dCBqdXN0 IGEgbG9jYWwgRXJyb3Igb2JqZWN0Ogo+ICsgKgo+ICsgKiBSZWNlaXZlIGFuIGVycm9yIGFuZCBu b3QgcGFzcyBpdDoKPiAgICAqICAgICBFcnJvciAqZXJyID0gTlVMTDsKPiAtICogICAgIGZvbyhh cmcsICZlcnIpOwo+ICsgKiAgICAgc3ViY2FsbChhcmcsICZlcnIpOwo+ICAgICogICAgIGlmIChl cnIpIHsKPiAgICAqICAgICAgICAgaGFuZGxlIHRoZSBlcnJvci4uLgo+ICsgKiAgICAgICAgIGVy cm9yX2ZyZWUoZXJyKTsKPiAgICAqICAgICB9Cj4gICAgKgo+ICsgKiBOb3RlLCB0aGF0IGJlZm9y ZSBFUlJQX0FVVE9fUFJPUEFHQVRFIGludHJvZHVjdGlvbiB0aGUgcGF0dGVybiBhYm92ZSAod2l0 aAo+ICsgKiBlcnJvcl9wcm9wYWdhdGUoKSBpbnN0ZWFkIG9mIGVycm9yX2ZyZWUoKSkgd2FzIHVz ZWQgdG8gY2hlY2sgYW5kIHBhc3MgZXJyb3IKPiArICogdG8gdGhlIGNhbGxlci4gTm93IHRoaXMg aXMgREVQUkVDQVRFRCogKHNlZSBiZWxvdykuCgpIbW0gLSBpZiB3ZSBidWxrLWNvbnZlcnQgdGhl IGVudGlyZSB0cmVlLCB0aGVuIHRoZXJlIHdvbid0IGJlIGFueSAKZGVwcmVjYXRlZCB1c2VzIHRv IGJlIHdvcnRoIGRvY3VtZW50aW5nLiAgQnV0IGlmIHdlIGRvIGtlZXAgdGhpcyBwYXJhZ3JhcGg6 CgpOb3RlIHRoYXQgb2xkZXIgY29kZSB0aGF0IGRpZCBub3QgdXNlIEVSUlBfQVVUT19QUk9QQUdB VEUgd291bGQgaW5zdGVhZCAKbmVlZCBhIGxvY2FsIEVyciB2YXJpYWJsZSBhbmQgdGhlIHVzZSBv ZiBlcnJvcl9wcm9wYWdhdGUoKSB0byBwcm9wZXJseSAKaGFuZGxlIGFsbCBwb3NzaWJsZSBjYWxs ZXIgdmFsdWVzIG9mIGVycnAuCgo+ICsgKgo+ICsgKiBOb3RlIGFsc28sIHRoYXQgaWYgeW91IHdh bnQgdG8gdXNlIGVycm9yX2FwcGVuZF9oaW50L2Vycm9yX3ByZXBlbmQgb3IgdGhlaXIKPiArICog dmFyaWFudHMsIHlvdSBtdXN0IHVzZSBFUlJQX0FVVE9fUFJPUEFHQVRFIHRvby4gT3RoZXJ3aXNl LCBpbiBjYXNlIG9mCj4gKyAqIGVycm9yX2ZhdGFsLCB5b3UnbGwgbWlzcyB0aGUgY2hhbmNlIHRv IGluc2VydCB5b3VyIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KPiArICogaW50byBFcnJvciBvYmpl Y3QuCgpOb3RlIHRoYXQgYW55IGZ1bmN0aW9uIHRoYXQgd2FudHMgdG8gbW9kaWZ5IGFuIGVycm9y IG9iamVjdCwgc3VjaCBhcyBieSAKY2FsbGluZyBlcnJvcl9hcHBlbmRfaGludCBvciBlcnJvcl9w cmVwZW5kLCBtdXN0IHVzZSAKRVJSUF9BVVRPX1BST1BBR0FURSwgaW4gb3JkZXIgZm9yIGEgY2Fs bGVyJ3MgdXNlIG9mICZlcnJvcl9mYXRhbCB0byBzZWUgCnRoZSBhZGRpdGlvbmFsIGluZm9ybWF0 aW9uLgoKPiArICoKPiArICogSW4gcmFyZSBjYXNlcywgd2UgbmVlZCB0byBwYXNzIGV4aXN0aW5n IEVycm9yIG9iamVjdCB0byB0aGUgY2FsbGVyIGJ5IGhhbmQ6Cj4gKyAqICAgICBlcnJvcl9wcm9w YWdhdGUoZXJycCwgZXJyKTsKPiArICoKPiArICogUGFzcyBhbiBleGlzdGluZyBlcnJvciB0byB0 aGUgY2FsbGVyIHdpdGggdGhlIG1lc3NhZ2UgbW9kaWZpZWQ6Cj4gKyAqICAgICBlcnJvcl9wcm9w YWdhdGVfcHJlcGVuZChlcnJwLCBlcnIpOwo+ICsgKgo+ICsgKgo+ICAgICogQ2FsbCBhIGZ1bmN0 aW9uIGlnbm9yaW5nIGVycm9yczoKPiAgICAqICAgICBmb28oYXJnLCBOVUxMKTsKPiAgICAqCj4g QEAgLTc4LDI2ICsxNDAsNiBAQAo+ICAgICogQ2FsbCBhIGZ1bmN0aW9uIHRyZWF0aW5nIGVycm9y cyBhcyBmYXRhbDoKPiAgICAqICAgICBmb28oYXJnLCAmZXJyb3JfZmF0YWwpOwo+ICAgICoKPiAt ICogUmVjZWl2ZSBhbiBlcnJvciBhbmQgcGFzcyBpdCBvbiB0byB0aGUgY2FsbGVyOgo+IC0gKiAg ICAgRXJyb3IgKmVyciA9IE5VTEw7Cj4gLSAqICAgICBmb28oYXJnLCAmZXJyKTsKPiAtICogICAg IGlmIChlcnIpIHsKPiAtICogICAgICAgICBoYW5kbGUgdGhlIGVycm9yLi4uCj4gLSAqICAgICAg ICAgZXJyb3JfcHJvcGFnYXRlKGVycnAsIGVycik7Cj4gLSAqICAgICB9Cj4gLSAqIHdoZXJlIEVy cm9yICoqZXJycCBpcyBhIHBhcmFtZXRlciwgYnkgY29udmVudGlvbiB0aGUgbGFzdCBvbmUuCj4g LSAqCj4gLSAqIERvICpub3QqICJvcHRpbWl6ZSIgdGhpcyB0bwo+IC0gKiAgICAgZm9vKGFyZywg ZXJycCk7Cj4gLSAqICAgICBpZiAoKmVycnApIHsgLy8gV1JPTkchCj4gLSAqICAgICAgICAgaGFu ZGxlIHRoZSBlcnJvci4uLgo+IC0gKiAgICAgfQo+IC0gKiBiZWNhdXNlIGVycnAgbWF5IGJlIE5V TEwhCj4gLSAqCj4gLSAqIEJ1dCB3aGVuIGFsbCB5b3UgZG8gd2l0aCB0aGUgZXJyb3IgaXMgcGFz cyBpdCBvbiwgcGxlYXNlIHVzZQo+IC0gKiAgICAgZm9vKGFyZywgZXJycCk7Cj4gLSAqIGZvciBy ZWFkYWJpbGl0eS4KPiAtICoKPiAgICAqIFJlY2VpdmUgYW5kIGFjY3VtdWxhdGUgbXVsdGlwbGUg ZXJyb3JzIChmaXJzdCBvbmUgd2lucyk6Cj4gICAgKiAgICAgRXJyb3IgKmVyciA9IE5VTEwsICps b2NhbF9lcnIgPSBOVUxMOwo+ICAgICogICAgIGZvbyhhcmcsICZlcnIpOwo+IEBAIC0xMTQsNiAr MTU2LDYxIEBACj4gICAgKiAgICAgICAgIGhhbmRsZSB0aGUgZXJyb3IuLi4KPiAgICAqICAgICB9 Cj4gICAgKiBiZWNhdXNlIHRoaXMgbWF5IHBhc3MgYSBub24tbnVsbCBlcnIgdG8gYmFyKCkuCj4g KyAqCj4gKyAqIERFUFJFQ0FURUQqCj4gKyAqCgpBZ2FpbiwgSSdtIG5vdCBzdXJlIHdlIG5lZWQg dGhpcyBzZWN0aW9uIGluIHRoZSBjb2RlYmFzZSBpZiB3ZSBkbyBhIGJ1bGsgCmNvbnZlcnNpb24u ICBCdXQgbW92aW5nIGl0IHRvIHRoZSBjb21taXQgbWVzc2FnZSBpcyBzdGlsbCB1c2VmdWwuCgo+ ICsgKiBUaGUgZm9sbG93aW5nIHBhdHRlcm4gb2YgcmVjZWl2aW5nIGNoZWNraW5nIGFuZCBwYXNz aW5nIHRoZSBjYWxsZXIgb2YgdGhlCj4gKyAqIGVycm9yIGJ5IGhhbmQgaXMgZGVwcmVjYXRlZCBu b3c6CgpUaGUgZm9sbG93aW5nIHBhdHRlcm4gb2YgcmVjZWl2aW5nLCBjaGVja2luZywgYW5kIHRo ZW4gZm9yd2FyZGluZyBhbiAKZXJyb3IgdG8gdGhlIGNhbGxlciBieSBoYW5kIGlzIG5vdyBkZXBy ZWNhdGVkOgoKPiArICoKPiArICogICAgIEVycm9yICplcnIgPSBOVUxMOwo+ICsgKiAgICAgZm9v KGFyZywgJmVycik7Cj4gKyAqICAgICBpZiAoZXJyKSB7Cj4gKyAqICAgICAgICAgaGFuZGxlIHRo ZSBlcnJvci4uLgo+ICsgKiAgICAgICAgIGVycm9yX3Byb3BhZ2F0ZShlcnJwLCBlcnIpOwo+ICsg KiAgICAgfQo+ICsgKgo+ICsgKiBJbnN0ZWFkLCB1c2UgRVJSUF9BVVRPX1BST1BBR0FURSBtYWNy byAoZGVmaW5lZCBiZWxvdykuCgpEcm9wICIoZGVmaW5lZCBiZWxvdykiLgoKPiArICoKPiArICog VGhlIG9sZCBwYXR0ZXJuIGlzIGRlcHJlY2F0ZWQgYmVjYXVzZSBvZiB0d28gdGhpbmdzOgo+ICsg Kgo+ICsgKiAxLiBJc3N1ZSB3aXRoIGVycm9yX2Fib3J0IGFuZCBlcnJvcl9wcm9wYWdhdGU6IHdo ZW4gd2Ugd3JhcCBlcnJvcl9hYm9ydCBieQo+ICsgKiBsb2NhbF9lcnIrZXJyb3JfcHJvcGFnYXRl LCB0aGUgcmVzdWx0aW5nIGNvcmVkdW1wIHdpbGwgcmVmZXIgdG8KPiArICogZXJyb3JfcHJvcGFn YXRlIGFuZCBub3QgdG8gdGhlIHBsYWNlIHdoZXJlIGVycm9yIGhhcHBlbmVkLgo+ICsgKgo+ICsg KiAyLiBBIGxvdCBvZiBleHRyYSBjb2RlIG9mIHRoZSBzYW1lIHBhdHRlcm4KPiArICoKPiArICog SG93IHRvIHVwZGF0ZSBvbGQgY29kZSB0byB1c2UgRVJSUF9BVVRPX1BST1BBR0FURT8KPiArICoK PiArICogQWxsIHlvdSBuZWVkIGlzIHRvIGFkZCBFUlJQX0FVVE9fUFJPUEFHQVRFKCkgaW52b2Nh dGlvbiBhdCBmdW5jdGlvbiBzdGFydCwKPiArICogdGhhbiB5b3UgbWF5IHNhZmVseSBkZXJlZmVy ZW5jZSBlcnJwIHRvIGNoZWNrIGVycm9ycyBhbmQgZG8gbm90IG5lZWQgYW55Cj4gKyAqIGFkZGl0 aW9uYWwgbG9jYWwgRXJyb3IgdmFyaWFibGVzIG9yIGNhbGxzIHRvIGVycm9yX3Byb3BhZ2F0ZSgp Lgo+ICsgKgo+ICsgKiBFeGFtcGxlOgo+ICsgKgo+ICsgKiBvbGQgY29kZQo+ICsgKgo+ICsgKiAg ICAgdm9pZCBmbiguLi4sIEVycm9yICoqZXJycCkgewo+ICsgKiAgICAgICAgIEVycm9yICplcnIg PSBOVUxMOwo+ICsgKiAgICAgICAgIGZvbyhhcmcsICZlcnIpOwo+ICsgKiAgICAgICAgIGlmIChl cnIpIHsKPiArICogICAgICAgICAgICAgaGFuZGxlIHRoZSBlcnJvci4uLgo+ICsgKiAgICAgICAg ICAgICBlcnJvcl9wcm9wYWdhdGUoZXJycCwgZXJyKTsKPiArICogICAgICAgICAgICAgcmV0dXJu Owo+ICsgKiAgICAgICAgIH0KPiArICogICAgICAgICAuLi4KPiArICogICAgIH0KPiArICoKPiAr ICogdXBkYXRlZCBjb2RlCj4gKyAqCj4gKyAqICAgICB2b2lkIGZuKC4uLiwgRXJyb3IgKiplcnJw KSB7Cj4gKyAqICAgICAgICAgRVJSUF9BVVRPX1BST1BBR0FURSgpOwo+ICsgKiAgICAgICAgIGZv byhhcmcsIGVycnApOwo+ICsgKiAgICAgICAgIGlmICgqZXJycCkgewo+ICsgKiAgICAgICAgICAg ICBoYW5kbGUgdGhlIGVycm9yLi4uCj4gKyAqICAgICAgICAgICAgIHJldHVybjsKPiArICogICAg ICAgICB9Cj4gKyAqICAgICAgICAgLi4uCj4gKyAqICAgICB9CgpBZ2FpbiwgSSdtIHRoaW5raW5n IHRoZSBhYm92ZSBleGFtcGxlIGlzIG1vcmUgdXNlZnVsIGluIHRoZSBjb21taXQgCm1lc3NhZ2Ug aW5zdGVhZCBvZiBwZXJtYW5lbnRseSBpbiB0aGUgLmggZmlsZS4KCj4gICAgKi8KPiAgIAo+ICAg I2lmbmRlZiBFUlJPUl9ICj4gQEAgLTMyMiw2ICs0MTksNDYgQEAgdm9pZCBlcnJvcl9zZXRfaW50 ZXJuYWwoRXJyb3IgKiplcnJwLAo+ICAgICAgICAgICAgICAgICAgICAgICAgICAgRXJyb3JDbGFz cyBlcnJfY2xhc3MsIGNvbnN0IGNoYXIgKmZtdCwgLi4uKQo+ICAgICAgIEdDQ19GTVRfQVRUUig2 LCA3KTsKPiAgIAo+ICt0eXBlZGVmIHN0cnVjdCBFcnJvclByb3BhZ2F0b3Igewo+ICsgICAgRXJy b3IgKmxvY2FsX2VycjsKPiArICAgIEVycm9yICoqZXJycDsKPiArfSBFcnJvclByb3BhZ2F0b3I7 Cj4gKwo+ICtzdGF0aWMgaW5saW5lIHZvaWQgZXJyb3JfcHJvcGFnYXRvcl9jbGVhbnVwKEVycm9y UHJvcGFnYXRvciAqcHJvcCkKPiArewo+ICsgICAgZXJyb3JfcHJvcGFnYXRlKHByb3AtPmVycnAs IHByb3AtPmxvY2FsX2Vycik7Cj4gK30KPiArCj4gK0dfREVGSU5FX0FVVE9fQ0xFQU5VUF9DTEVB Ul9GVU5DKEVycm9yUHJvcGFnYXRvciwgZXJyb3JfcHJvcGFnYXRvcl9jbGVhbnVwKTsKPiArCj4g Ky8qCj4gKyAqIEVSUlBfQVVUT19QUk9QQUdBVEUKPiArICoKPiArICogVGhpcyBtYWNybyBpcyBj cmVhdGVkIHRvIGJlIHRoZSBmaXJzdCBsaW5lIG9mIGEgZnVuY3Rpb24gd2hpY2ggdXNlCj4gKyAq IEVycm9yICoqZXJycCBwYXJhbWV0ZXIgdG8gcmVwb3J0IGVycm9yLiBJdCdzIG5lZWRlZCBvbmx5 IGluIGNhc2VzIHdoZXJlIHdlCj4gKyAqIHdhbnQgdG8gdXNlIGVycm9yX3ByZXBlbmQsIGVycm9y X2FwcGVuZF9oaW50IG9yIGRlcmVmZXJlbmNlICplcnJwLiBJdCdzCj4gKyAqIHN0aWxsIHNhZmUg KGJ1dCB1c2VsZXNzKSBpbiBvdGhlciBjYXNlcy4KClRoaXMgbWFjcm8gZXhpc3RzIHRvIGFzc2lz dCB3aXRoIHByb3BlciBlcnJvciBoYW5kbGluZyBpbiBhIGZ1bmN0aW9uIAp3aGljaCB1c2VzIGFu IEVycm9yICoqZXJycCBwYXJhbWV0ZXIuICBJdCBtdXN0IGJlIHVzZWQgYXMgdGhlIGZpcnN0IGxp bmUgCm9mIGEgZnVuY3Rpb24gd2hpY2ggbW9kaWZpZXMgYW4gZXJyb3IgKHdpdGggZXJyb3JfcHJl cGVuZCwgCmVycm9yX2FwcGVuZF9oaW50LCBvciBzaW1pbGFyKSBvciB3aGljaCB3YW50cyB0byBk ZXJlZmVyZW5jZSAqZXJycC4gIEl0IAppcyBzdGlsbCBzYWZlIChidXQgdXNlbGVzcykgdG8gdXNl IGluIG90aGVyIGZ1bmN0aW9ucy4KCj4gKyAqCj4gKyAqIElmIGVycnAgaXMgTlVMTCBvciBwb2lu dHMgdG8gZXJyb3JfZmF0YWwsIGl0IGlzIHJld3JpdHRlbiB0byBwb2ludCB0byBhCj4gKyAqIGxv Y2FsIEVycm9yIG9iamVjdCwgd2hpY2ggd2lsbCBiZSBhdXRvbWF0aWNhbGx5IHByb3BhZ2F0ZWQg dG8gdGhlIG9yaWdpbmFsCj4gKyAqIGVycnAgb24gZnVuY3Rpb24gZXhpdCAoc2VlIGVycm9yX3By b3BhZ2F0b3JfY2xlYW51cCkuCj4gKyAqCj4gKyAqIEFmdGVyIGludm9jYXRpb24gb2YgdGhpcyBt YWNybyBpdCBpcyBhbHdheXMgc2FmZSB0byBkZXJlZmVyZW5jZSBlcnJwCj4gKyAqIChhcyBpdCdz IG5vdCBOVUxMIGFueW1vcmUpIGFuZCB0byBhZGQgaW5mb3JtYXRpb24gYnkgZXJyb3JfcHJlcGVu ZCBvcgo+ICsgKiBlcnJvcl9hcHBlbmRfaGludCAoYXMsIGlmIGl0IHdhcyBlcnJvcl9mYXRhbCwg d2Ugc3dhcHBlZCBpdCB3aXRoIGEKPiArICogbG9jYWxfZXJyb3IgdG8gYmUgcHJvcGFnYXRlZCBv biBjbGVhbnVwKS4KPiArICoKPiArICogTm90ZTogd2UgZG9uJ3Qgd3JhcCB0aGUgZXJyb3JfYWJv cnQgY2FzZSwgYXMgd2Ugd2FudCByZXN1bHRpbmcgY29yZWR1bXAKPiArICogdG8gcG9pbnQgdG8g dGhlIHBsYWNlIHdoZXJlIHRoZSBlcnJvciBoYXBwZW5lZCwgbm90IHRvIGVycm9yX3Byb3BhZ2F0 ZS4KPiArICovCj4gKyNkZWZpbmUgRVJSUF9BVVRPX1BST1BBR0FURSgpIFwKPiArICAgIGdfYXV0 byhFcnJvclByb3BhZ2F0b3IpIF9hdXRvX2VycnBfcHJvcCA9IHsuZXJycCA9IGVycnB9OyBcCj4g KyAgICBkbyB7IFwKPiArICAgICAgICBpZiAoIWVycnAgfHwgZXJycCA9PSAmZXJyb3JfZmF0YWwp IHsgXAo+ICsgICAgICAgICAgICBlcnJwID0gJl9hdXRvX2VycnBfcHJvcC5sb2NhbF9lcnI7IFwK PiArICAgICAgICB9IFwKPiArICAgIH0gd2hpbGUgKDApCj4gKwo+ICAgLyoKPiAgICAqIFNwZWNp YWwgZXJyb3IgZGVzdGluYXRpb24gdG8gYWJvcnQgb24gZXJyb3IuCj4gICAgKiBTZWUgZXJyb3Jf c2V0ZygpIGFuZCBlcnJvcl9wcm9wYWdhdGUoKSBmb3IgZGV0YWlscy4KPiAKClRoZSBtYWNybyBp dHNlbGYgbG9va3MgY29ycmVjdC4gSSdsbCBsZWF2ZSBpdCB1cCB0byBNYXJrdXMgaG93IHRvIGhh bmRsZSAKdGhlIGNvbW1lbnQgdGV4dCwgYnV0IHlvdSBjYW4gYWRkOgoKUmV2aWV3ZWQtYnk6IEVy aWMgQmxha2UgPGVibGFrZUByZWRoYXQuY29tPgoKCi0tIApFcmljIEJsYWtlLCBQcmluY2lwYWwg U29mdHdhcmUgRW5naW5lZXIKUmVkIEhhdCwgSW5jLiAgICAgICAgICAgKzEtOTE5LTMwMS0zMjI2 ClZpcnR1YWxpemF0aW9uOiAgcWVtdS5vcmcgfCBsaWJ2aXJ0Lm9yZwoKCl9fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fClhlbi1kZXZlbCBtYWlsaW5nIGxpc3QK WGVuLWRldmVsQGxpc3RzLnhlbnByb2plY3Qub3JnCmh0dHBzOi8vbGlzdHMueGVucHJvamVjdC5v cmcvbWFpbG1hbi9saXN0aW5mby94ZW4tZGV2ZWw=