From aedd48160f79de3372eb233ebbf9d8d47c22072a Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Mon, 30 Apr 2018 12:37:29 +0100 Subject: bash-completion: systemctl: use systemctl --no-pager Signed-off-by: Emil Velikov --- shell-completion/bash/systemctl.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shell-completion') diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in index 8bf83c8ae..e493d3bd5 100644 --- a/shell-completion/bash/systemctl.in +++ b/shell-completion/bash/systemctl.in @@ -7,7 +7,7 @@ __systemctl() { local mode=$1; shift 1 - systemctl $mode --full --no-legend "$@" 2>/dev/null + systemctl $mode --full --no-legend --no-pager "$@" 2>/dev/null } __systemd_properties() { -- cgit v1.2.3-65-gdbad From c839b729c5f7b08f6d91bf9567d0b1f91d17e0f7 Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Mon, 30 Apr 2018 12:53:50 +0100 Subject: bash-completion: systemctl: pass current partial unit to list-unit* Pass the partial name of the unit file to list-unit-files and list-units. This allows for faster completion, since systemctl does not need to list all the unit files. For reference: - time systemctl list-unit-files -> ~200ms - time systemctl list-unit-files netctl* -> ~15ms - time systemctl list-units -> ~5ms - time systemctl list-units netctl* -> ~5ms While the list-units time itself is unaffected, now a shorter list is produced. Thus as we pass it to `systemctl show' (via __filter_units_by_properties) the execution time will be decreased even further. v2: Update list-units hunk in commit message, add quotes around $2* v3: Remove funky indentation, quote all $cur instances Signed-off-by: Emil Velikov --- shell-completion/bash/systemctl.in | 48 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'shell-completion') diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in index e493d3bd5..28981c2a7 100644 --- a/shell-completion/bash/systemctl.in +++ b/shell-completion/bash/systemctl.in @@ -65,35 +65,35 @@ __get_all_units () { { __systemctl $1 list-unit-files; __systemctl $1 list- | { while read -r a b; do echo " $a"; done; }; } __get_non_template_units() { { __systemctl $1 list-unit-files; __systemctl $1 list-units --all; } \ | { while read -r a b; do [[ $a =~ @\. ]] || echo " $a"; done; }; } -__get_template_names () { __systemctl $1 list-unit-files \ +__get_template_names () { __systemctl $1 list-unit-files "$2*" \ | { while read -r a b; do [[ $a =~ @\. ]] && echo " ${a%%@.*}@"; done; }; } -__get_active_units () { __systemctl $1 list-units \ +__get_active_units () { __systemctl $1 list-units "$2*" \ | { while read -r a b; do echo " $a"; done; }; } __get_startable_units () { # find startable inactive units __filter_units_by_properties $1 ActiveState,CanStart inactive,yes $( - { __systemctl $1 list-unit-files --state enabled,enabled-runtime,linked,linked-runtime,static,indirect,disabled,generated,transient | \ + { __systemctl $1 list-unit-files --state enabled,enabled-runtime,linked,linked-runtime,static,indirect,disabled,generated,transient "$2*" | \ { while read -r a b; do [[ $a =~ @\. ]] || echo " $a"; done; } - __systemctl $1 list-units --state inactive,failed | \ + __systemctl $1 list-units --state inactive,failed "$2*" | \ { while read -r a b c; do [[ $b == "loaded" ]] && echo " $a"; done; } } | sort -u ) } __get_restartable_units () { # filter out masked and not-found __filter_units_by_property $1 CanStart yes $( - __systemctl $1 list-unit-files --state enabled,disabled,static | \ + __systemctl $1 list-unit-files --state enabled,disabled,static "$2*" | \ { while read -r a b; do [[ $a =~ @\. ]] || echo " $a"; done; } - __systemctl $1 list-units | \ + __systemctl $1 list-units "$2*" | \ { while read -r a b; do echo " $a"; done; } ) } -__get_failed_units () { __systemctl $1 list-units \ +__get_failed_units () { __systemctl $1 list-units "$2*" \ | { while read -r a b c d; do [[ $c == "failed" ]] && echo " $a"; done; }; } -__get_enabled_units () { __systemctl $1 list-unit-files \ +__get_enabled_units () { __systemctl $1 list-unit-files "$2*" \ | { while read -r a b c ; do [[ $b == "enabled" ]] && echo " $a"; done; }; } -__get_disabled_units () { __systemctl $1 list-unit-files \ +__get_disabled_units () { __systemctl $1 list-unit-files "$2*" \ | { while read -r a b c ; do [[ $b == "disabled" ]] && echo " $a"; done; }; } -__get_masked_units () { __systemctl $1 list-unit-files \ +__get_masked_units () { __systemctl $1 list-unit-files "$2*" \ | { while read -r a b c ; do [[ $b == "masked" ]] && echo " $a"; done; }; } __get_all_unit_files () { { __systemctl $1 list-unit-files; } | { while read -r a b; do echo " $a"; done; }; } @@ -220,38 +220,38 @@ _systemctl () { compopt -o filenames elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then - comps=$( __get_enabled_units $mode ) + comps=$( __get_enabled_units $mode "$cur" ) compopt -o filenames elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then - comps=$( __get_disabled_units $mode; - __get_template_names $mode) + comps=$( __get_disabled_units $mode "$cur"; + __get_template_names $mode "$cur") compopt -o filenames elif __contains_word "$verb" ${VERBS[REENABLABLE_UNITS]}; then - comps=$( __get_disabled_units $mode; - __get_enabled_units $mode; - __get_template_names $mode) + comps=$( __get_disabled_units $mode "$cur"; + __get_enabled_units $mode "$cur"; + __get_template_names $mode "$cur") compopt -o filenames elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then - comps=$( __get_startable_units $mode; - __get_template_names $mode) + comps=$( __get_startable_units $mode "$cur"; + __get_template_names $mode "$cur") compopt -o filenames elif __contains_word "$verb" ${VERBS[RESTARTABLE_UNITS]}; then - comps=$( __get_restartable_units $mode; - __get_template_names $mode) + comps=$( __get_restartable_units $mode "$cur"; + __get_template_names $mode "$cur") compopt -o filenames elif __contains_word "$verb" ${VERBS[STOPPABLE_UNITS]}; then comps=$( __filter_units_by_property $mode CanStop yes \ - $( __get_active_units $mode ) ) + $( __get_active_units $mode "$cur" ) ) compopt -o filenames elif __contains_word "$verb" ${VERBS[RELOADABLE_UNITS]}; then comps=$( __filter_units_by_property $mode CanReload yes \ - $( __get_active_units $mode ) ) + $( __get_active_units $mode "$cur" ) ) compopt -o filenames elif __contains_word "$verb" ${VERBS[ISOLATABLE_UNITS]}; then @@ -260,11 +260,11 @@ _systemctl () { compopt -o filenames elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then - comps=$( __get_failed_units $mode ) + comps=$( __get_failed_units $mode "$cur" ) compopt -o filenames elif __contains_word "$verb" ${VERBS[MASKED_UNITS]}; then - comps=$( __get_masked_units $mode ) + comps=$( __get_masked_units $mode "$cur" ) compopt -o filenames elif __contains_word "$verb" ${VERBS[TARGET_AND_UNITS]}; then -- cgit v1.2.3-65-gdbad From ff728637cc5013e3b58b4fa5c6cf39e662c5474b Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Mon, 30 Apr 2018 13:37:51 +0100 Subject: zsh-completion: systemctl: pass only $PREFIX* to list-unit* Using a leading * and $SUFFIX produces misleading results. Let's imagine that one mistypes nect instead of netc, they will get a rather misleading completion like: sys-fs-fuse-connections.mount Not to mention that the execution time is up by ~1/3. time systemctl list-unit-files netctl* -> ~12ms time systemctl list-unit-files *netctl* -> ~17ms Furthermore more units are matched, leading to greater execution time of `systemctl show' in _filter_units_by_property Use only $PREFIX*, removing the leading * and trailing $SUFFIX*. Signed-off-by: Emil Velikov --- shell-completion/zsh/_systemctl.in | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'shell-completion') diff --git a/shell-completion/zsh/_systemctl.in b/shell-completion/zsh/_systemctl.in index 000b58560..2bb2fff37 100644 --- a/shell-completion/zsh/_systemctl.in +++ b/shell-completion/zsh/_systemctl.in @@ -135,29 +135,29 @@ _filter_units_by_property() { echo -E - "${(@g:o:)${(k@)props[(Re)$property=$value]}#Id=}" } -_systemctl_get_template_names() { echo -E - ${^${(M)${(f)"$(__systemctl list-unit-files "*$PREFIX*$SUFFIX*" )"}##*@.[^[:space:]]##}%%@.*}\@ } +_systemctl_get_template_names() { echo -E - ${^${(M)${(f)"$(__systemctl list-unit-files "$PREFIX*" )"}##*@.[^[:space:]]##}%%@.*}\@ } -_systemctl_active_units() {_sys_active_units=( ${${(f)"$(__systemctl list-units "*$PREFIX*$SUFFIX*" )"}%% *} )} +_systemctl_active_units() {_sys_active_units=( ${${(f)"$(__systemctl list-units "$PREFIX*" )"}%% *} )} _systemctl_startable_units(){ _sys_startable_units=( $( _filter_units_by_property ActiveState inactive $( _filter_units_by_property CanStart yes ${${${(f)"$( - __systemctl $mode list-unit-files --state enabled,disabled,static "*$PREFIX*$SUFFIX*" - __systemctl $mode list-units --state inactive,failed "*$PREFIX*$SUFFIX*" + __systemctl $mode list-unit-files --state enabled,disabled,static "$PREFIX*" + __systemctl $mode list-units --state inactive,failed "$PREFIX*" )"}:#*@.*}%%[[:space:]]*} )) ) } _systemctl_restartable_units(){ _sys_restartable_units=( $( _filter_units_by_property CanStart yes ${${${(f)"$( - __systemctl $mode list-unit-files --state enabled,disabled,static "*$PREFIX*$SUFFIX*" - __systemctl $mode list-units "*$PREFIX*$SUFFIX*" + __systemctl $mode list-unit-files --state enabled,disabled,static "$PREFIX*" + __systemctl $mode list-units "$PREFIX*" )"}:#*@.*}%%[[:space:]]*} ) ) } -_systemctl_failed_units() {_sys_failed_units=( ${${(f)"$(__systemctl list-units --state=failed "*$PREFIX*$SUFFIX*" )"}%% *} ) } -_systemctl_unit_state() { typeset -gA _sys_unit_state; _sys_unit_state=( $(__systemctl list-unit-files "*$PREFIX*$SUFFIX*" ) ) } +_systemctl_failed_units() {_sys_failed_units=( ${${(f)"$(__systemctl list-units --state=failed "$PREFIX*" )"}%% *} ) } +_systemctl_unit_state() { typeset -gA _sys_unit_state; _sys_unit_state=( $(__systemctl list-unit-files "$PREFIX*" ) ) } local fun # Completion functions for ALL_UNITS -- cgit v1.2.3-65-gdbad From 8a6236e51aea33788f543f79aa611486a17cd612 Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Mon, 30 Apr 2018 14:45:25 +0100 Subject: zsh-completion: systemctl: tweak --state list for startable units This effectively ports over b1bdb6496c07fc4fcf3f0feae69b5ef89ae557d9 from the bash completion to zsh. Modulo the new function, since it's unrelated perf. improvement. Signed-off-by: Emil Velikov --- shell-completion/zsh/_systemctl.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shell-completion') diff --git a/shell-completion/zsh/_systemctl.in b/shell-completion/zsh/_systemctl.in index 2bb2fff37..9ade70b82 100644 --- a/shell-completion/zsh/_systemctl.in +++ b/shell-completion/zsh/_systemctl.in @@ -143,7 +143,7 @@ _systemctl_active_units() {_sys_active_units=( ${${(f)"$(__systemctl list-unit _systemctl_startable_units(){ _sys_startable_units=( $( _filter_units_by_property ActiveState inactive $( _filter_units_by_property CanStart yes ${${${(f)"$( - __systemctl $mode list-unit-files --state enabled,disabled,static "$PREFIX*" + __systemctl $mode list-unit-files --state enabled,enabled-runtime,linked,linked-runtime,static,indirect,disabled,generated,transient "$PREFIX*" __systemctl $mode list-units --state inactive,failed "$PREFIX*" )"}:#*@.*}%%[[:space:]]*} )) ) -- cgit v1.2.3-65-gdbad From 98476dc8b23d3ac7cb7e818a066f519c888ef8ac Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Thu, 7 Jun 2018 16:24:45 +0100 Subject: shell-completion: systemctl: pass current word to all list_unit* Earlier patch added the current word to the performance critical paths. Here we add it to every place, for consistency sake. Suggested-by: Yu Watanabe (yuwata) Signed-off-by: Emil Velikov --- shell-completion/bash/systemctl.in | 18 +++++++++--------- shell-completion/zsh/_systemctl.in | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'shell-completion') diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in index 28981c2a7..4ff76d87f 100644 --- a/shell-completion/bash/systemctl.in +++ b/shell-completion/bash/systemctl.in @@ -61,9 +61,9 @@ __filter_units_by_properties () { done } -__get_all_units () { { __systemctl $1 list-unit-files; __systemctl $1 list-units --all; } \ +__get_all_units () { { __systemctl $1 list-unit-files "$2*"; __systemctl $1 list-units --all "$2*"; } \ | { while read -r a b; do echo " $a"; done; }; } -__get_non_template_units() { { __systemctl $1 list-unit-files; __systemctl $1 list-units --all; } \ +__get_non_template_units() { { __systemctl $1 list-unit-files "$2*"; __systemctl $1 list-units --all "$2*"; } \ | { while read -r a b; do [[ $a =~ @\. ]] || echo " $a"; done; }; } __get_template_names () { __systemctl $1 list-unit-files "$2*" \ | { while read -r a b; do [[ $a =~ @\. ]] && echo " ${a%%@.*}@"; done; }; } @@ -95,7 +95,7 @@ __get_disabled_units () { __systemctl $1 list-unit-files "$2*" \ | { while read -r a b c ; do [[ $b == "disabled" ]] && echo " $a"; done; }; } __get_masked_units () { __systemctl $1 list-unit-files "$2*" \ | { while read -r a b c ; do [[ $b == "masked" ]] && echo " $a"; done; }; } -__get_all_unit_files () { { __systemctl $1 list-unit-files; } | { while read -r a b; do echo " $a"; done; }; } +__get_all_unit_files () { { __systemctl $1 list-unit-files "$2*"; } | { while read -r a b; do echo " $a"; done; }; } __get_machines() { local a b @@ -212,11 +212,11 @@ _systemctl () { comps="${VERBS[*]}" elif __contains_word "$verb" ${VERBS[ALL_UNITS]}; then - comps=$( __get_all_units $mode ) + comps=$( __get_all_units $mode "$cur" ) compopt -o filenames elif __contains_word "$verb" ${VERBS[NONTEMPLATE_UNITS]}; then - comps=$( __get_non_template_units $mode ) + comps=$( __get_non_template_units $mode "$cur" ) compopt -o filenames elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then @@ -256,7 +256,7 @@ _systemctl () { elif __contains_word "$verb" ${VERBS[ISOLATABLE_UNITS]}; then comps=$( __filter_units_by_property $mode AllowIsolate yes \ - $( __get_all_units $mode ) ) + $( __get_all_units $mode "$cur" ) ) compopt -o filenames elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then @@ -270,10 +270,10 @@ _systemctl () { elif __contains_word "$verb" ${VERBS[TARGET_AND_UNITS]}; then if __contains_word "$prev" ${VERBS[TARGET_AND_UNITS]} \ || __contains_word "$prev" ${OPTS[STANDALONE]}; then - comps=$( __systemctl $mode list-unit-files --type target --all \ + comps=$( __systemctl $mode list-unit-files --type target --all "$cur*" \ | { while read -r a b; do echo " $a"; done; } ) else - comps=$( __get_all_unit_files $mode ) + comps=$( __get_all_unit_files $mode "$cur" ) fi compopt -o filenames @@ -293,7 +293,7 @@ _systemctl () { compopt -o filenames elif __contains_word "$verb" ${VERBS[TARGETS]}; then - comps=$( __systemctl $mode list-unit-files --type target --full --all \ + comps=$( __systemctl $mode list-unit-files --type target --full --all "$cur*" \ | { while read -r a b; do echo " $a"; done; } ) fi diff --git a/shell-completion/zsh/_systemctl.in b/shell-completion/zsh/_systemctl.in index 9ade70b82..e49129b90 100644 --- a/shell-completion/zsh/_systemctl.in +++ b/shell-completion/zsh/_systemctl.in @@ -106,7 +106,7 @@ _systemctl_all_units() if ( [[ ${+_sys_all_units} -eq 0 ]] || _cache_invalid SYS_ALL_UNITS$_sys_service_mgr ) || ! _retrieve_cache SYS_ALL_UNITS$_sys_service_mgr; then - _sys_all_units=( ${${(f)"$(__systemctl list-units --all)"}%% *} ) + _sys_all_units=( ${${(f)"$(__systemctl list-units --all "$PREFIX*" )"}%% *} ) _store_cache SYS_ALL_UNITS$_sys_service_mgr _sys_all_units fi } @@ -119,7 +119,7 @@ _systemctl_really_all_units() if ( [[ ${+_sys_really_all_units} -eq 0 ]] || _cache_invalid SYS_REALLY_ALL_UNITS$_sys_service_mgr ) || ! _retrieve_cache SYS_REALLY_ALL_UNITS$_sys_service_mgr; then - all_unit_files=( ${${(f)"$(__systemctl list-unit-files)"}%% *} ) + all_unit_files=( ${${(f)"$(__systemctl list-unit-files "$PREFIX*" )"}%% *} ) _systemctl_all_units really_all_units=($_sys_all_units $all_unit_files) _sys_really_all_units=(${(u)really_all_units}) @@ -270,7 +270,7 @@ done (( $+functions[_systemctl_set-default] )) || _systemctl_set-default() { _wanted systemd-targets expl target \ - compadd "$@" - ${${(f)"$(__systemctl list-unit-files --type target --all)"}%% *} || + compadd "$@" - ${${(f)"$(__systemctl list-unit-files --type target --all "$PREFIX*" )"}%% *} || _message "no targets found" } -- cgit v1.2.3-65-gdbad From 9b536b1af2730de61c21dbe0522fd40547b0468b Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Mon, 11 Jun 2018 16:35:23 +0100 Subject: shell-completion: systemctl: do not list template units in {re,}start Template units lacking DefaultInstance cannot be enabled/disabled or started/restarted. By adding DefaultInstance the unit can be enabled/disabled but it still cannot be started/restarted. Signed-off-by: Emil Velikov --- shell-completion/bash/systemctl.in | 6 ++---- shell-completion/zsh/_systemctl.in | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'shell-completion') diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in index 4ff76d87f..1c26ca24c 100644 --- a/shell-completion/bash/systemctl.in +++ b/shell-completion/bash/systemctl.in @@ -235,13 +235,11 @@ _systemctl () { compopt -o filenames elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then - comps=$( __get_startable_units $mode "$cur"; - __get_template_names $mode "$cur") + comps=$( __get_startable_units $mode "$cur" ) compopt -o filenames elif __contains_word "$verb" ${VERBS[RESTARTABLE_UNITS]}; then - comps=$( __get_restartable_units $mode "$cur"; - __get_template_names $mode "$cur") + comps=$( __get_restartable_units $mode "$cur" ) compopt -o filenames elif __contains_word "$verb" ${VERBS[STOPPABLE_UNITS]}; then diff --git a/shell-completion/zsh/_systemctl.in b/shell-completion/zsh/_systemctl.in index e49129b90..173e815a1 100644 --- a/shell-completion/zsh/_systemctl.in +++ b/shell-completion/zsh/_systemctl.in @@ -206,7 +206,7 @@ done { local _sys_startable_units; _systemctl_startable_units _wanted systemd-units expl 'startable unit' \ - compadd "$@" - ${_sys_startable_units[*]} $(_systemctl_get_template_names) + compadd "$@" - ${_sys_startable_units[*]} } # Completion functions for STOPPABLE_UNITS @@ -246,7 +246,7 @@ for fun in restart reload-or-restart ; do { local _sys_restartable_units; _systemctl_restartable_units _wanted systemd-units expl 'restartable unit' \ - compadd "$@" - ${_sys_restartable_units[*]} $(_systemctl_get_template_names) + compadd "$@" - ${_sys_restartable_units[*]} } done -- cgit v1.2.3-65-gdbad From 4ed141166c8b3a633ca7b5e15828071dce63eab0 Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Mon, 11 Jun 2018 11:53:08 +0100 Subject: zsh-completion: systemctl: list template units only as needed Currently the completion adds template units for commands such as is-active, is-failed, is-enabled, status, show and others. At the same time systemctl barfs at us, since an instanced template unit is needed. Follow the example list from bash-completion as to which commands should not list template units. Note: The above is observed regardless of DefaultInstance. Signed-off-by: Emil Velikov --- shell-completion/zsh/_systemctl.in | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'shell-completion') diff --git a/shell-completion/zsh/_systemctl.in b/shell-completion/zsh/_systemctl.in index 173e815a1..9f576ed77 100644 --- a/shell-completion/zsh/_systemctl.in +++ b/shell-completion/zsh/_systemctl.in @@ -135,6 +135,11 @@ _filter_units_by_property() { echo -E - "${(@g:o:)${(k@)props[(Re)$property=$value]}#Id=}" } +_systemctl_get_non_template_names() { echo -E - ${^${(R)${(f)"$( + __systemctl $mode list-unit-files "$PREFIX*" + __systemctl $mode list-units --all "$PREFIX*" + )"}:#*@.*}%%[[:space:]]*} } + _systemctl_get_template_names() { echo -E - ${^${(M)${(f)"$(__systemctl list-unit-files "$PREFIX*" )"}##*@.[^[:space:]]##}%%@.*}\@ } @@ -161,7 +166,7 @@ _systemctl_unit_state() { typeset -gA _sys_unit_state; _sys_unit_state=( $(__sys local fun # Completion functions for ALL_UNITS -for fun in is-active is-failed is-enabled status show cat mask preset help list-dependencies edit revert add-wants add-requires ; do +for fun in cat mask ; do (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() { _systemctl_really_all_units @@ -170,6 +175,15 @@ for fun in is-active is-failed is-enabled status show cat mask preset help list- } done +# Completion functions for NONTEMPLATE_UNITS +for fun in is-active is-failed is-enabled status show preset help list-dependencies edit revert add-wants add-requires ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _wanted systemd-units expl unit \ + compadd "$@" - $(_systemctl_get_non_template_names) + } +done + # Completion functions for ENABLED_UNITS (( $+functions[_systemctl_disable] )) || _systemctl_disable() { -- cgit v1.2.3-65-gdbad